[Impeller] Add buffer-to-texture blit capability check; fix GL+VK playgrounds on macOS (#41320)
GL/VK playgrounds that load image fixtures are currently broken on
macOS.
diff --git a/impeller/playground/playground.cc b/impeller/playground/playground.cc
index ec48aa3..4f61c5c 100644
--- a/impeller/playground/playground.cc
+++ b/impeller/playground/playground.cc
@@ -395,82 +395,82 @@
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,
diff --git a/impeller/renderer/backend/gles/context_gles.cc b/impeller/renderer/backend/gles/context_gles.cc
index fb42495..f2bba7c 100644
--- a/impeller/renderer/backend/gles/context_gles.cc
+++ b/impeller/renderer/backend/gles/context_gles.cc
@@ -65,6 +65,7 @@
.SetHasThreadingRestrictions(true)
.SetSupportsOffscreenMSAA(false)
.SetSupportsSSBO(false)
+ .SetSupportsBufferToTextureBlits(false)
.SetSupportsTextureToTextureBlits(
reactor_->GetProcTable().BlitFramebuffer.IsAvailable())
.SetSupportsFramebufferFetch(false)
diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm
index 5976c5b..2bca0a1 100644
--- a/impeller/renderer/backend/metal/context_mtl.mm
+++ b/impeller/renderer/backend/metal/context_mtl.mm
@@ -52,6 +52,7 @@
.SetHasThreadingRestrictions(false)
.SetSupportsOffscreenMSAA(true)
.SetSupportsSSBO(true)
+ .SetSupportsBufferToTextureBlits(true)
.SetSupportsTextureToTextureBlits(true)
.SetSupportsDecalTileMode(true)
.SetSupportsFramebufferFetch(DeviceSupportsFramebufferFetch(device))
diff --git a/impeller/renderer/backend/vulkan/capabilities_vk.cc b/impeller/renderer/backend/vulkan/capabilities_vk.cc
index 7346ccd..ff4410f 100644
--- a/impeller/renderer/backend/vulkan/capabilities_vk.cc
+++ b/impeller/renderer/backend/vulkan/capabilities_vk.cc
@@ -314,6 +314,11 @@
}
// |Capabilities|
+bool CapabilitiesVK::SupportsBufferToTextureBlits() const {
+ return false;
+}
+
+// |Capabilities|
bool CapabilitiesVK::SupportsTextureToTextureBlits() const {
return true;
}
diff --git a/impeller/renderer/backend/vulkan/capabilities_vk.h b/impeller/renderer/backend/vulkan/capabilities_vk.h
index 78fdc62..006ed6f 100644
--- a/impeller/renderer/backend/vulkan/capabilities_vk.h
+++ b/impeller/renderer/backend/vulkan/capabilities_vk.h
@@ -56,6 +56,9 @@
bool SupportsSSBO() const override;
// |Capabilities|
+ bool SupportsBufferToTextureBlits() const override;
+
+ // |Capabilities|
bool SupportsTextureToTextureBlits() const override;
// |Capabilities|
diff --git a/impeller/renderer/capabilities.cc b/impeller/renderer/capabilities.cc
index f92f69e..5b23d4c 100644
--- a/impeller/renderer/capabilities.cc
+++ b/impeller/renderer/capabilities.cc
@@ -29,6 +29,11 @@
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 @@
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 @@
: 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 @@
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 @@
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 @@
has_threading_restrictions_, //
supports_offscreen_msaa_, //
supports_ssbo_, //
+ supports_buffer_to_texture_blits_, //
supports_texture_to_texture_blits_, //
supports_framebuffer_fetch_, //
supports_compute_, //
diff --git a/impeller/renderer/capabilities.h b/impeller/renderer/capabilities.h
index f2dde2c..78c0c20 100644
--- a/impeller/renderer/capabilities.h
+++ b/impeller/renderer/capabilities.h
@@ -21,6 +21,8 @@
virtual bool SupportsSSBO() const = 0;
+ virtual bool SupportsBufferToTextureBlits() const = 0;
+
virtual bool SupportsTextureToTextureBlits() const = 0;
virtual bool SupportsFramebufferFetch() const = 0;
@@ -57,6 +59,8 @@
CapabilitiesBuilder& SetSupportsSSBO(bool value);
+ CapabilitiesBuilder& SetSupportsBufferToTextureBlits(bool value);
+
CapabilitiesBuilder& SetSupportsTextureToTextureBlits(bool value);
CapabilitiesBuilder& SetSupportsFramebufferFetch(bool value);
@@ -80,6 +84,7 @@
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;