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

Commit 8897901

Browse files
authored
[Impeller] Switch from transient stencil-only to depth+stencil buffer. (#47987)
Part of flutter/flutter#138460. In preparation for [draw order optimization](flutter/flutter#114402) and [StC](flutter/flutter#123671). Use a transient depth+stencil texture instead of a stencil-only texture. Doing this in isolation to detect/weed out any HAL bugs with handling the attachment.
1 parent fb4931c commit 8897901

File tree

9 files changed

+119
-58
lines changed

9 files changed

+119
-58
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,6 +3557,8 @@ TEST_P(AiksTest, GaussianBlurWithoutDecalSupport) {
35573557
.WillRepeatedly(::testing::Return(false));
35583558
FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
35593559
FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
3560+
FLT_FORWARD(mock_capabilities, old_capabilities,
3561+
GetDefaultDepthStencilFormat);
35603562
FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
35613563
FLT_FORWARD(mock_capabilities, old_capabilities,
35623564
SupportsImplicitResolvingMSAA);

impeller/entity/entity_pass.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,8 @@ bool EntityPass::Render(ContentContext& renderer,
423423
// If a root stencil was provided by the caller, then verify that it has a
424424
// configuration which can be used to render this pass.
425425
auto stencil_attachment = root_render_target.GetStencilAttachment();
426-
if (stencil_attachment.has_value()) {
426+
auto depth_attachment = root_render_target.GetDepthAttachment();
427+
if (stencil_attachment.has_value() && depth_attachment.has_value()) {
427428
auto stencil_texture = stencil_attachment->texture;
428429
if (!stencil_texture) {
429430
VALIDATION_LOG << "The root RenderTarget must have a stencil texture.";
@@ -442,7 +443,7 @@ bool EntityPass::Render(ContentContext& renderer,
442443
// Setup a new root stencil with an optimal configuration if one wasn't
443444
// provided by the caller.
444445
else {
445-
root_render_target.SetupStencilAttachment(
446+
root_render_target.SetupDepthStencilAttachments(
446447
*renderer.GetContext(), *renderer.GetRenderTargetCache(),
447448
color0.texture->GetSize(),
448449
renderer.GetContext()->GetCapabilities()->SupportsOffscreenMSAA(),

impeller/renderer/backend/gles/blit_command_gles.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static std::optional<GLuint> ConfigureFBO(
4141
gl.BindFramebuffer(fbo_type, fbo);
4242

4343
if (!TextureGLES::Cast(*texture).SetAsFramebufferAttachment(
44-
fbo_type, TextureGLES::AttachmentPoint::kColor0)) {
44+
fbo_type, TextureGLES::AttachmentType::kColor0)) {
4545
VALIDATION_LOG << "Could not attach texture to framebuffer.";
4646
DeleteFBO(gl, fbo, fbo_type);
4747
return std::nullopt;

impeller/renderer/backend/gles/render_pass_gles.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,20 +186,20 @@ struct RenderPassData {
186186

187187
if (auto color = TextureGLES::Cast(pass_data.color_attachment.get())) {
188188
if (!color->SetAsFramebufferAttachment(
189-
GL_FRAMEBUFFER, TextureGLES::AttachmentPoint::kColor0)) {
189+
GL_FRAMEBUFFER, TextureGLES::AttachmentType::kColor0)) {
190190
return false;
191191
}
192192
}
193193

194194
if (auto depth = TextureGLES::Cast(pass_data.depth_attachment.get())) {
195195
if (!depth->SetAsFramebufferAttachment(
196-
GL_FRAMEBUFFER, TextureGLES::AttachmentPoint::kDepth)) {
196+
GL_FRAMEBUFFER, TextureGLES::AttachmentType::kDepth)) {
197197
return false;
198198
}
199199
}
200200
if (auto stencil = TextureGLES::Cast(pass_data.stencil_attachment.get())) {
201201
if (!stencil->SetAsFramebufferAttachment(
202-
GL_FRAMEBUFFER, TextureGLES::AttachmentPoint::kStencil)) {
202+
GL_FRAMEBUFFER, TextureGLES::AttachmentType::kStencil)) {
203203
return false;
204204
}
205205
}

impeller/renderer/backend/gles/texture_gles.cc

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <optional>
88
#include <utility>
99

10+
#include "flutter/fml/logging.h"
1011
#include "flutter/fml/mapping.h"
1112
#include "flutter/fml/trace_event.h"
1213
#include "impeller/base/allocation.h"
@@ -17,13 +18,37 @@
1718

1819
namespace impeller {
1920

21+
static bool IsDepthStencilFormat(PixelFormat format) {
22+
switch (format) {
23+
case PixelFormat::kS8UInt:
24+
case PixelFormat::kD24UnormS8Uint:
25+
case PixelFormat::kD32FloatS8UInt:
26+
return true;
27+
case PixelFormat::kUnknown:
28+
case PixelFormat::kA8UNormInt:
29+
case PixelFormat::kR8UNormInt:
30+
case PixelFormat::kR8G8UNormInt:
31+
case PixelFormat::kR8G8B8A8UNormInt:
32+
case PixelFormat::kR8G8B8A8UNormIntSRGB:
33+
case PixelFormat::kB8G8R8A8UNormInt:
34+
case PixelFormat::kB8G8R8A8UNormIntSRGB:
35+
case PixelFormat::kR32G32B32A32Float:
36+
case PixelFormat::kR16G16B16A16Float:
37+
case PixelFormat::kB10G10R10XR:
38+
case PixelFormat::kB10G10R10XRSRGB:
39+
case PixelFormat::kB10G10R10A10XR:
40+
return false;
41+
}
42+
FML_UNREACHABLE();
43+
}
44+
2045
static TextureGLES::Type GetTextureTypeFromDescriptor(
2146
const TextureDescriptor& desc) {
2247
const auto usage = static_cast<TextureUsageMask>(desc.usage);
2348
const auto render_target =
2449
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
2550
const auto is_msaa = desc.sample_count == SampleCount::kCount4;
26-
if (usage == render_target && desc.format == PixelFormat::kS8UInt) {
51+
if (usage == render_target && IsDepthStencilFormat(desc.format)) {
2752
return is_msaa ? TextureGLES::Type::kRenderBufferMultisampled
2853
: TextureGLES::Type::kRenderBuffer;
2954
}
@@ -457,19 +482,20 @@ TextureGLES::Type TextureGLES::GetType() const {
457482
return type_;
458483
}
459484

460-
static GLenum ToAttachmentPoint(TextureGLES::AttachmentPoint point) {
485+
static GLenum ToAttachmentType(TextureGLES::AttachmentType point) {
461486
switch (point) {
462-
case TextureGLES::AttachmentPoint::kColor0:
487+
case TextureGLES::AttachmentType::kColor0:
463488
return GL_COLOR_ATTACHMENT0;
464-
case TextureGLES::AttachmentPoint::kDepth:
489+
case TextureGLES::AttachmentType::kDepth:
465490
return GL_DEPTH_ATTACHMENT;
466-
case TextureGLES::AttachmentPoint::kStencil:
491+
case TextureGLES::AttachmentType::kStencil:
467492
return GL_STENCIL_ATTACHMENT;
468493
}
469494
}
470495

471-
bool TextureGLES::SetAsFramebufferAttachment(GLenum target,
472-
AttachmentPoint point) const {
496+
bool TextureGLES::SetAsFramebufferAttachment(
497+
GLenum target,
498+
AttachmentType attachment_type) const {
473499
if (!IsValid()) {
474500
return false;
475501
}
@@ -482,29 +508,30 @@ bool TextureGLES::SetAsFramebufferAttachment(GLenum target,
482508

483509
switch (type_) {
484510
case Type::kTexture:
485-
gl.FramebufferTexture2D(target, // target
486-
ToAttachmentPoint(point), // attachment
487-
GL_TEXTURE_2D, // textarget
488-
handle.value(), // texture
489-
0 // level
511+
gl.FramebufferTexture2D(target, // target
512+
ToAttachmentType(attachment_type), // attachment
513+
GL_TEXTURE_2D, // textarget
514+
handle.value(), // texture
515+
0 // level
490516
);
491517
break;
492518
case Type::kTextureMultisampled:
493519
gl.FramebufferTexture2DMultisampleEXT(
494-
target, // target
495-
ToAttachmentPoint(point), // attachment
496-
GL_TEXTURE_2D, // textarget
497-
handle.value(), // texture
498-
0, // level
499-
4 // samples
520+
target, // target
521+
ToAttachmentType(attachment_type), // attachment
522+
GL_TEXTURE_2D, // textarget
523+
handle.value(), // texture
524+
0, // level
525+
4 // samples
500526
);
501527
break;
502528
case Type::kRenderBuffer:
503529
case Type::kRenderBufferMultisampled:
504-
gl.FramebufferRenderbuffer(target, // target
505-
ToAttachmentPoint(point), // attachment
506-
GL_RENDERBUFFER, // render-buffer target
507-
handle.value() // render-buffer
530+
gl.FramebufferRenderbuffer(
531+
target, // target
532+
ToAttachmentType(attachment_type), // attachment
533+
GL_RENDERBUFFER, // render-buffer target
534+
handle.value() // render-buffer
508535
);
509536
break;
510537
}

impeller/renderer/backend/gles/texture_gles.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,14 @@ class TextureGLES final : public Texture,
4141

4242
[[nodiscard]] bool GenerateMipmap();
4343

44-
enum class AttachmentPoint {
44+
enum class AttachmentType {
4545
kColor0,
4646
kDepth,
4747
kStencil,
4848
};
49-
[[nodiscard]] bool SetAsFramebufferAttachment(GLenum target,
50-
AttachmentPoint point) const;
49+
[[nodiscard]] bool SetAsFramebufferAttachment(
50+
GLenum target,
51+
AttachmentType attachment_type) const;
5152

5253
Type GetType() const;
5354

impeller/renderer/render_target.cc

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ RenderTarget RenderTarget::CreateOffscreen(
255255
target.SetColorAttachment(color0, 0u);
256256

257257
if (stencil_attachment_config.has_value()) {
258-
target.SetupStencilAttachment(context, allocator, size, false, label,
259-
stencil_attachment_config.value());
258+
target.SetupDepthStencilAttachments(context, allocator, size, false, label,
259+
stencil_attachment_config.value());
260260
} else {
261261
target.SetStencilAttachment(std::nullopt);
262262
}
@@ -347,43 +347,56 @@ RenderTarget RenderTarget::CreateOffscreenMSAA(
347347
// Create MSAA stencil texture.
348348

349349
if (stencil_attachment_config.has_value()) {
350-
target.SetupStencilAttachment(context, allocator, size, true, label,
351-
stencil_attachment_config.value());
350+
target.SetupDepthStencilAttachments(context, allocator, size, true, label,
351+
stencil_attachment_config.value());
352352
} else {
353353
target.SetStencilAttachment(std::nullopt);
354354
}
355355

356356
return target;
357357
}
358358

359-
void RenderTarget::SetupStencilAttachment(
359+
void RenderTarget::SetupDepthStencilAttachments(
360360
const Context& context,
361361
RenderTargetAllocator& allocator,
362362
ISize size,
363363
bool msaa,
364364
const std::string& label,
365365
AttachmentConfig stencil_attachment_config) {
366-
TextureDescriptor stencil_tex0;
367-
stencil_tex0.storage_mode = stencil_attachment_config.storage_mode;
366+
TextureDescriptor depth_stencil_texture_desc;
367+
depth_stencil_texture_desc.storage_mode =
368+
stencil_attachment_config.storage_mode;
368369
if (msaa) {
369-
stencil_tex0.type = TextureType::kTexture2DMultisample;
370-
stencil_tex0.sample_count = SampleCount::kCount4;
370+
depth_stencil_texture_desc.type = TextureType::kTexture2DMultisample;
371+
depth_stencil_texture_desc.sample_count = SampleCount::kCount4;
371372
}
372-
stencil_tex0.format = context.GetCapabilities()->GetDefaultStencilFormat();
373-
stencil_tex0.size = size;
374-
stencil_tex0.usage =
373+
depth_stencil_texture_desc.format =
374+
context.GetCapabilities()->GetDefaultDepthStencilFormat();
375+
depth_stencil_texture_desc.size = size;
376+
depth_stencil_texture_desc.usage =
375377
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
376378

379+
auto depth_stencil_texture =
380+
allocator.CreateTexture(depth_stencil_texture_desc);
381+
if (!depth_stencil_texture) {
382+
return; // Error messages are handled by `Allocator::CreateTexture`.
383+
}
384+
385+
DepthAttachment depth0;
386+
depth0.load_action = stencil_attachment_config.load_action;
387+
depth0.store_action = stencil_attachment_config.store_action;
388+
depth0.clear_depth = 0u;
389+
depth0.texture = depth_stencil_texture;
390+
377391
StencilAttachment stencil0;
378392
stencil0.load_action = stencil_attachment_config.load_action;
379393
stencil0.store_action = stencil_attachment_config.store_action;
380394
stencil0.clear_stencil = 0u;
381-
stencil0.texture = allocator.CreateTexture(stencil_tex0);
395+
stencil0.texture = depth_stencil_texture;
382396

383-
if (!stencil0.texture) {
384-
return; // Error messages are handled by `Allocator::CreateTexture`.
385-
}
386-
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label.c_str()));
397+
stencil0.texture->SetLabel(
398+
SPrintF("%s Depth+Stencil Texture", label.c_str()));
399+
SetDepthAttachment(std::move(depth0));
387400
SetStencilAttachment(std::move(stencil0));
388401
}
389402

@@ -403,6 +416,9 @@ size_t RenderTarget::GetTotalAttachmentCount() const {
403416
if (stencil_.has_value()) {
404417
count++;
405418
}
419+
if (depth_.has_value()) {
420+
count++;
421+
}
406422
return count;
407423
}
408424

impeller/renderer/render_target.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,13 @@ class RenderTarget final {
109109

110110
bool IsValid() const;
111111

112-
void SetupStencilAttachment(const Context& context,
113-
RenderTargetAllocator& allocator,
114-
ISize size,
115-
bool msaa,
116-
const std::string& label = "Offscreen",
117-
AttachmentConfig stencil_attachment_config =
118-
kDefaultStencilAttachmentConfig);
112+
void SetupDepthStencilAttachments(const Context& context,
113+
RenderTargetAllocator& allocator,
114+
ISize size,
115+
bool msaa,
116+
const std::string& label = "Offscreen",
117+
AttachmentConfig stencil_attachment_config =
118+
kDefaultStencilAttachmentConfig);
119119

120120
SampleCount GetSampleCount() const;
121121

impeller/renderer/renderer_unittests.cc

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,9 +1161,9 @@ TEST_P(RendererTest, StencilMask) {
11611161
stencil_config.storage_mode = StorageMode::kHostVisible;
11621162
auto render_target_allocator =
11631163
RenderTargetAllocator(context->GetResourceAllocator());
1164-
render_target.SetupStencilAttachment(*context, render_target_allocator,
1165-
render_target.GetRenderTargetSize(),
1166-
true, "stencil", stencil_config);
1164+
render_target.SetupDepthStencilAttachments(
1165+
*context, render_target_allocator,
1166+
render_target.GetRenderTargetSize(), true, "stencil", stencil_config);
11671167
// Fill the stencil buffer with an checkerboard pattern.
11681168
const auto target_width = render_target.GetRenderTargetSize().width;
11691169
const auto target_height = render_target.GetRenderTargetSize().height;
@@ -1289,6 +1289,20 @@ TEST_P(RendererTest, CanLookupRenderTargetProperties) {
12891289
render_target.GetRenderTargetSize());
12901290
}
12911291

1292+
TEST_P(RendererTest,
1293+
RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat) {
1294+
auto context = GetContext();
1295+
auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1296+
GetContext()->GetResourceAllocator());
1297+
1298+
RenderTarget render_target = RenderTarget::CreateOffscreenMSAA(
1299+
*context, *render_target_cache, {100, 100}, /*mip_count=*/1);
1300+
EXPECT_EQ(render_target.GetDepthAttachment()
1301+
->texture->GetTextureDescriptor()
1302+
.format,
1303+
GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1304+
}
1305+
12921306
} // namespace testing
12931307
} // namespace impeller
12941308

0 commit comments

Comments
 (0)