Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller] Store the root stencil on iOS #41509

Merged
merged 4 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ EntityPass* EntityPass::AddSubpass(std::unique_ptr<EntityPass> pass) {
return subpass_pointer;
}

static RenderTarget::AttachmentConfig GetDefaultStencilConfig(bool readable) {
return RenderTarget::AttachmentConfig{
.storage_mode = readable ? StorageMode::kDevicePrivate
: StorageMode::kDeviceTransient,
.load_action = LoadAction::kDontCare,
.store_action = StoreAction::kDontCare,
};
}

static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
ISize size,
bool readable,
Expand All @@ -170,13 +179,8 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
.resolve_storage_mode = StorageMode::kDevicePrivate,
.load_action = LoadAction::kDontCare,
.store_action = StoreAction::kMultisampleResolve,
.clear_color = clear_color}, // color_attachment_config
RenderTarget::AttachmentConfig{
.storage_mode = readable ? StorageMode::kDevicePrivate
: StorageMode::kDeviceTransient,
.load_action = LoadAction::kDontCare,
.store_action = StoreAction::kDontCare,
} // stencil_attachment_config
.clear_color = clear_color}, // color_attachment_config
GetDefaultStencilConfig(readable) // stencil_attachment_config
);
} else {
target = RenderTarget::CreateOffscreen(
Expand All @@ -187,13 +191,8 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
.storage_mode = StorageMode::kDevicePrivate,
.load_action = LoadAction::kDontCare,
.store_action = StoreAction::kDontCare,
}, // color_attachment_config
RenderTarget::AttachmentConfig{
.storage_mode = readable ? StorageMode::kDevicePrivate
: StorageMode::kDeviceTransient,
.load_action = LoadAction::kDontCare,
.store_action = StoreAction::kDontCare,
} // stencil_attachment_config
}, // color_attachment_config
GetDefaultStencilConfig(readable) // stencil_attachment_config
);
}

Expand All @@ -215,16 +214,28 @@ bool EntityPass::Render(ContentContext& renderer,
return false;
}

if (!render_target.GetStencilAttachment().has_value()) {
VALIDATION_LOG << "The root RenderTarget must have a stencil attachment.";
return false;
}

auto stencil_texture = render_target.GetStencilAttachment()->texture;
if (!stencil_texture) {
VALIDATION_LOG << "The root RenderTarget must have a stencil texture.";
return false;
}

