Skip to content

Commit 87e1d0e

Browse files
committed
Merge pull request #106653 from stuartcarnie/metal_stencil_support
Metal: Ensure stencil-only rendering is supported
2 parents c225686 + 4201db6 commit 87e1d0e

File tree

3 files changed

+42
-30
lines changed

3 files changed

+42
-30
lines changed

drivers/metal/metal_objects.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ class API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) MDCommandBuffer {
355355
DIRTY_NONE = 0b0000'0000,
356356
DIRTY_PIPELINE = 0b0000'0001, //! pipeline state
357357
DIRTY_UNIFORMS = 0b0000'0010, //! uniform sets
358-
DIRTY_DEPTH = 0b0000'0100, //! depth / stenci state
358+
DIRTY_DEPTH = 0b0000'0100, //! depth / stencil state
359359
DIRTY_VERTEX = 0b0000'1000, //! vertex buffers
360360
DIRTY_VIEWPORT = 0b0001'0000, //! viewport rectangles
361361
DIRTY_SCISSOR = 0b0010'0000, //! scissor rectangles
@@ -625,8 +625,11 @@ struct API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) UniformSet {
625625
struct ShaderCacheEntry;
626626

627627
enum class ShaderLoadStrategy {
628-
DEFAULT,
628+
IMMEDIATE,
629629
LAZY,
630+
631+
/// The default strategy is to load the shader immediately.
632+
DEFAULT = IMMEDIATE,
630633
};
631634

632635
/// A Metal shader library.

drivers/metal/metal_objects.mm

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -597,37 +597,40 @@
597597
MDRenderPass const &pass = *render.pass;
598598
MDSubpass const &subpass = render.get_subpass();
599599

600-
// First determine attachments that should be cleared.
601-
LocalVector<RDD::AttachmentClear> clears;
602-
clears.reserve(subpass.color_references.size() + /* possible depth stencil clear */ 1);
600+
uint32_t ds_index = subpass.depth_stencil_reference.attachment;
601+
bool clear_depth = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, false));
602+
bool clear_stencil = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, true));
603603

604-
for (uint32_t i = 0; i < subpass.color_references.size(); i++) {
604+
uint32_t color_count = subpass.color_references.size();
605+
uint32_t clear_count = color_count + (clear_depth || clear_stencil ? 1 : 0);
606+
if (clear_count == 0) {
607+
return;
608+
}
609+
610+
RDD::AttachmentClear *clears = ALLOCA_ARRAY(RDD::AttachmentClear, clear_count);
611+
uint32_t clears_idx = 0;
612+
613+
for (uint32_t i = 0; i < color_count; i++) {
605614
uint32_t idx = subpass.color_references[i].attachment;
606615
if (idx != RDD::AttachmentReference::UNUSED && pass.attachments[idx].shouldClear(subpass, false)) {
607-
clears.push_back({ .aspect = RDD::TEXTURE_ASPECT_COLOR_BIT, .color_attachment = idx, .value = render.clear_values[idx] });
616+
clears[clears_idx++] = { .aspect = RDD::TEXTURE_ASPECT_COLOR_BIT, .color_attachment = idx, .value = render.clear_values[idx] };
608617
}
609618
}
610-
uint32_t ds_index = subpass.depth_stencil_reference.attachment;
611-
bool shouldClearDepth = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, false));
612-
bool shouldClearStencil = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, true));
613-
if (shouldClearDepth || shouldClearStencil) {
619+
620+
if (clear_depth || clear_stencil) {
614621
MDAttachment const &attachment = pass.attachments[ds_index];
615622
BitField<RDD::TextureAspectBits> bits = {};
616-
if (shouldClearDepth && attachment.type & MDAttachmentType::Depth) {
623+
if (clear_depth && attachment.type & MDAttachmentType::Depth) {
617624
bits.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
618625
}
619-
if (shouldClearStencil && attachment.type & MDAttachmentType::Stencil) {
626+
if (clear_stencil && attachment.type & MDAttachmentType::Stencil) {
620627
bits.set_flag(RDD::TEXTURE_ASPECT_STENCIL_BIT);
621628
}
622629

623-
clears.push_back({ .aspect = bits, .color_attachment = ds_index, .value = render.clear_values[ds_index] });
624-
}
625-
626-
if (clears.is_empty()) {
627-
return;
630+
clears[clears_idx++] = { .aspect = bits, .color_attachment = ds_index, .value = render.clear_values[ds_index] };
628631
}
629632

630-
render_clear_attachments(clears, { render.render_area });
633+
render_clear_attachments(VectorView(clears, clear_count), { render.render_area });
631634
}
632635

633636
void MDCommandBuffer::render_next_subpass() {
@@ -1448,9 +1451,9 @@
14481451

14491452
for (uint32_t i = 0; i < uniforms.size(); i++) {
14501453
RDD::BoundUniform const &uniform = uniforms[i];
1451-
UniformInfo ui = set.uniforms[i];
1454+
const UniformInfo &ui = set.uniforms[i];
14521455

1453-
BindingInfo *bi = ui.bindings.getptr(stage);
1456+
const BindingInfo *bi = ui.bindings.getptr(stage);
14541457
if (bi == nullptr) {
14551458
// No binding for this stage.
14561459
continue;
@@ -1481,7 +1484,7 @@
14811484
textures[j] = texture;
14821485
add_usage(texture, stage, bi->usage);
14831486
}
1484-
BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
1487+
const BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
14851488
if (sbi) {
14861489
[enc setSamplerStates:samplers withRange:NSMakeRange(sbi->index, count)];
14871490
}
@@ -1510,7 +1513,7 @@
15101513
id<MTLTexture> obj = rid::get(uniform.ids[0]);
15111514
[enc setTexture:obj atIndex:bi->index];
15121515
add_usage(obj, stage, bi->usage);
1513-
BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
1516+
const BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
15141517
if (sbi) {
15151518
id<MTLTexture> tex = obj.parentTexture ? obj.parentTexture : obj;
15161519
id<MTLBuffer> buf = tex.buffer;
@@ -1976,7 +1979,7 @@ + (instancetype)newLibraryWithCacheEntry:(ShaderCacheEntry *)entry
19761979
options:(MTLCompileOptions *)options
19771980
strategy:(ShaderLoadStrategy)strategy {
19781981
switch (strategy) {
1979-
case ShaderLoadStrategy::DEFAULT:
1982+
case ShaderLoadStrategy::IMMEDIATE:
19801983
[[fallthrough]];
19811984
default:
19821985
return [[MDImmediateLibrary alloc] initWithCacheEntry:entry device:device source:source options:options];

drivers/metal/rendering_device_driver_metal.mm

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,6 +2479,8 @@ void deserialize(BufReader &p_reader) {
24792479
options.languageVersion = binary_data.get_msl_version();
24802480
HashMap<ShaderStage, MDLibrary *> libraries;
24812481

2482+
r_name = String(binary_data.shader_name.ptr());
2483+
24822484
for (ShaderStageData &shader_data : binary_data.stages) {
24832485
r_shader_desc.stages.push_back(shader_data.stage);
24842486

@@ -2535,7 +2537,7 @@ void deserialize(BufReader &p_reader) {
25352537
su.stages = (ShaderStage)(uint8_t)uniform.stages;
25362538
uset.write[i] = su;
25372539

2538-
UniformInfo ui;
2540+
UniformInfo &ui = set.uniforms[i];
25392541
ui.binding = uniform.binding;
25402542
ui.active_stages = uniform.active_stages;
25412543
for (KeyValue<RDC::ShaderStage, BindingInfo> &kv : uniform.bindings) {
@@ -2544,7 +2546,6 @@ void deserialize(BufReader &p_reader) {
25442546
for (KeyValue<RDC::ShaderStage, BindingInfo> &kv : uniform.bindings_secondary) {
25452547
ui.bindings_secondary.insert(kv.key, kv.value);
25462548
}
2547-
set.uniforms[i] = ui;
25482549
}
25492550
}
25502551
for (UniformSetData &uniform_set : binary_data.uniforms) {
@@ -3550,17 +3551,22 @@ bool isArrayTexture(MTLTextureType p_type) {
35503551
desc.alphaToCoverageEnabled = p_multisample_state.enable_alpha_to_coverage;
35513552
desc.alphaToOneEnabled = p_multisample_state.enable_alpha_to_one;
35523553

3553-
// Depth stencil.
3554-
if (p_depth_stencil_state.enable_depth_test && desc.depthAttachmentPixelFormat != MTLPixelFormatInvalid) {
3555-
pipeline->raster_state.depth_test.enabled = true;
3554+
// Depth buffer.
3555+
bool depth_enabled = p_depth_stencil_state.enable_depth_test && desc.depthAttachmentPixelFormat != MTLPixelFormatInvalid;
3556+
bool stencil_enabled = p_depth_stencil_state.enable_stencil && desc.stencilAttachmentPixelFormat != MTLPixelFormatInvalid;
3557+
3558+
if (depth_enabled || stencil_enabled) {
35563559
MTLDepthStencilDescriptor *ds_desc = [MTLDepthStencilDescriptor new];
3560+
3561+
pipeline->raster_state.depth_test.enabled = depth_enabled;
35573562
ds_desc.depthWriteEnabled = p_depth_stencil_state.enable_depth_write;
35583563
ds_desc.depthCompareFunction = COMPARE_OPERATORS[p_depth_stencil_state.depth_compare_operator];
35593564
if (p_depth_stencil_state.enable_depth_range) {
35603565
WARN_PRINT("unsupported: depth range");
35613566
}
35623567

3563-
if (p_depth_stencil_state.enable_stencil) {
3568+
if (stencil_enabled) {
3569+
pipeline->raster_state.stencil.enabled = true;
35643570
pipeline->raster_state.stencil.front_reference = p_depth_stencil_state.front_op.reference;
35653571
pipeline->raster_state.stencil.back_reference = p_depth_stencil_state.back_op.reference;
35663572

0 commit comments

Comments
 (0)