From c339d8df2783109cf43a4a53a32da9e11f6c24f2 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. --- 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 ca9a40c02ee..cb54a271e52 100644 --- a/src/kosmickrisp/compiler/nir_to_msl.c +++ b/src/kosmickrisp/compiler/nir_to_msl.c @@ -1005,7 +1005,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 7882edf1662..21861b72691 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);