From e73f70e135149f808f845822bf4b98378e572d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 26 May 2025 04:09:29 -0400 Subject: [PATCH] radeonsi: add si_shader_variant_info::clip/culldist_mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit so that it can be different between shader variants Reviewed-by: Pierre-Eric Pelloux-Prayer Acked-by: Timur Kristóf Part-of: --- src/gallium/drivers/radeonsi/si_shader.c | 39 +++++++------------ src/gallium/drivers/radeonsi/si_shader_info.c | 8 ++-- src/gallium/drivers/radeonsi/si_shader_info.h | 4 +- .../drivers/radeonsi/si_shader_variant_info.c | 20 +++++++--- src/gallium/drivers/radeonsi/si_state.c | 14 +++---- .../drivers/radeonsi/si_state_draw.cpp | 5 ++- .../drivers/radeonsi/si_state_shaders.cpp | 9 ++--- 7 files changed, 47 insertions(+), 52 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index f56b4a0c994..e7b5390a2a2 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1112,10 +1112,6 @@ static void si_lower_ngg(struct si_shader *shader, nir_shader *nir, const union si_shader_key *key = &shader->key; assert(key->ge.as_ngg); - uint8_t clip_cull_dist_mask = - (sel->info.clipdist_mask & ~key->ge.opt.kill_clip_distances) | - sel->info.culldist_mask; - ac_nir_lower_ngg_options options = { .hw_info = &sel->screen->info, .max_workgroup_size = si_get_max_workgroup_size(shader), @@ -1124,7 +1120,7 @@ static void si_lower_ngg(struct si_shader *shader, nir_shader *nir, .disable_streamout = !shader->info.num_streamout_vec4s, .vs_output_param_offset = temp_info->vs_output_param_offset, .has_param_exports = shader->info.nr_param_exports, - .export_clipdist_mask = clip_cull_dist_mask, + .export_clipdist_mask = shader->info.clipdist_mask | shader->info.culldist_mask, .force_vrs = sel->screen->options.vrs2x2, .use_gfx12_xfb_intrinsic = !nir->info.use_aco_amd, .skip_viewport_state_culling = sel->info.writes_viewport_index, @@ -1290,23 +1286,21 @@ static void si_assign_param_offsets(nir_shader *nir, struct si_shader *shader, } } -static unsigned si_get_nr_pos_exports(const struct si_shader_selector *sel, - const union si_shader_key *key) +static unsigned si_get_nr_pos_exports(const struct si_shader *shader) { - const struct si_shader_info *info = &sel->info; + const struct si_shader_info *info = &shader->selector->info; /* Must have a position export. */ unsigned nr_pos_exports = 1; - if ((info->writes_psize && !key->ge.opt.kill_pointsize) || - (info->writes_edgeflag && !key->ge.as_ngg) || - (info->writes_layer && !key->ge.opt.kill_layer) || - info->writes_viewport_index || sel->screen->options.vrs2x2) { + if ((info->writes_psize && !shader->key.ge.opt.kill_pointsize) || + (info->writes_edgeflag && !shader->key.ge.as_ngg) || + (info->writes_layer && !shader->key.ge.opt.kill_layer) || + info->writes_viewport_index || shader->selector->screen->options.vrs2x2) { nr_pos_exports++; } - unsigned clipdist_mask = - (info->clipdist_mask & ~key->ge.opt.kill_clip_distances) | info->culldist_mask; + unsigned clipdist_mask = shader->info.clipdist_mask | shader->info.culldist_mask; for (int i = 0; i < 2; i++) { if (clipdist_mask & BITFIELD_RANGE(i * 4, 4)) @@ -1556,7 +1550,7 @@ static void run_late_optimization_and_lowering_passes(struct si_nir_shader_ctx * si_assign_param_offsets(nir, shader, &ctx->temp_info); /* Assign num of position exports. */ - shader->info.nr_pos_exports = si_get_nr_pos_exports(sel, key); + shader->info.nr_pos_exports = si_get_nr_pos_exports(shader); if (key->ge.as_ngg) { /* Lower last VGT NGG shader stage. */ @@ -1564,13 +1558,9 @@ static void run_late_optimization_and_lowering_passes(struct si_nir_shader_ctx * } else if (nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_TESS_EVAL) { /* Lower last VGT none-NGG VS/TES shader stage. */ - unsigned clip_cull_mask = - (sel->info.clipdist_mask & ~key->ge.opt.kill_clip_distances) | - sel->info.culldist_mask; - NIR_PASS_V(nir, ac_nir_lower_legacy_vs, sel->screen->info.gfx_level, - clip_cull_mask, + shader->info.clipdist_mask | shader->info.culldist_mask, false, false, ctx->temp_info.vs_output_param_offset, shader->info.nr_param_exports, @@ -1598,14 +1588,11 @@ static void run_late_optimization_and_lowering_passes(struct si_nir_shader_ctx * ctx->temp_info.vs_output_param_offset[semantic] = shader->info.nr_param_exports++; } - unsigned clip_cull_mask = - (sel->info.clipdist_mask & ~shader->key.ge.opt.kill_clip_distances) | sel->info.culldist_mask; - ac_nir_lower_legacy_gs_options options = { .has_gen_prim_query = false, .has_pipeline_stats_query = sel->screen->use_ngg, .gfx_level = sel->screen->info.gfx_level, - .export_clipdist_mask = clip_cull_mask, + .export_clipdist_mask = shader->info.clipdist_mask | shader->info.culldist_mask, .param_offsets = ctx->temp_info.vs_output_param_offset, .has_param_exports = shader->info.nr_param_exports, .disable_streamout = !shader->info.num_streamout_vec4s, @@ -1888,8 +1875,10 @@ si_nir_generate_gs_copy_shader(struct si_screen *sscreen, shader->is_gs_copy_shader = true; shader->wave_size = si_determine_wave_size(sscreen, shader); shader->info.num_streamout_vec4s = gs_shader->info.num_streamout_vec4s; - shader->info.nr_pos_exports = si_get_nr_pos_exports(gs_selector, &gs_shader->key); + shader->info.nr_pos_exports = si_get_nr_pos_exports(gs_shader); shader->info.nr_param_exports = gs_shader->info.nr_param_exports; + shader->info.clipdist_mask = gs_shader->info.clipdist_mask; + shader->info.culldist_mask = gs_shader->info.culldist_mask; nir_shader *nir = gs_copy_shader; struct si_linked_shaders linked; diff --git a/src/gallium/drivers/radeonsi/si_shader_info.c b/src/gallium/drivers/radeonsi/si_shader_info.c index 1bc1e793841..204dc42e7c9 100644 --- a/src/gallium/drivers/radeonsi/si_shader_info.c +++ b/src/gallium/drivers/radeonsi/si_shader_info.c @@ -542,7 +542,6 @@ void si_nir_scan_shader(struct si_screen *sscreen, struct nir_shader *nir, info->writes_viewport_index = nir->info.outputs_written & VARYING_BIT_VIEWPORT; info->writes_layer = nir->info.outputs_written & VARYING_BIT_LAYER; info->writes_psize = nir->info.outputs_written & VARYING_BIT_PSIZ; - info->writes_clipvertex = nir->info.outputs_written & VARYING_BIT_CLIP_VERTEX; info->writes_edgeflag = nir->info.outputs_written & VARYING_BIT_EDGE; if (nir->xfb_info) { @@ -641,10 +640,9 @@ void si_nir_scan_shader(struct si_screen *sscreen, struct nir_shader *nir, mesa_vertices_per_prim(nir->info.gs.input_primitive); } - info->clipdist_mask = info->writes_clipvertex ? SI_USER_CLIP_PLANE_MASK : - u_bit_consecutive(0, nir->info.clip_distance_array_size); - info->culldist_mask = u_bit_consecutive(0, nir->info.cull_distance_array_size) << - nir->info.clip_distance_array_size; + info->clipdist_mask = nir->info.outputs_written & VARYING_BIT_CLIP_VERTEX ? + SI_USER_CLIP_PLANE_MASK : + BITFIELD_MASK(nir->info.clip_distance_array_size); if (nir->info.stage == MESA_SHADER_FRAGMENT) { for (unsigned i = 0; i < info->num_inputs; i++) { diff --git a/src/gallium/drivers/radeonsi/si_shader_info.h b/src/gallium/drivers/radeonsi/si_shader_info.h index a9aaf3b6eb4..e9123882588 100644 --- a/src/gallium/drivers/radeonsi/si_shader_info.h +++ b/src/gallium/drivers/radeonsi/si_shader_info.h @@ -109,7 +109,6 @@ struct si_shader_info { uint8_t num_tess_level_vram_outputs; /* max "get_unique_index_patch" + 1*/ uint8_t clipdist_mask; - uint8_t culldist_mask; bool gs_writes_stream0; uint16_t esgs_vertex_stride; @@ -159,7 +158,6 @@ struct si_shader_info { bool uses_tg_size; bool uses_atomic_ordered_add; bool writes_psize; - bool writes_clipvertex; bool writes_primid; bool writes_viewport_index; bool writes_layer; @@ -223,6 +221,8 @@ struct si_shader_variant_info { bool uses_discard : 1; uint8_t nr_pos_exports; uint8_t nr_param_exports; + uint8_t clipdist_mask; + uint8_t culldist_mask; uint8_t num_streamout_vec4s; uint8_t ngg_lds_scratch_size; unsigned private_mem_vgprs; diff --git a/src/gallium/drivers/radeonsi/si_shader_variant_info.c b/src/gallium/drivers/radeonsi/si_shader_variant_info.c index 4ab6b152cbf..6ebd7946619 100644 --- a/src/gallium/drivers/radeonsi/si_shader_variant_info.c +++ b/src/gallium/drivers/radeonsi/si_shader_variant_info.c @@ -249,13 +249,21 @@ void si_get_shader_variant_info(struct si_shader *shader, } } - if (nir->info.stage <= MESA_SHADER_GEOMETRY && nir->xfb_info && - !shader->key.ge.as_ls && !shader->key.ge.as_es) { - unsigned num_streamout_dwords = 0; + if (nir->info.stage <= MESA_SHADER_GEOMETRY) { + if (!shader->key.ge.as_ls && !shader->key.ge.as_es) { + if (nir->xfb_info) { + unsigned num_streamout_dwords = 0; - for (unsigned i = 0; i < 4; i++) - num_streamout_dwords += nir->info.xfb_stride[i]; - shader->info.num_streamout_vec4s = DIV_ROUND_UP(num_streamout_dwords, 4); + for (unsigned i = 0; i < 4; i++) + num_streamout_dwords += nir->info.xfb_stride[i]; + shader->info.num_streamout_vec4s = DIV_ROUND_UP(num_streamout_dwords, 4); + } + + shader->info.clipdist_mask = shader->selector->info.clipdist_mask & + ~shader->key.ge.opt.kill_clip_distances; + shader->info.culldist_mask = BITFIELD_RANGE(nir->info.clip_distance_array_size, + nir->info.cull_distance_array_size); + } } } diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 2d655d7ef98..5d1b7a9d1d7 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -892,22 +892,20 @@ static void si_emit_clip_state(struct si_context *sctx, unsigned index) static void si_emit_clip_regs(struct si_context *sctx, unsigned index) { struct si_shader *vs = si_get_vs(sctx)->current; - struct si_shader_selector *vs_sel = vs->selector; - struct si_shader_info *info = &vs_sel->info; struct si_state_rasterizer *rs = sctx->queued.named.rasterizer; - bool window_space = vs_sel->stage == MESA_SHADER_VERTEX ? - info->base.vs.window_space_position : 0; + bool window_space = vs->selector->stage == MESA_SHADER_VERTEX ? + vs->selector->info.base.vs.window_space_position : 0; unsigned ucp_mask = 0, clipdist_mask = 0, culldist_mask = 0; - if (!vs_sel->info.clipdist_mask && !vs_sel->info.culldist_mask) { - assert(!vs_sel->info.culldist_mask); + if (!vs->info.clipdist_mask && !vs->info.culldist_mask) { + assert(!vs->info.culldist_mask); ucp_mask = SI_USER_CLIP_PLANE_MASK & rs->clip_plane_enable; } else { - clipdist_mask = vs_sel->info.clipdist_mask & rs->clip_plane_enable; + clipdist_mask = vs->info.clipdist_mask & rs->clip_plane_enable; /* For points, we need to set the cull distance bits too because the clip distance bits have * no effect on them. */ - culldist_mask = vs_sel->info.culldist_mask | clipdist_mask; + culldist_mask = vs->info.culldist_mask | clipdist_mask; } unsigned pa_cl_cntl = S_02881C_BYPASS_VTX_RATE_COMBINER(sctx->gfx_level >= GFX10_3 && diff --git a/src/gallium/drivers/radeonsi/si_state_draw.cpp b/src/gallium/drivers/radeonsi/si_state_draw.cpp index ce71fa368c4..89154efefa3 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.cpp +++ b/src/gallium/drivers/radeonsi/si_state_draw.cpp @@ -264,7 +264,10 @@ static bool si_update_shaders(struct si_context *sctx) sctx->dirty_atoms |= SI_STATE_BIT(rasterizer); } - if (old_pa_cl_vs_out_cntl != hw_vs->pa_cl_vs_out_cntl) + if (old_pa_cl_vs_out_cntl != hw_vs->pa_cl_vs_out_cntl || + (!old_vs || + old_vs->info.clipdist_mask != hw_vs->info.clipdist_mask || + old_vs->info.culldist_mask != hw_vs->info.culldist_mask)) si_mark_atom_dirty(sctx, &sctx->atoms.s.clip_regs); /* If we start to use any of these, we need to update the SGPR. */ diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.cpp b/src/gallium/drivers/radeonsi/si_state_shaders.cpp index 9ceb8e1facc..12d34bb516c 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.cpp +++ b/src/gallium/drivers/radeonsi/si_state_shaders.cpp @@ -1350,8 +1350,7 @@ static unsigned si_get_vs_out_cntl(const struct si_shader_selector *sel, const struct si_shader *shader, bool ngg) { /* Clip distances can be killed, but cull distances can't. */ - unsigned clipcull_mask = (sel->info.clipdist_mask & ~shader->key.ge.opt.kill_clip_distances) | - sel->info.culldist_mask; + unsigned clipcull_mask = shader->info.clipdist_mask | shader->info.culldist_mask; bool writes_psize = sel->info.writes_psize && !shader->key.ge.opt.kill_pointsize; bool writes_layer = sel->info.writes_layer && !shader->key.ge.opt.kill_layer; bool misc_vec_ena = writes_psize || (sel->info.writes_edgeflag && !ngg) || @@ -3624,9 +3623,9 @@ static void si_update_clip_regs(struct si_context *sctx, struct si_shader_select (!old_hw_vs || (old_hw_vs->stage == MESA_SHADER_VERTEX && old_hw_vs->info.base.vs.window_space_position) != (next_hw_vs->stage == MESA_SHADER_VERTEX && next_hw_vs->info.base.vs.window_space_position) || - old_hw_vs->info.clipdist_mask != next_hw_vs->info.clipdist_mask || - old_hw_vs->info.culldist_mask != next_hw_vs->info.culldist_mask || !old_hw_vs_variant || - !next_hw_vs_variant || + !old_hw_vs_variant || !next_hw_vs_variant || + old_hw_vs_variant->info.clipdist_mask != next_hw_vs_variant->info.clipdist_mask || + old_hw_vs_variant->info.culldist_mask != next_hw_vs_variant->info.culldist_mask || old_hw_vs_variant->pa_cl_vs_out_cntl != next_hw_vs_variant->pa_cl_vs_out_cntl)) si_mark_atom_dirty(sctx, &sctx->atoms.s.clip_regs); }