From de6ca8c7ec4616ec8d4560d7364c6113c707ac91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 10 Apr 2025 21:19:45 -0400 Subject: [PATCH] radeonsi: gather writes_z/stencil/sample_mask as shader variant info si_get_shader_variant_info doesn't need to check the kill flags because killed stores are removed from NIR before that. Only shader variants need to clear the writes_* flags if the epilog kills them. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/drivers/radeonsi/si_shader.c | 42 +++++++++---------- src/gallium/drivers/radeonsi/si_shader.h | 6 +-- src/gallium/drivers/radeonsi/si_shader_llvm.c | 4 +- .../drivers/radeonsi/si_state_shaders.cpp | 10 ++--- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 2cb8af8e24b..c39aaf0bd74 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1325,9 +1325,9 @@ void si_shader_dump_stats_for_shader_db(struct si_screen *screen, struct si_shad unreachable("invalid shader key"); } else if (shader->selector->stage == MESA_SHADER_FRAGMENT) { num_ps_outputs = util_bitcount(shader->selector->info.colors_written) + - (shader->ps.writes_z || - shader->ps.writes_stencil || - shader->ps.writes_samplemask); + (shader->info.writes_z || + shader->info.writes_stencil || + shader->info.writes_sample_mask); } util_debug_message(debug, SHADER_INFO, @@ -2857,6 +2857,18 @@ si_get_shader_variant_info(struct si_shader *shader, nir_shader *nir) nir_intrinsic_atomic_op(intr) != nir_atomic_op_ordered_add_gfx12_amd)) shader->info.uses_vmem_load_other = true; break; + case nir_intrinsic_store_output: + if (nir->info.stage == MESA_SHADER_FRAGMENT) { + nir_io_semantics sem = nir_intrinsic_io_semantics(intr); + + if (sem.location == FRAG_RESULT_DEPTH) + shader->info.writes_z = true; + else if (sem.location == FRAG_RESULT_STENCIL) + shader->info.writes_stencil = true; + else if (sem.location == FRAG_RESULT_SAMPLE_MASK) + shader->info.writes_sample_mask = true; + } + break; default: break; } @@ -3144,29 +3156,13 @@ debug_message_stderr(void *data, unsigned *id, enum util_debug_type ptype, fprintf(stderr, "\n"); } -static void -determine_shader_variant_info(struct si_screen *sscreen, struct si_shader *shader) -{ - struct si_shader_selector *sel = shader->selector; - - if (sel->stage == MESA_SHADER_FRAGMENT) { - shader->ps.writes_z = sel->info.writes_z && !shader->key.ps.part.epilog.kill_z; - shader->ps.writes_stencil = sel->info.writes_stencil && - !shader->key.ps.part.epilog.kill_stencil; - shader->ps.writes_samplemask = sel->info.writes_samplemask && - !shader->key.ps.part.epilog.kill_samplemask; - } -} - bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, struct si_shader *shader, struct util_debug_callback *debug) { bool ret = true; struct si_shader_selector *sel = shader->selector; - - determine_shader_variant_info(sscreen, shader); - struct si_linked_shaders linked; + get_nir_shaders(shader, &linked); nir_shader *nir = linked.consumer.nir; @@ -3712,8 +3708,6 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler if (!mainp) return false; - determine_shader_variant_info(sscreen, shader); - /* Copy the compiled shader data over. */ shader->is_binary_shared = true; shader->binary = mainp->binary; @@ -3760,6 +3754,10 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler * are allocated inputs. */ shader->config.num_vgprs = MAX2(shader->config.num_vgprs, shader->info.num_input_vgprs); + + shader->info.writes_z &= !shader->key.ps.part.epilog.kill_z; + shader->info.writes_stencil &= !shader->key.ps.part.epilog.kill_stencil; + shader->info.writes_sample_mask &= !shader->key.ps.part.epilog.kill_samplemask; break; default:; } diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 5b1ce23e9c9..d8228436a45 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -878,6 +878,9 @@ struct si_shader_binary_info { bool uses_vs_state_indexed : 1; /* VS_STATE_INDEXED */ bool uses_gs_state_provoking_vtx_first : 1; bool uses_gs_state_outprim : 1; + bool writes_z : 1; + bool writes_stencil : 1; + bool writes_sample_mask : 1; uint8_t nr_pos_exports; uint8_t nr_param_exports; unsigned private_mem_vgprs; @@ -1027,9 +1030,6 @@ struct si_shader { unsigned num_interp; unsigned spi_gs_out_config_ps; unsigned pa_sc_hisz_control; - bool writes_z; - bool writes_stencil; - bool writes_samplemask; } ps; }; diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.c b/src/gallium/drivers/radeonsi/si_shader_llvm.c index b42cbf0591a..265ad2e7788 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm.c @@ -801,8 +801,8 @@ bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler * if (nir->info.stage == MESA_SHADER_FRAGMENT) { exports_color_null = sel->info.colors_written; - exports_mrtz = shader->ps.writes_z || shader->ps.writes_stencil || - shader->ps.writes_samplemask || + exports_mrtz = shader->info.writes_z || shader->info.writes_stencil || + shader->info.writes_sample_mask || shader->key.ps.part.epilog.alpha_to_coverage_via_mrtz; if (!exports_mrtz && !exports_color_null) exports_color_null = si_shader_uses_discard(shader) || sscreen->info.gfx_level < GFX10; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.cpp b/src/gallium/drivers/radeonsi/si_state_shaders.cpp index b20426ccc55..bf77ea5efbd 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.cpp +++ b/src/gallium/drivers/radeonsi/si_state_shaders.cpp @@ -2113,9 +2113,9 @@ static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader) /* DB_SHADER_CONTROL */ shader->ps.db_shader_control = - S_02880C_Z_EXPORT_ENABLE(shader->ps.writes_z) | - S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(shader->ps.writes_stencil) | - S_02880C_MASK_EXPORT_ENABLE(shader->ps.writes_samplemask) | + S_02880C_Z_EXPORT_ENABLE(shader->info.writes_z) | + S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(shader->info.writes_stencil) | + S_02880C_MASK_EXPORT_ENABLE(shader->info.writes_sample_mask) | S_02880C_COVERAGE_TO_MASK_ENABLE(sscreen->info.gfx_level <= GFX10_3 && shader->key.ps.part.epilog.alpha_to_coverage_via_mrtz) | S_02880C_KILL_ENABLE(si_shader_uses_discard(shader)); @@ -2187,8 +2187,8 @@ static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader) shader->ps.spi_ps_input_addr = shader->config.spi_ps_input_addr; shader->ps.num_interp = si_get_ps_num_interp(shader); shader->ps.spi_shader_z_format = - ac_get_spi_shader_z_format(shader->ps.writes_z, shader->ps.writes_stencil, - shader->ps.writes_samplemask, + ac_get_spi_shader_z_format(shader->info.writes_z, shader->info.writes_stencil, + shader->info.writes_sample_mask, shader->key.ps.part.epilog.alpha_to_coverage_via_mrtz); /* Ensure that some export memory is always allocated, for two reasons: