From 0df9ba303391fbb1c19ace3244f86f35fff7a408 Mon Sep 17 00:00:00 2001 From: squidbus Date: Wed, 29 Apr 2026 18:51:25 -0700 Subject: [PATCH] kk: Fix handling of sample mask and sample rate shading Sample mask should only be limited to current sample bit when using sample rate shading, and sample shading flag in multisample state should be considered. Reviewed-by: Aitor Camacho Part-of: --- src/kosmickrisp/compiler/msl_nir_lower_common.c | 9 +++++++++ src/kosmickrisp/compiler/nir_to_msl.c | 2 +- src/kosmickrisp/vulkan/kk_shader.c | 13 +++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/kosmickrisp/compiler/msl_nir_lower_common.c b/src/kosmickrisp/compiler/msl_nir_lower_common.c index 5d9f254d487..98686418f5f 100644 --- a/src/kosmickrisp/compiler/msl_nir_lower_common.c +++ b/src/kosmickrisp/compiler/msl_nir_lower_common.c @@ -369,6 +369,15 @@ lower_sample_shading(nir_builder *b, nir_intrinsic_instr *intr, void *data) return true; } + if (intr->intrinsic == nir_intrinsic_load_sample_mask_in) { + b->cursor = nir_after_instr(&intr->instr); + nir_def *sample_id = nir_load_sample_id(b); + nir_def *sample_bit = nir_ishl(b, nir_imm_int(b, 1), sample_id); + nir_def *sample_mask_bit = nir_iand(b, &intr->def, sample_bit); + nir_def_rewrite_uses_after(&intr->def, sample_mask_bit); + return true; + } + if (intr->intrinsic != nir_intrinsic_load_interpolated_input) return false; diff --git a/src/kosmickrisp/compiler/nir_to_msl.c b/src/kosmickrisp/compiler/nir_to_msl.c index 27009b9c99c..ffccd9a7493 100644 --- a/src/kosmickrisp/compiler/nir_to_msl.c +++ b/src/kosmickrisp/compiler/nir_to_msl.c @@ -1012,7 +1012,7 @@ intrinsic_to_msl(struct nir_to_msl_ctx *ctx, nir_intrinsic_instr *instr) P(ctx, "gl_SampleID;\n"); break; case nir_intrinsic_load_sample_mask_in: - P(ctx, "gl_SampleMask & (1u << gl_SampleID);\n"); + P(ctx, "gl_SampleMask;\n"); break; case nir_intrinsic_load_sample_pos: P(ctx, "get_sample_position(gl_SampleID);\n"); diff --git a/src/kosmickrisp/vulkan/kk_shader.c b/src/kosmickrisp/vulkan/kk_shader.c index 86edaa2b925..8c4fea4e26d 100644 --- a/src/kosmickrisp/vulkan/kk_shader.c +++ b/src/kosmickrisp/vulkan/kk_shader.c @@ -127,6 +127,7 @@ struct kk_fs_key { struct vk_depth_stencil_state ds; uint32_t rasterization_samples; uint16_t static_sample_mask; + bool sample_shading_enable; bool has_depth; }; @@ -151,6 +152,7 @@ kk_populate_fs_key(struct kk_fs_key *key, if (state->ms) { key->rasterization_samples = state->ms->rasterization_samples; key->static_sample_mask = state->ms->sample_mask; + key->sample_shading_enable = state->ms->sample_shading_enable; } /* Depth writes are removed unless there's an actual attachment */ @@ -400,6 +402,9 @@ static void kk_lower_fs(struct kk_device *dev, nir_shader *nir, const struct vk_graphics_pipeline_state *state) { + nir->info.fs.uses_sample_shading |= state->ms && + state->ms->sample_shading_enable; + /* msl_nir_lower_sample_shading needs to go before blending since * nir_lower_blend will always set uses_sample_shading to true if there's any * output read. I believe we do not need to lower it always, that is why it @@ -440,8 +445,12 @@ kk_lower_fs(struct kk_device *dev, nir_shader *nir, if (!nir->info.fs.early_fragment_tests) { nir_function_impl *entrypoint = nir_shader_get_entrypoint(nir); nir_builder b = nir_builder_at(nir_after_impl(entrypoint)); - nir_discard_if(&b, - nir_ieq_imm(&b, nir_load_sample_mask_in(&b), 0u)); + + nir_def *sample_id = nir_load_sample_id(&b); + nir_def *sample_bit = nir_ishl(&b, nir_imm_int(&b, 1), sample_id); + nir_def *sample_mask_bit = nir_iand(&b, nir_load_sample_mask_in(&b), + sample_bit); + nir_discard_if(&b, nir_ieq_imm(&b, sample_mask_bit, 0u)); } } NIR_PASS(_, nir, msl_lower_static_sample_mask, state->ms->sample_mask);