From ec37fed52b4a000b7d2466c1215f1646caf94b7c Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Wed, 31 Dec 2025 13:07:49 -0500 Subject: [PATCH] tu, ir3, nir: Plumb through driver param for alpha-to-coverage We will need this when alpha-to-coverage is dynamic and we need to emulate it. Part-of: --- src/compiler/nir/nir_divergence_analysis.c | 1 + src/compiler/nir/nir_intrinsics.py | 1 + src/freedreno/ir3/ir3_compiler_nir.c | 3 +++ src/freedreno/ir3/ir3_nir.c | 3 +++ src/freedreno/ir3/ir3_shader.h | 3 ++- src/freedreno/vulkan/tu_cmd_buffer.cc | 4 +++- src/freedreno/vulkan/tu_shader.cc | 10 +++++++--- 7 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c index 718c8160a0d..d24464d637c 100644 --- a/src/compiler/nir/nir_divergence_analysis.c +++ b/src/compiler/nir/nir_divergence_analysis.c @@ -364,6 +364,7 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state) case nir_intrinsic_load_ray_query_global_intel: case nir_intrinsic_load_call_return_address_amd: case nir_intrinsic_load_indirect_address_intel: + case nir_intrinsic_load_alpha_to_coverage_enable_ir3: is_divergent = false; break; diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index ae6410f990f..d474a1a0ca0 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -1537,6 +1537,7 @@ intrinsic("load_frag_coord_unscaled_ir3", dest_comp=4, flags=[CAN_ELIMINATE, CAN_REORDER], bit_sizes=[32]) intrinsic("load_frag_coord_gmem_ir3", dest_comp=4, flags=[CAN_ELIMINATE, CAN_REORDER], bit_sizes=[32]) +system_value("alpha_to_coverage_enable_ir3", 1) # Per-view gl_FragSizeEXT and gl_FragCoord offset. intrinsic("load_frag_size_ir3", src_comp=[1], dest_comp=2, indices=[RANGE], diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 3d707dfc9d6..6915cc18570 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -3217,6 +3217,9 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) case nir_intrinsic_load_frag_invocation_count: dst[0] = create_driver_param(ctx, IR3_DP_FS(frag_invocation_count)); break; + case nir_intrinsic_load_alpha_to_coverage_enable_ir3: + dst[0] = create_driver_param(ctx, IR3_DP_FS(alpha_to_coverage_enable)); + break; case nir_intrinsic_load_frag_size_ir3: case nir_intrinsic_load_frag_offset_ir3: case nir_intrinsic_load_gmem_frag_scale_ir3: diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index 1102a8b98b7..ed8d20c33a8 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -1761,6 +1761,9 @@ ir3_get_driver_param_info(const nir_shader *shader, nir_intrinsic_instr *intr, case nir_intrinsic_load_frag_invocation_count: param_info->offset = IR3_DP_FS(frag_invocation_count); break; + case nir_intrinsic_load_alpha_to_coverage_enable_ir3: + param_info->offset = IR3_DP_FS(alpha_to_coverage_enable); + break; default: return false; } diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h index 33f169e0324..bf393dbb180 100644 --- a/src/freedreno/ir3/ir3_shader.h +++ b/src/freedreno/ir3/ir3_shader.h @@ -103,7 +103,8 @@ struct ir3_driver_params_fs { /* Dynamic params (that aren't known when compiling the shader) */ #define IR3_DP_FS_DYNAMIC dword_offsetof(struct ir3_driver_params_fs, frag_invocation_count) uint32_t frag_invocation_count; - uint32_t __pad_05_07[3]; + uint32_t alpha_to_coverage_enable; + uint32_t __pad_06_07[2]; uint32_t frag_size; uint32_t __pad_09; uint32_t frag_offset; diff --git a/src/freedreno/vulkan/tu_cmd_buffer.cc b/src/freedreno/vulkan/tu_cmd_buffer.cc index 0a8052a6a5b..7e5b8567d3c 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.cc +++ b/src/freedreno/vulkan/tu_cmd_buffer.cc @@ -7866,7 +7866,7 @@ tu_emit_fdm_params(struct tu_cmd_buffer *cmd, STATIC_ASSERT(IR3_DP_FS(frag_invocation_count) == IR3_DP_FS_DYNAMIC); tu_cs_emit(cs, fs->fs.sample_shading ? cmd->vk.dynamic_graphics_state.ms.rasterization_samples : 1); - tu_cs_emit(cs, 0); + tu_cs_emit(cs, cmd->vk.dynamic_graphics_state.ms.alpha_to_coverage_enable); tu_cs_emit(cs, 0); tu_cs_emit(cs, 0); @@ -8229,6 +8229,8 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, bool dirty_fs_params = false; if (BITSET_TEST(cmd->vk.dynamic_graphics_state.dirty, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES) || + BITSET_TEST(cmd->vk.dynamic_graphics_state.dirty, + MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE) || (cmd->state.dirty & (TU_CMD_DIRTY_PROGRAM | TU_CMD_DIRTY_FDM))) { tu_emit_fs_params(cmd); dirty_fs_params = true; diff --git a/src/freedreno/vulkan/tu_shader.cc b/src/freedreno/vulkan/tu_shader.cc index 2617dd31d36..b04f6f919b5 100644 --- a/src/freedreno/vulkan/tu_shader.cc +++ b/src/freedreno/vulkan/tu_shader.cc @@ -678,14 +678,18 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr, nir_def_replace(&instr->def, result); return true; } - case nir_intrinsic_load_frag_invocation_count: { + case nir_intrinsic_load_frag_invocation_count: + case nir_intrinsic_load_alpha_to_coverage_enable_ir3: { if (!dev->compiler->info->props.load_shader_consts_via_preamble) return false; + unsigned offset = + instr->intrinsic == nir_intrinsic_load_frag_invocation_count ? + IR3_DP_FS(frag_invocation_count) : + IR3_DP_FS(alpha_to_coverage_enable); nir_def *result = ir3_load_driver_ubo(b, 1, &shader->const_state.fdm_ubo, - IR3_DP_FS(frag_invocation_count) - - IR3_DP_FS_DYNAMIC); + offset - IR3_DP_FS_DYNAMIC); nir_def_replace(&instr->def, result); return true;