StencilCoverageStack stencil_coverage_stack = {StencilCoverageLayer{
.coverage = Rect::MakeSize(render_target.GetRenderTargetSize()),
.stencil_depth = 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();
renderer.GetDeviceCapabilities().SupportsReadFromResolve() &&
stencil_texture->GetTextureDescriptor().storage_mode !=
StorageMode::kDeviceTransient;
if (!supports_root_pass_reads && GetTotalPassReads(renderer) > 0) {
auto offscreen_target =
CreateRenderTarget(renderer, render_target.GetRenderTargetSize(), true,
Expand Down
2 changes: 1 addition & 1 deletion impeller/renderer/backend/metal/surface_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
color0.resolve_texture = resolve_tex;

TextureDescriptor stencil_tex_desc;
stencil_tex_desc.storage_mode = StorageMode::kDeviceTransient;
stencil_tex_desc.storage_mode = StorageMode::kDevicePrivate;
stencil_tex_desc.type = TextureType::kTexture2DMultisample;
stencil_tex_desc.sample_count = SampleCount::kCount4;
stencil_tex_desc.format =
Expand Down
4 changes: 2 additions & 2 deletions impeller/renderer/backend/vulkan/surface_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
color0.resolve_texture = resolve_tex;

TextureDescriptor stencil0_tex;
stencil0_tex.storage_mode = StorageMode::kDeviceTransient;
stencil0_tex.type = TextureType::kTexture2D;
stencil0_tex.storage_mode = StorageMode::kDevicePrivate;
stencil0_tex.type = TextureType::kTexture2DMultisample;
stencil0_tex.sample_count = SampleCount::kCount4;
stencil0_tex.format = context->GetCapabilities()->GetDefaultStencilFormat();
stencil0_tex.size = msaa_tex_desc.size;
Expand Down
75 changes: 35 additions & 40 deletions impeller/renderer/render_target.cc
Original file line number Diff line number Diff line change
Expand Up @@ -239,25 +239,8 @@ RenderTarget RenderTarget::CreateOffscreen(
target.SetColorAttachment(color0, 0u);

if (stencil_attachment_config.has_value()) {
TextureDescriptor stencil_tex0;
stencil_tex0.storage_mode = stencil_attachment_config->storage_mode;
stencil_tex0.format = context.GetCapabilities()->GetDefaultStencilFormat();
stencil_tex0.size = size;
stencil_tex0.usage =
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);

StencilAttachment stencil0;
stencil0.load_action = stencil_attachment_config->load_action;
stencil0.store_action = stencil_attachment_config->store_action;
stencil0.clear_stencil = 0u;
stencil0.texture =
context.GetResourceAllocator()->CreateTexture(stencil_tex0);

if (!stencil0.texture) {
return {};
}
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label.c_str()));
target.SetStencilAttachment(std::move(stencil0));
target.SetupStencilAttachment(context, size, false, label,
stencil_attachment_config.value());
} else {
target.SetStencilAttachment(std::nullopt);
}
Expand Down Expand Up @@ -331,34 +314,46 @@ RenderTarget RenderTarget::CreateOffscreenMSAA(
// Create MSAA stencil texture.

if (stencil_attachment_config.has_value()) {
TextureDescriptor stencil_tex0;
stencil_tex0.storage_mode = stencil_attachment_config->storage_mode;
stencil_tex0.type = TextureType::kTexture2DMultisample;
stencil_tex0.sample_count = SampleCount::kCount4;
stencil_tex0.format = context.GetCapabilities()->GetDefaultStencilFormat();
stencil_tex0.size = size;
stencil_tex0.usage =
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);

StencilAttachment stencil0;
stencil0.load_action = stencil_attachment_config->load_action;
stencil0.store_action = stencil_attachment_config->store_action;
stencil0.clear_stencil = 0u;
stencil0.texture =
context.GetResourceAllocator()->CreateTexture(stencil_tex0);

if (!stencil0.texture) {
return {};
}
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label.c_str()));
target.SetStencilAttachment(std::move(stencil0));
target.SetupStencilAttachment(context, size, true, label,
stencil_attachment_config.value());
} else {
target.SetStencilAttachment(std::nullopt);
}

return target;
}

void RenderTarget::SetupStencilAttachment(
const Context& context,
ISize size,
bool msaa,
const std::string& label,
AttachmentConfig stencil_attachment_config) {
TextureDescriptor stencil_tex0;
stencil_tex0.storage_mode = stencil_attachment_config.storage_mode;
if (msaa) {
stencil_tex0.type = TextureType::kTexture2DMultisample;
stencil_tex0.sample_count = SampleCount::kCount4;
}
stencil_tex0.format = context.GetCapabilities()->GetDefaultStencilFormat();
stencil_tex0.size = size;
stencil_tex0.usage =
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);

StencilAttachment stencil0;
stencil0.load_action = stencil_attachment_config.load_action;
stencil0.store_action = stencil_attachment_config.store_action;
stencil0.clear_stencil = 0u;
stencil0.texture =
context.GetResourceAllocator()->CreateTexture(stencil_tex0);

if (!stencil0.texture) {
return; // Error messages are handled by `Allocator::CreateTexture`.
}
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label.c_str()));
SetStencilAttachment(std::move(stencil0));
}

size_t RenderTarget::GetTotalAttachmentCount() const {
size_t count = 0u;
for (const auto& [_, color] : colors_) {
Expand Down
7 changes: 7 additions & 0 deletions impeller/renderer/render_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ class RenderTarget final {

bool IsValid() const;

void SetupStencilAttachment(const Context& context,
ISize size,
bool msaa,
const std::string& label = "Offscreen",
AttachmentConfig stencil_attachment_config =
kDefaultStencilAttachmentConfig);

SampleCount GetSampleCount() const;

bool HasColorAttachment(size_t index) const;
Expand Down