From ba164c17ff7023444dbca7f7eeb8f09eaed5523e Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 12 Apr 2023 13:28:42 -0700 Subject: [PATCH] [Impeller] Metal: Read from onscreen textures (flutter/engine#41107) Removes the "final blit" for Metal because https://github.com/flutter/engine/pull/41085 allows us to read from the onscreen texture. We can't do this trick when running the Vulkan backend right now because it doesn't have `SupportsReadFromResolve` yet, which means we need to toggle between two textures. --- .../src/flutter/impeller/entity/entity_pass.cc | 8 +++++++- .../renderer/backend/gles/context_gles.cc | 1 + .../renderer/backend/metal/context_mtl.mm | 1 + .../renderer/backend/vulkan/capabilities_vk.cc | 5 +++++ .../renderer/backend/vulkan/capabilities_vk.h | 3 +++ .../flutter/impeller/renderer/capabilities.cc | 16 ++++++++++++++++ .../src/flutter/impeller/renderer/capabilities.h | 6 ++++++ 7 files changed, 39 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/impeller/entity/entity_pass.cc b/engine/src/flutter/impeller/entity/entity_pass.cc index f76452bfdfc..41423278925 100644 --- a/engine/src/flutter/impeller/entity/entity_pass.cc +++ b/engine/src/flutter/impeller/entity/entity_pass.cc @@ -213,7 +213,13 @@ bool EntityPass::Render(ContentContext& renderer, .coverage = Rect::MakeSize(render_target.GetRenderTargetSize()), .stencil_depth = 0}}; - if (GetTotalPassReads(renderer) > 0) { + // + bool supports_root_pass_reads = + renderer.GetDeviceCapabilities().SupportsReadFromOnscreenTexture() && + // If the backend doesn't have `SupportsReadFromResolve`, we need to flip + // between two textures when restoring a previous MSAA pass. + renderer.GetDeviceCapabilities().SupportsReadFromResolve(); + if (!supports_root_pass_reads && GetTotalPassReads(renderer) > 0) { auto offscreen_target = CreateRenderTarget(renderer, render_target.GetRenderTargetSize(), true, clear_color_.Premultiply()); diff --git a/engine/src/flutter/impeller/renderer/backend/gles/context_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/context_gles.cc index 10a8a4e1b17..4d3207d36cc 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/context_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/context_gles.cc @@ -72,6 +72,7 @@ ContextGLES::ContextGLES(std::unique_ptr gl, .SetDefaultStencilFormat(PixelFormat::kS8UInt) .SetSupportsCompute(false, false) .SetSupportsReadFromResolve(false) + .SetSupportsReadFromOnscreenTexture(false) .Build(); } diff --git a/engine/src/flutter/impeller/renderer/backend/metal/context_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/context_mtl.mm index 9e5941a14c0..7af8367a35b 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/context_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/context_mtl.mm @@ -59,6 +59,7 @@ static std::unique_ptr InferMetalCapabilities( .SetDefaultStencilFormat(PixelFormat::kS8UInt) .SetSupportsCompute(true, DeviceSupportsComputeSubgroups(device)) .SetSupportsReadFromResolve(true) + .SetSupportsReadFromOnscreenTexture(true) .Build(); } diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc index 42b1c830ac2..7346ccdc161 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc @@ -338,6 +338,11 @@ bool CapabilitiesVK::SupportsReadFromResolve() const { return false; } +// |Capabilities| +bool CapabilitiesVK::SupportsReadFromOnscreenTexture() const { + return false; +} + bool CapabilitiesVK::SupportsDecalTileMode() const { return true; } diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.h index dc23d432075..78fdc620e2a 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.h @@ -70,6 +70,9 @@ class CapabilitiesVK final : public Capabilities, // |Capabilities| bool SupportsReadFromResolve() const override; + // |Capabilities| + bool SupportsReadFromOnscreenTexture() const override; + // |Capabilities| bool SupportsDecalTileMode() const override; diff --git a/engine/src/flutter/impeller/renderer/capabilities.cc b/engine/src/flutter/impeller/renderer/capabilities.cc index 77b082b8f3c..f92f69ea7a0 100644 --- a/engine/src/flutter/impeller/renderer/capabilities.cc +++ b/engine/src/flutter/impeller/renderer/capabilities.cc @@ -46,6 +46,11 @@ class StandardCapabilities final : public Capabilities { return supports_compute_subgroups_; } + // |Capabilities| + bool SupportsReadFromOnscreenTexture() const override { + return supports_read_from_onscreen_texture_; + } + // |Capabilities| bool SupportsReadFromResolve() const override { return supports_read_from_resolve_; @@ -74,6 +79,7 @@ class StandardCapabilities final : public Capabilities { bool supports_framebuffer_fetch, bool supports_compute, bool supports_compute_subgroups, + bool supports_read_from_onscreen_texture, bool supports_read_from_resolve, bool supports_decal_tile_mode, PixelFormat default_color_format, @@ -85,6 +91,8 @@ class StandardCapabilities final : public Capabilities { supports_framebuffer_fetch_(supports_framebuffer_fetch), supports_compute_(supports_compute), supports_compute_subgroups_(supports_compute_subgroups), + supports_read_from_onscreen_texture_( + supports_read_from_onscreen_texture), supports_read_from_resolve_(supports_read_from_resolve), supports_decal_tile_mode_(supports_decal_tile_mode), default_color_format_(default_color_format), @@ -99,6 +107,7 @@ class StandardCapabilities final : public Capabilities { bool supports_framebuffer_fetch_ = false; bool supports_compute_ = false; bool supports_compute_subgroups_ = false; + bool supports_read_from_onscreen_texture_ = false; bool supports_read_from_resolve_ = false; bool supports_decal_tile_mode_ = false; PixelFormat default_color_format_ = PixelFormat::kUnknown; @@ -146,6 +155,12 @@ CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsCompute(bool compute, return *this; } +CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsReadFromOnscreenTexture( + bool read_from_onscreen_texture) { + supports_read_from_resolve_ = read_from_onscreen_texture; + return *this; +} + CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsReadFromResolve( bool read_from_resolve) { supports_read_from_resolve_ = read_from_resolve; @@ -178,6 +193,7 @@ std::unique_ptr CapabilitiesBuilder::Build() { supports_framebuffer_fetch_, // supports_compute_, // supports_compute_subgroups_, // + supports_read_from_onscreen_texture_, // supports_read_from_resolve_, // supports_decal_tile_mode_, // *default_color_format_, // diff --git a/engine/src/flutter/impeller/renderer/capabilities.h b/engine/src/flutter/impeller/renderer/capabilities.h index c66fd27b20c..f2dde2ce6e4 100644 --- a/engine/src/flutter/impeller/renderer/capabilities.h +++ b/engine/src/flutter/impeller/renderer/capabilities.h @@ -29,6 +29,8 @@ class Capabilities { virtual bool SupportsComputeSubgroups() const = 0; + virtual bool SupportsReadFromOnscreenTexture() const = 0; + virtual bool SupportsReadFromResolve() const = 0; virtual bool SupportsDecalTileMode() const = 0; @@ -61,6 +63,9 @@ class CapabilitiesBuilder { CapabilitiesBuilder& SetSupportsCompute(bool compute, bool subgroups); + CapabilitiesBuilder& SetSupportsReadFromOnscreenTexture( + bool read_from_onscreen_texture); + CapabilitiesBuilder& SetSupportsReadFromResolve(bool read_from_resolve); CapabilitiesBuilder& SetDefaultColorFormat(PixelFormat value); @@ -79,6 +84,7 @@ class CapabilitiesBuilder { bool supports_framebuffer_fetch_ = false; bool supports_compute_ = false; bool supports_compute_subgroups_ = false; + bool supports_read_from_onscreen_texture_ = false; bool supports_read_from_resolve_ = false; bool supports_decal_tile_mode_ = false; std::optional default_color_format_ = std::nullopt;