radv: pack clip and cull distance outputs for both legacy and NGG pipelines

This increases primitive throughput when packing reduces the number
of pos exports due to holes in clip and cull distance arrays that could be
punched out by nir_opt_clip_cull_const. This applies to all chips.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35473>
This commit is contained in:
Marek Olšák
2025-06-09 17:58:03 -04:00
committed by Marge Bot
parent 2751d488ce
commit 44dd39d121
3 changed files with 16 additions and 10 deletions
+1 -1
View File
@@ -887,7 +887,7 @@ emit_ms_vertex(nir_builder *b, nir_def *index, nir_def *row, bool exports, bool
ms_emit_arrayed_outputs(b, index, per_vertex_outputs, s);
if (exports) {
ac_nir_export_position(b, s->hw_info->gfx_level, s->clipdist_enable_mask, false, false, false,
ac_nir_export_position(b, s->hw_info->gfx_level, s->clipdist_enable_mask, false, false, true,
!s->has_param_exports, false,
s->per_vertex_outputs | VARYING_BIT_POS, &s->out, row);
}
+2 -1
View File
@@ -489,7 +489,7 @@ radv_postprocess_nir(struct radv_device *device, const struct radv_graphics_stat
} else if (is_last_vgt_stage) {
if (stage->stage != MESA_SHADER_GEOMETRY) {
NIR_PASS(_, stage->nir, ac_nir_lower_legacy_vs, gfx_level,
stage->info.outinfo.clip_dist_mask | stage->info.outinfo.cull_dist_mask, false, false,
stage->info.outinfo.clip_dist_mask | stage->info.outinfo.cull_dist_mask, false, true,
stage->info.outinfo.vs_output_param_offset, stage->info.outinfo.param_exports,
stage->info.outinfo.export_prim_id, false, stage->info.force_vrs_per_vertex);
@@ -499,6 +499,7 @@ radv_postprocess_nir(struct radv_device *device, const struct radv_graphics_stat
.has_pipeline_stats_query = false,
.gfx_level = pdev->info.gfx_level,
.export_clipdist_mask = stage->info.outinfo.clip_dist_mask | stage->info.outinfo.cull_dist_mask,
.pack_clip_cull_distances = true,
.param_offsets = stage->info.outinfo.vs_output_param_offset,
.has_param_exports = stage->info.outinfo.param_exports,
.force_vrs = stage->info.force_vrs_per_vertex,
+13 -8
View File
@@ -792,6 +792,7 @@ radv_lower_ngg(struct radv_device *device, struct radv_shader_stage *ngg_stage,
options.export_clipdist_mask = info->outinfo.clip_dist_mask | info->outinfo.cull_dist_mask;
options.cull_clipdist_mask = options.export_clipdist_mask;
options.dont_export_cull_distances = info->has_ngg_culling;
options.pack_clip_cull_distances = true;
options.vs_output_param_offset = info->outinfo.vs_output_param_offset;
options.has_param_exports = info->outinfo.param_exports || info->outinfo.prim_param_exports;
options.can_cull = info->has_ngg_culling;
@@ -1428,7 +1429,7 @@ radv_open_rtld_binary(struct radv_device *device, const struct radv_shader_binar
#endif
static unsigned
radv_get_num_pos_exports(struct radv_shader_info *info)
radv_get_num_pos_exports(struct radv_shader_info *info, unsigned *clip_dist_mask, unsigned *cull_dist_mask)
{
unsigned num = 1;
@@ -1436,13 +1437,19 @@ radv_get_num_pos_exports(struct radv_shader_info *info)
info->outinfo.writes_primitive_shading_rate)
num++;
unsigned clip_cull_mask = info->outinfo.clip_dist_mask | (info->has_ngg_culling ? 0 : info->outinfo.cull_dist_mask);
/* Clip and cull distances are packed by ac_nir_export_position. */
unsigned num_clip_dist_comps = util_bitcount(info->outinfo.clip_dist_mask);
/* Cull distances are not exported if the shader culls against them. */
unsigned num_cull_dist_comps = info->has_ngg_culling ? 0 : util_bitcount(info->outinfo.cull_dist_mask);
unsigned clip_cull_mask = BITFIELD_MASK(num_clip_dist_comps + num_cull_dist_comps);
if (clip_cull_mask & 0x0f)
num++;
if (clip_cull_mask & 0xf0)
num++;
*clip_dist_mask = BITFIELD_MASK(num_clip_dist_comps);
*cull_dist_mask = BITFIELD_RANGE(num_clip_dist_comps, num_cull_dist_comps);
return num;
}
@@ -1451,7 +1458,8 @@ radv_precompute_registers_hw_vs(struct radv_device *device, struct radv_shader_b
{
const struct radv_physical_device *pdev = radv_device_physical(device);
struct radv_shader_info *info = &binary->info;
unsigned num_pos_exports = radv_get_num_pos_exports(info);
unsigned clip_dist_mask, cull_dist_mask;
unsigned num_pos_exports = radv_get_num_pos_exports(info, &clip_dist_mask, &cull_dist_mask);
/* VS is required to export at least one param. */
const uint32_t nparams = MAX2(info->outinfo.param_exports, 1);
@@ -1468,8 +1476,6 @@ radv_precompute_registers_hw_vs(struct radv_device *device, struct radv_shader_b
const bool misc_vec_ena = info->outinfo.writes_pointsize || info->outinfo.writes_layer ||
info->outinfo.writes_viewport_index || info->outinfo.writes_primitive_shading_rate;
const unsigned clip_dist_mask = info->outinfo.clip_dist_mask;
const unsigned cull_dist_mask = info->outinfo.cull_dist_mask;
const unsigned total_mask = clip_dist_mask | cull_dist_mask;
info->regs.pa_cl_vs_out_cntl =
@@ -1624,7 +1630,8 @@ radv_precompute_registers_hw_ngg(struct radv_device *device, const struct ac_sha
if (info->outinfo.writes_layer_per_primitive || info->outinfo.writes_viewport_index_per_primitive ||
info->outinfo.writes_primitive_shading_rate_per_primitive)
idx_format = V_028708_SPI_SHADER_2COMP;
unsigned num_pos_exports = radv_get_num_pos_exports(info);
unsigned clip_dist_mask, cull_dist_mask;
unsigned num_pos_exports = radv_get_num_pos_exports(info, &clip_dist_mask, &cull_dist_mask);
info->regs.ngg.spi_shader_idx_format = S_028708_IDX0_EXPORT_FORMAT(idx_format);
@@ -1636,8 +1643,6 @@ radv_precompute_registers_hw_ngg(struct radv_device *device, const struct ac_sha
const bool misc_vec_ena = info->outinfo.writes_pointsize || info->outinfo.writes_layer ||
info->outinfo.writes_viewport_index || info->outinfo.writes_primitive_shading_rate;
const unsigned clip_dist_mask = info->outinfo.clip_dist_mask;
const unsigned cull_dist_mask = info->has_ngg_culling ? 0 : info->outinfo.cull_dist_mask;
const unsigned total_mask = clip_dist_mask | cull_dist_mask;
info->regs.pa_cl_vs_out_cntl =