[Impeller] Add buffer-to-texture blit capability check; fix GL+VK playgrounds on macOS (flutter/engine#41320)

GL/VK playgrounds that load image fixtures are currently broken on
macOS.
This commit is contained in:
Brandon DeRosier
2023-04-18 21:38:35 -07:00
committed by GitHub
parent ee5279217a
commit addeb03c02
7 changed files with 98 additions and 68 deletions

View File

@@ -395,82 +395,82 @@ std::optional<DecompressedImage> Playground::DecodeImageRGBA(
return image;
}
namespace {
std::shared_ptr<Texture> CreateTextureForDecompressedImage(
static std::shared_ptr<Texture> CreateTextureForDecompressedImage(
const std::shared_ptr<Context>& context,
DecompressedImage& decompressed_image,
bool enable_mipmapping) {
// TODO(https://github.com/flutter/flutter/issues/123468): copying buffers to
// textures is not implemented for GLES/Vulkan.
#if FML_OS_MACOSX
impeller::TextureDescriptor texture_descriptor;
texture_descriptor.storage_mode = impeller::StorageMode::kDevicePrivate;
texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
texture_descriptor.size = decompressed_image.GetSize();
texture_descriptor.mip_count =
enable_mipmapping ? decompressed_image.GetSize().MipCount() : 1u;
if (context->GetCapabilities()->SupportsBufferToTextureBlits()) {
impeller::TextureDescriptor texture_descriptor;
texture_descriptor.storage_mode = impeller::StorageMode::kDevicePrivate;
texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
texture_descriptor.size = decompressed_image.GetSize();
texture_descriptor.mip_count =
enable_mipmapping ? decompressed_image.GetSize().MipCount() : 1u;
auto dest_texture =
context->GetResourceAllocator()->CreateTexture(texture_descriptor);
if (!dest_texture) {
FML_DLOG(ERROR) << "Could not create Impeller texture.";
return nullptr;
auto dest_texture =
context->GetResourceAllocator()->CreateTexture(texture_descriptor);
if (!dest_texture) {
FML_DLOG(ERROR) << "Could not create Impeller texture.";
return nullptr;
}
auto buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
*decompressed_image.GetAllocation().get());
dest_texture->SetLabel(
impeller::SPrintF("ui.Image(%p)", dest_texture.get()).c_str());
auto command_buffer = context->CreateCommandBuffer();
if (!command_buffer) {
FML_DLOG(ERROR)
<< "Could not create command buffer for mipmap generation.";
return nullptr;
}
command_buffer->SetLabel("Mipmap Command Buffer");
auto blit_pass = command_buffer->CreateBlitPass();
if (!blit_pass) {
FML_DLOG(ERROR) << "Could not create blit pass for mipmap generation.";
return nullptr;
}
blit_pass->SetLabel("Mipmap Blit Pass");
blit_pass->AddCopy(buffer->AsBufferView(), dest_texture);
if (enable_mipmapping) {
blit_pass->GenerateMipmap(dest_texture);
}
blit_pass->EncodeCommands(context->GetResourceAllocator());
if (!command_buffer->SubmitCommands()) {
FML_DLOG(ERROR) << "Failed to submit blit pass command buffer.";
return nullptr;
}
return dest_texture;
} else { // Doesn't support buffer-to-texture blits.
auto texture_descriptor = TextureDescriptor{};
texture_descriptor.storage_mode = StorageMode::kHostVisible;
texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
texture_descriptor.size = decompressed_image.GetSize();
texture_descriptor.mip_count =
enable_mipmapping ? decompressed_image.GetSize().MipCount() : 1u;
auto texture =
context->GetResourceAllocator()->CreateTexture(texture_descriptor);
if (!texture) {
VALIDATION_LOG << "Could not allocate texture for fixture.";
return nullptr;
}
auto uploaded = texture->SetContents(decompressed_image.GetAllocation());
if (!uploaded) {
VALIDATION_LOG
<< "Could not upload texture to device memory for fixture.";
return nullptr;
}
return texture;
}
auto buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
*decompressed_image.GetAllocation().get());
dest_texture->SetLabel(
impeller::SPrintF("ui.Image(%p)", dest_texture.get()).c_str());
auto command_buffer = context->CreateCommandBuffer();
if (!command_buffer) {
FML_DLOG(ERROR) << "Could not create command buffer for mipmap generation.";
return nullptr;
}
command_buffer->SetLabel("Mipmap Command Buffer");
auto blit_pass = command_buffer->CreateBlitPass();
if (!blit_pass) {
FML_DLOG(ERROR) << "Could not create blit pass for mipmap generation.";
return nullptr;
}
blit_pass->SetLabel("Mipmap Blit Pass");
blit_pass->AddCopy(buffer->AsBufferView(), dest_texture);
if (enable_mipmapping) {
blit_pass->GenerateMipmap(dest_texture);
}
blit_pass->EncodeCommands(context->GetResourceAllocator());
if (!command_buffer->SubmitCommands()) {
FML_DLOG(ERROR) << "Failed to submit blit pass command buffer.";
return nullptr;
}
return dest_texture;
#else
auto texture_descriptor = TextureDescriptor{};
texture_descriptor.storage_mode = StorageMode::kHostVisible;
texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
texture_descriptor.size = decompressed_image.GetSize();
texture_descriptor.mip_count =
enable_mipmapping ? decompressed_image.GetSize().MipCount() : 1u;
auto texture =
context->GetResourceAllocator()->CreateTexture(texture_descriptor);
if (!texture) {
VALIDATION_LOG << "Could not allocate texture for fixture.";
return nullptr;
}
auto uploaded = texture->SetContents(decompressed_image.GetAllocation());
if (!uploaded) {
VALIDATION_LOG << "Could not upload texture to device memory for fixture.";
return nullptr;
}
return texture;
#endif // FML_OS_MACOS
}
} // namespace
std::shared_ptr<Texture> Playground::CreateTextureForMapping(
const std::shared_ptr<Context>& context,

View File

@@ -65,6 +65,7 @@ ContextGLES::ContextGLES(std::unique_ptr<ProcTableGLES> gl,
.SetHasThreadingRestrictions(true)
.SetSupportsOffscreenMSAA(false)
.SetSupportsSSBO(false)
.SetSupportsBufferToTextureBlits(false)
.SetSupportsTextureToTextureBlits(
reactor_->GetProcTable().BlitFramebuffer.IsAvailable())
.SetSupportsFramebufferFetch(false)

View File

@@ -52,6 +52,7 @@ static std::unique_ptr<Capabilities> InferMetalCapabilities(
.SetHasThreadingRestrictions(false)
.SetSupportsOffscreenMSAA(true)
.SetSupportsSSBO(true)
.SetSupportsBufferToTextureBlits(true)
.SetSupportsTextureToTextureBlits(true)
.SetSupportsDecalTileMode(true)
.SetSupportsFramebufferFetch(DeviceSupportsFramebufferFetch(device))

View File

@@ -313,6 +313,11 @@ bool CapabilitiesVK::SupportsSSBO() const {
return true;
}
// |Capabilities|
bool CapabilitiesVK::SupportsBufferToTextureBlits() const {
return false;
}
// |Capabilities|
bool CapabilitiesVK::SupportsTextureToTextureBlits() const {
return true;

View File

@@ -55,6 +55,9 @@ class CapabilitiesVK final : public Capabilities,
// |Capabilities|
bool SupportsSSBO() const override;
// |Capabilities|
bool SupportsBufferToTextureBlits() const override;
// |Capabilities|
bool SupportsTextureToTextureBlits() const override;

View File

@@ -28,6 +28,11 @@ class StandardCapabilities final : public Capabilities {
// |Capabilities|
bool SupportsSSBO() const override { return supports_ssbo_; }
// |Capabilities|
bool SupportsBufferToTextureBlits() const override {
return supports_buffer_to_texture_blits_;
}
// |Capabilities|
bool SupportsTextureToTextureBlits() const override {
return supports_texture_to_texture_blits_;
@@ -75,6 +80,7 @@ class StandardCapabilities final : public Capabilities {
StandardCapabilities(bool has_threading_restrictions,
bool supports_offscreen_msaa,
bool supports_ssbo,
bool supports_buffer_to_texture_blits,
bool supports_texture_to_texture_blits,
bool supports_framebuffer_fetch,
bool supports_compute,
@@ -87,6 +93,7 @@ class StandardCapabilities final : public Capabilities {
: has_threading_restrictions_(has_threading_restrictions),
supports_offscreen_msaa_(supports_offscreen_msaa),
supports_ssbo_(supports_ssbo),
supports_buffer_to_texture_blits_(supports_buffer_to_texture_blits),
supports_texture_to_texture_blits_(supports_texture_to_texture_blits),
supports_framebuffer_fetch_(supports_framebuffer_fetch),
supports_compute_(supports_compute),
@@ -103,6 +110,7 @@ class StandardCapabilities final : public Capabilities {
bool has_threading_restrictions_ = false;
bool supports_offscreen_msaa_ = false;
bool supports_ssbo_ = false;
bool supports_buffer_to_texture_blits_ = false;
bool supports_texture_to_texture_blits_ = false;
bool supports_framebuffer_fetch_ = false;
bool supports_compute_ = false;
@@ -136,6 +144,12 @@ CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsSSBO(bool value) {
return *this;
}
CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsBufferToTextureBlits(
bool value) {
supports_buffer_to_texture_blits_ = value;
return *this;
}
CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsTextureToTextureBlits(
bool value) {
supports_texture_to_texture_blits_ = value;
@@ -189,6 +203,7 @@ std::unique_ptr<Capabilities> CapabilitiesBuilder::Build() {
has_threading_restrictions_, //
supports_offscreen_msaa_, //
supports_ssbo_, //
supports_buffer_to_texture_blits_, //
supports_texture_to_texture_blits_, //
supports_framebuffer_fetch_, //
supports_compute_, //

View File

@@ -21,6 +21,8 @@ class Capabilities {
virtual bool SupportsSSBO() const = 0;
virtual bool SupportsBufferToTextureBlits() const = 0;
virtual bool SupportsTextureToTextureBlits() const = 0;
virtual bool SupportsFramebufferFetch() const = 0;
@@ -57,6 +59,8 @@ class CapabilitiesBuilder {
CapabilitiesBuilder& SetSupportsSSBO(bool value);
CapabilitiesBuilder& SetSupportsBufferToTextureBlits(bool value);
CapabilitiesBuilder& SetSupportsTextureToTextureBlits(bool value);
CapabilitiesBuilder& SetSupportsFramebufferFetch(bool value);
@@ -80,6 +84,7 @@ class CapabilitiesBuilder {
bool has_threading_restrictions_ = false;
bool supports_offscreen_msaa_ = false;
bool supports_ssbo_ = false;
bool supports_buffer_to_texture_blits_ = false;
bool supports_texture_to_texture_blits_ = false;
bool supports_framebuffer_fetch_ = false;
bool supports_compute_ = false;