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

Commit ff318fd

Browse files
authored
[Impeller] Store the root stencil on iOS (#41509)
Switch the root RenderPass stencil from transient to device private, add validation logs, and dry the offscreen stencil setup. Also make the multisample root stencil setup valid in Vulkan (the attachment mismatched the texture -- this didn't matter before since we were always replacing it). Fixes a bug where the stencil gets erased between root render passes -- this issue was introduced when we removed the root blit on iOS.
1 parent 86118e5 commit ff318fd

File tree

5 files changed

+72
-59
lines changed

5 files changed

+72
-59
lines changed

impeller/entity/entity_pass.cc

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ EntityPass* EntityPass::AddSubpass(std::unique_ptr<EntityPass> pass) {
148148
return subpass_pointer;
149149
}
150150

151+
static RenderTarget::AttachmentConfig GetDefaultStencilConfig(bool readable) {
152+
return RenderTarget::AttachmentConfig{
153+
.storage_mode = readable ? StorageMode::kDevicePrivate
154+
: StorageMode::kDeviceTransient,
155+
.load_action = LoadAction::kDontCare,
156+
.store_action = StoreAction::kDontCare,
157+
};
158+
}
159+
151160
static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
152161
ISize size,
153162
bool readable,
@@ -170,13 +179,8 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
170179
.resolve_storage_mode = StorageMode::kDevicePrivate,
171180
.load_action = LoadAction::kDontCare,
172181
.store_action = StoreAction::kMultisampleResolve,
173-
.clear_color = clear_color}, // color_attachment_config
174-
RenderTarget::AttachmentConfig{
175-
.storage_mode = readable ? StorageMode::kDevicePrivate
176-
: StorageMode::kDeviceTransient,
177-
.load_action = LoadAction::kDontCare,
178-
.store_action = StoreAction::kDontCare,
179-
} // stencil_attachment_config
182+
.clear_color = clear_color}, // color_attachment_config
183+
GetDefaultStencilConfig(readable) // stencil_attachment_config
180184
);
181185
} else {
182186
target = RenderTarget::CreateOffscreen(
@@ -187,13 +191,8 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
187191
.storage_mode = StorageMode::kDevicePrivate,
188192
.load_action = LoadAction::kDontCare,
189193
.store_action = StoreAction::kDontCare,
190-
}, // color_attachment_config
191-
RenderTarget::AttachmentConfig{
192-
.storage_mode = readable ? StorageMode::kDevicePrivate
193-
: StorageMode::kDeviceTransient,
194-
.load_action = LoadAction::kDontCare,
195-
.store_action = StoreAction::kDontCare,
196-
} // stencil_attachment_config
194+
}, // color_attachment_config
195+
GetDefaultStencilConfig(readable) // stencil_attachment_config
197196
);
198197
}
199198

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

217+
if (!render_target.GetStencilAttachment().has_value()) {
218+
VALIDATION_LOG << "The root RenderTarget must have a stencil attachment.";
219+
return false;
220+
}
221+
222+
auto stencil_texture = render_target.GetStencilAttachment()->texture;
223+
if (!stencil_texture) {
224+
VALIDATION_LOG << "The root RenderTarget must have a stencil texture.";
225+
return false;
226+
}
227+
218228
StencilCoverageStack stencil_coverage_stack = {StencilCoverageLayer{
219229
.coverage = Rect::MakeSize(render_target.GetRenderTargetSize()),
220230
.stencil_depth = 0}};
221231

