From 44dd39d121f13333e91ce1986ba53c46323eae44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 9 Jun 2025 17:58:03 -0400 Subject: [PATCH] radv: pack clip and cull distance outputs for both legacy and NGG pipelines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Timur Kristóf Part-of: --- src/amd/common/nir/ac_nir_lower_ngg_mesh.c | 2 +- src/amd/vulkan/radv_pipeline.c | 3 ++- src/amd/vulkan/radv_shader.c | 21 +++++++++++++-------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/amd/common/nir/ac_nir_lower_ngg_mesh.c b/src/amd/common/nir/ac_nir_lower_ngg_mesh.c index 0ffec71d14e..992a099ac91 100644 --- a/src/amd/common/nir/ac_nir_lower_ngg_mesh.c +++ b/src/amd/common/nir/ac_nir_lower_ngg_mesh.c @@ -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); } diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 51b087fd360..b38d50ad6e3 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -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, diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index cfe09ca5aec..0d088bf8b68 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -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 =