diff --git a/impeller/playground/playground.cc b/impeller/playground/playground.cc index ec48aa3550bf9..4f61c5c5020ef 100644 --- a/impeller/playground/playground.cc +++ b/impeller/playground/playground.cc @@ -395,82 +395,82 @@ std::optional Playground::DecodeImageRGBA( return image; } -namespace { -std::shared_ptr CreateTextureForDecompressedImage( +static std::shared_ptr CreateTextureForDecompressedImage( const std::shared_ptr& 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; - - 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()); + 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; + } - dest_texture->SetLabel( - impeller::SPrintF("ui.Image(%p)", dest_texture.get()).c_str()); + auto buffer = context->GetResourceAllocator()->CreateBufferWithCopy( + *decompressed_image.GetAllocation().get()); - 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"); + dest_texture->SetLabel( + impeller::SPrintF("ui.Image(%p)", dest_texture.get()).c_str()); - 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); - } + 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"); - 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 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); + } - auto texture = - context->GetResourceAllocator()->CreateTexture(texture_descriptor); - if (!texture) { - VALIDATION_LOG << "Could not allocate texture for fixture."; - return nullptr; - } + 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; + auto uploaded = texture->SetContents(decompressed_image.GetAllocation()); + if (!uploaded) { + VALIDATION_LOG + << "Could not upload texture to device memory for fixture."; + return nullptr; + } + return texture; } - return texture; -#endif // FML_OS_MACOS } -} // namespace std::shared_ptr Playground::CreateTextureForMapping( const std::shared_ptr& context, diff --git a/impeller/renderer/backend/gles/context_gles.cc b/impeller/renderer/backend/gles/context_gles.cc index fb42495e36a13..f2bba7c15c524 100644 --- a/impeller/renderer/backend/gles/context_gles.cc +++ b/impeller/renderer/backend/gles/context_gles.cc @@ -65,6 +65,7 @@ ContextGLES::ContextGLES(std::unique_ptr gl, .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 5976c5b9c7477..2bca0a145dbdd 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -52,6 +52,7 @@ static bool DeviceSupportsComputeSubgroups(id device) { .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 7346ccdc16138..ff4410f15935a 100644 --- a/impeller/renderer/backend/vulkan/capabilities_vk.cc +++ b/impeller/renderer/backend/vulkan/capabilities_vk.cc @@ -313,6 +313,11 @@ bool CapabilitiesVK::SupportsSSBO() const { return true; } +// |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 78fdc620e2a6b..006ed6f0e0889 100644 --- a/impeller/renderer/backend/vulkan/capabilities_vk.h +++ b/impeller/renderer/backend/vulkan/capabilities_vk.h @@ -55,6 +55,9 @@ class CapabilitiesVK final : public Capabilities, // |Capabilities| bool SupportsSSBO() const override; + // |Capabilities| + bool SupportsBufferToTextureBlits() const override; + // |Capabilities| bool SupportsTextureToTextureBlits() const override; diff --git a/impeller/renderer/capabilities.cc b/impeller/renderer/capabilities.cc index f92f69ea7a0ca..5b23d4ca1d7a8 100644 --- a/impeller/renderer/capabilities.cc +++ b/impeller/renderer/capabilities.cc @@ -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 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_, // diff --git a/impeller/renderer/capabilities.h b/impeller/renderer/capabilities.h index f2dde2ce6e4ab..78c0c209a7895 100644 --- a/impeller/renderer/capabilities.h +++ b/impeller/renderer/capabilities.h @@ -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;