222-
//
223232
bool supports_root_pass_reads =
224233
renderer.GetDeviceCapabilities().SupportsReadFromOnscreenTexture() &&
225234
// If the backend doesn't have `SupportsReadFromResolve`, we need to flip
226235
// between two textures when restoring a previous MSAA pass.
227-
renderer.GetDeviceCapabilities().SupportsReadFromResolve();
236+
renderer.GetDeviceCapabilities().SupportsReadFromResolve() &&
237+
stencil_texture->GetTextureDescriptor().storage_mode !=
238+
StorageMode::kDeviceTransient;
228239
if (!supports_root_pass_reads && GetTotalPassReads(renderer) > 0) {
229240
auto offscreen_target =
230241
CreateRenderTarget(renderer, render_target.GetRenderTargetSize(), true,

impeller/renderer/backend/metal/surface_mtl.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
color0.resolve_texture = resolve_tex;
8585

8686
TextureDescriptor stencil_tex_desc;
87-
stencil_tex_desc.storage_mode = StorageMode::kDeviceTransient;
87+
stencil_tex_desc.storage_mode = StorageMode::kDevicePrivate;
8888
stencil_tex_desc.type = TextureType::kTexture2DMultisample;
8989
stencil_tex_desc.sample_count = SampleCount::kCount4;
9090
stencil_tex_desc.format =

impeller/renderer/backend/vulkan/surface_vk.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
6161
color0.resolve_texture = resolve_tex;
6262

6363
TextureDescriptor stencil0_tex;
64-
stencil0_tex.storage_mode = StorageMode::kDeviceTransient;
65-
stencil0_tex.type = TextureType::kTexture2D;
64+
stencil0_tex.storage_mode = StorageMode::kDevicePrivate;
65+
stencil0_tex.type = TextureType::kTexture2DMultisample;
6666
stencil0_tex.sample_count = SampleCount::kCount4;
6767
stencil0_tex.format = context->GetCapabilities()->GetDefaultStencilFormat();
6868
stencil0_tex.size = msaa_tex_desc.size;

impeller/renderer/render_target.cc

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -239,25 +239,8 @@ RenderTarget RenderTarget::CreateOffscreen(
239239
target.SetColorAttachment(color0, 0u);
240240

241241
if (stencil_attachment_config.has_value()) {
242-
TextureDescriptor stencil_tex0;
243-
stencil_tex0.storage_mode = stencil_attachment_config->storage_mode;
244-
stencil_tex0.format = context.GetCapabilities()->GetDefaultStencilFormat();
245-
stencil_tex0.size = size;
246-
stencil_tex0.usage =
247-
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
248-
249-
StencilAttachment stencil0;
250-
stencil0.load_action = stencil_attachment_config->load_action;
251-
stencil0.store_action = stencil_attachment_config->store_action;
252-
stencil0.clear_stencil = 0u;
253-
stencil0.texture =
254-
context.GetResourceAllocator()->CreateTexture(stencil_tex0);
255-
256-
if (!stencil0.texture) {
257-
return {};
258-
}
259-
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label.c_str()));
260-
target.SetStencilAttachment(std::move(stencil0));
242+
target.SetupStencilAttachment(context, size, false, label,
243+
stencil_attachment_config.value());
261244
} else {
262245
target.SetStencilAttachment(std::nullopt);
263246
}
@@ -331,34 +314,46 @@ RenderTarget RenderTarget::CreateOffscreenMSAA(
331314
// Create MSAA stencil texture.
332315

333316
if (stencil_attachment_config.has_value()) {
334-
TextureDescriptor stencil_tex0;
335-
stencil_tex0.storage_mode = stencil_attachment_config->storage_mode;
336-
stencil_tex0.type = TextureType::kTexture2DMultisample;
337-
stencil_tex0.sample_count = SampleCount::kCount4;
338-
stencil_tex0.format = context.GetCapabilities()->GetDefaultStencilFormat();
339-
stencil_tex0.size = size;
340-
stencil_tex0.usage =
341-
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
342-
343-
StencilAttachment stencil0;
344-
stencil0.load_action = stencil_attachment_config->load_action;
345-
stencil0.store_action = stencil_attachment_config->store_action;
346-
stencil0.clear_stencil = 0u;
347-
stencil0.texture =
348-
context.GetResourceAllocator()->CreateTexture(stencil_tex0);
349-
350-
if (!stencil0.texture) {
351-
return {};
352-
}
353-
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label.c_str()));
354-
target.SetStencilAttachment(std::move(stencil0));
317+
target.SetupStencilAttachment(context, size, true, label,
318+
stencil_attachment_config.value());
355319
} else {
356320
target.SetStencilAttachment(std::nullopt);
357321
}
358322

359323
return target;
360324
}
361325

326+
void RenderTarget::SetupStencilAttachment(
327+
const Context& context,
328+
ISize size,
329+
bool msaa,
330+
const std::string& label,
331+
AttachmentConfig stencil_attachment_config) {
332+
TextureDescriptor stencil_tex0;
333+
stencil_tex0.storage_mode = stencil_attachment_config.storage_mode;
334+
if (msaa) {
335+
stencil_tex0.type = TextureType::kTexture2DMultisample;
336+
stencil_tex0.sample_count = SampleCount::kCount4;
337+
}
338+
stencil_tex0.format = context.GetCapabilities()->GetDefaultStencilFormat();
339+
stencil_tex0.size = size;
340+
stencil_tex0.usage =
341+
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
342+
343+
StencilAttachment stencil0;
344+
stencil0.load_action = stencil_attachment_config.load_action;
345+
stencil0.store_action = stencil_attachment_config.store_action;
346+
stencil0.clear_stencil = 0u;
347+
stencil0.texture =
348+
context.GetResourceAllocator()->CreateTexture(stencil_tex0);
349+
350+
if (!stencil0.texture) {
351+
return; // Error messages are handled by `Allocator::CreateTexture`.
352+
}
353+
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label.c_str()));
354+
SetStencilAttachment(std::move(stencil0));
355+
}
356+
362357
size_t RenderTarget::GetTotalAttachmentCount() const {
363358
size_t count = 0u;
364359
for (const auto& [_, color] : colors_) {

impeller/renderer/render_target.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ class RenderTarget final {
7676

7777
bool IsValid() const;
7878

79+
void SetupStencilAttachment(const Context& context,
80+
ISize size,
81+
bool msaa,
82+
const std::string& label = "Offscreen",
83+
AttachmentConfig stencil_attachment_config =
84+
kDefaultStencilAttachmentConfig);
85+
7986
SampleCount GetSampleCount() const;
8087

8188
bool HasColorAttachment(size_t index) const;

0 commit comments

Comments
 (0)