radeonsi: add si_shader_variant_info::clip/culldist_mask

so that it can be different between shader variants

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Acked-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35529>
This commit is contained in:
Marek Olšák
2025-05-26 04:09:29 -04:00
committed by Marge Bot
parent 391c40f9fc
commit e73f70e135
7 changed files with 47 additions and 52 deletions
+14 -25
View File
@@ -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;
@@ -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++) {
@@ -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;
@@ -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);
}
}
}
+6 -8
View File
@@ -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 &&
@@ -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. */
@@ -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);
}