From 6cd813810e9381de002f30ee72b89604e0228390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 26 May 2025 06:26:27 -0400 Subject: [PATCH] ac/nir: add an option write_pos_to_clip_vertex to clip against POS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This enables emulating clip planes without ClipVertex via clip distances (max 8) instead of the fixed-func hw (max 6 planes). Reviewed-by: Pierre-Eric Pelloux-Prayer Reviewed-by: Timur Kristóf Part-of: --- src/amd/common/nir/ac_nir.h | 3 +++ src/amd/common/nir/ac_nir_create_gs_copy_shader.c | 5 +++-- src/amd/common/nir/ac_nir_helpers.h | 1 + src/amd/common/nir/ac_nir_lower_legacy_vs.c | 5 +++-- src/amd/common/nir/ac_nir_lower_ngg.c | 1 + src/amd/common/nir/ac_nir_lower_ngg_gs.c | 1 + src/amd/common/nir/ac_nir_lower_ngg_mesh.c | 2 +- src/amd/common/nir/ac_nir_prerast_utils.c | 8 ++++++-- src/amd/vulkan/radv_pipeline.c | 6 +++--- src/amd/vulkan/radv_pipeline_graphics.c | 2 +- src/gallium/drivers/radeonsi/si_shader.c | 2 ++ 11 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/amd/common/nir/ac_nir.h b/src/amd/common/nir/ac_nir.h index 91445d4f24e..0c69c6026e9 100644 --- a/src/amd/common/nir/ac_nir.h +++ b/src/amd/common/nir/ac_nir.h @@ -166,6 +166,7 @@ typedef struct { unsigned max_workgroup_size; unsigned wave_size; uint8_t clip_cull_dist_mask; + bool write_pos_to_clipvertex; const uint8_t *vs_output_param_offset; /* GFX11+ */ bool has_param_exports; bool can_cull; @@ -256,6 +257,7 @@ nir_shader * ac_nir_create_gs_copy_shader(const nir_shader *gs_nir, enum amd_gfx_level gfx_level, uint32_t clip_cull_mask, + bool write_pos_to_clipvertex, const uint8_t *param_offsets, bool has_param_exports, bool disable_streamout, @@ -268,6 +270,7 @@ bool ac_nir_lower_legacy_vs(nir_shader *nir, enum amd_gfx_level gfx_level, uint32_t clip_cull_mask, + bool write_pos_to_clipvertex, const uint8_t *param_offsets, bool has_param_exports, bool export_primitive_id, diff --git a/src/amd/common/nir/ac_nir_create_gs_copy_shader.c b/src/amd/common/nir/ac_nir_create_gs_copy_shader.c index b7b9649c6b1..02947aff4b2 100644 --- a/src/amd/common/nir/ac_nir_create_gs_copy_shader.c +++ b/src/amd/common/nir/ac_nir_create_gs_copy_shader.c @@ -14,6 +14,7 @@ nir_shader * ac_nir_create_gs_copy_shader(const nir_shader *gs_nir, enum amd_gfx_level gfx_level, uint32_t clip_cull_mask, + bool write_pos_to_clipvertex, const uint8_t *param_offsets, bool has_param_exports, bool disable_streamout, @@ -118,8 +119,8 @@ ac_nir_create_gs_copy_shader(const nir_shader *gs_nir, if (kill_layer) export_outputs &= ~VARYING_BIT_LAYER; - ac_nir_export_position(&b, gfx_level, clip_cull_mask, !has_param_exports, - force_vrs, export_outputs, &out, NULL); + ac_nir_export_position(&b, gfx_level, clip_cull_mask, write_pos_to_clipvertex, + !has_param_exports, force_vrs, export_outputs, &out, NULL); if (has_param_exports) { ac_nir_export_parameters(&b, param_offsets, diff --git a/src/amd/common/nir/ac_nir_helpers.h b/src/amd/common/nir/ac_nir_helpers.h index 8dbb281b2c3..2665a0ab746 100644 --- a/src/amd/common/nir/ac_nir_helpers.h +++ b/src/amd/common/nir/ac_nir_helpers.h @@ -110,6 +110,7 @@ void ac_nir_export_position(nir_builder *b, enum amd_gfx_level gfx_level, uint32_t clip_cull_mask, + bool write_pos_to_clipvertex, bool no_param_export, bool force_vrs, uint64_t outputs_written, diff --git a/src/amd/common/nir/ac_nir_lower_legacy_vs.c b/src/amd/common/nir/ac_nir_lower_legacy_vs.c index 332cf4ff5b5..91b5be12049 100644 --- a/src/amd/common/nir/ac_nir_lower_legacy_vs.c +++ b/src/amd/common/nir/ac_nir_lower_legacy_vs.c @@ -36,6 +36,7 @@ bool ac_nir_lower_legacy_vs(nir_shader *nir, enum amd_gfx_level gfx_level, uint32_t clip_cull_mask, + bool write_pos_to_clipvertex, const uint8_t *param_offsets, bool has_param_exports, bool export_primitive_id, @@ -76,8 +77,8 @@ ac_nir_lower_legacy_vs(nir_shader *nir, if (kill_layer) export_outputs &= ~VARYING_BIT_LAYER; - ac_nir_export_position(&b, gfx_level, clip_cull_mask, !has_param_exports, - force_vrs, export_outputs, &out, NULL); + ac_nir_export_position(&b, gfx_level, clip_cull_mask, write_pos_to_clipvertex, + !has_param_exports, force_vrs, export_outputs, &out, NULL); if (has_param_exports) { ac_nir_export_parameters(&b, param_offsets, diff --git a/src/amd/common/nir/ac_nir_lower_ngg.c b/src/amd/common/nir/ac_nir_lower_ngg.c index 91993594c08..ebef309ef04 100644 --- a/src/amd/common/nir/ac_nir_lower_ngg.c +++ b/src/amd/common/nir/ac_nir_lower_ngg.c @@ -1787,6 +1787,7 @@ ac_nir_lower_ngg_nogs(nir_shader *shader, const ac_nir_lower_ngg_options *option ac_nir_export_position(b, options->hw_info->gfx_level, options->clip_cull_dist_mask, + options->write_pos_to_clipvertex, !options->has_param_exports, options->force_vrs, export_outputs, &state.out, NULL); diff --git a/src/amd/common/nir/ac_nir_lower_ngg_gs.c b/src/amd/common/nir/ac_nir_lower_ngg_gs.c index edc21a27251..29166dfdc34 100644 --- a/src/amd/common/nir/ac_nir_lower_ngg_gs.c +++ b/src/amd/common/nir/ac_nir_lower_ngg_gs.c @@ -499,6 +499,7 @@ ngg_gs_emit_output(nir_builder *b, nir_def *max_num_out_vtx, nir_def *max_num_ou ac_nir_export_position(b, s->options->hw_info->gfx_level, s->options->clip_cull_dist_mask, + s->options->write_pos_to_clipvertex, !s->options->has_param_exports, s->options->force_vrs, export_outputs, &s->out, NULL); 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 bb694c756f5..fe15f3f5563 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, + ac_nir_export_position(b, s->hw_info->gfx_level, s->clipdist_enable_mask, false, !s->has_param_exports, false, s->per_vertex_outputs | VARYING_BIT_POS, &s->out, row); } diff --git a/src/amd/common/nir/ac_nir_prerast_utils.c b/src/amd/common/nir/ac_nir_prerast_utils.c index 8dbc74d895f..7f912be4004 100644 --- a/src/amd/common/nir/ac_nir_prerast_utils.c +++ b/src/amd/common/nir/ac_nir_prerast_utils.c @@ -228,6 +228,7 @@ void ac_nir_export_position(nir_builder *b, enum amd_gfx_level gfx_level, uint32_t clip_cull_mask, + bool write_pos_to_clipvertex, bool no_param_export, bool force_vrs, uint64_t outputs_written, @@ -259,10 +260,13 @@ ac_nir_export_position(nir_builder *b, nir_def *clip_dist[8] = {0}; - if (outputs_written & VARYING_BIT_CLIP_VERTEX) { + if (outputs_written & VARYING_BIT_CLIP_VERTEX || write_pos_to_clipvertex) { + /* Only one condition can be set. */ + assert(!(outputs_written & VARYING_BIT_CLIP_VERTEX) || !write_pos_to_clipvertex); /* Convert CLIP_VERTEX to clip distances. */ assert(!(outputs_written & (VARYING_BIT_CLIP_DIST0 | VARYING_BIT_CLIP_DIST1))); - nir_def *vtx = get_export_output(b, out->outputs[VARYING_SLOT_CLIP_VERTEX]); + gl_varying_slot slot = write_pos_to_clipvertex ? VARYING_SLOT_POS : VARYING_SLOT_CLIP_VERTEX; + nir_def *vtx = get_export_output(b, out->outputs[slot]); u_foreach_bit(i, clip_cull_mask) { nir_def *ucp = nir_load_user_clip_plane(b, .ucp_id = i); diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 31ac14b7a74..ec75dc4308f 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -444,9 +444,9 @@ 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, - stage->info.outinfo.vs_output_param_offset, stage->info.outinfo.param_exports, - stage->info.outinfo.export_prim_id, false, false, false, stage->info.force_vrs_per_vertex); + stage->info.outinfo.clip_dist_mask | stage->info.outinfo.cull_dist_mask, false, + stage->info.outinfo.vs_output_param_offset, stage->info.outinfo.param_exports, + stage->info.outinfo.export_prim_id, false, false, false, stage->info.force_vrs_per_vertex); } else { ac_nir_gs_output_info gs_out_info = { diff --git a/src/amd/vulkan/radv_pipeline_graphics.c b/src/amd/vulkan/radv_pipeline_graphics.c index 3f3791e8138..64843863e81 100644 --- a/src/amd/vulkan/radv_pipeline_graphics.c +++ b/src/amd/vulkan/radv_pipeline_graphics.c @@ -2271,7 +2271,7 @@ radv_create_gs_copy_shader(struct radv_device *device, struct vk_pipeline_cache .varying_mask = gs_info->gs.output_usage_mask, }; nir_shader *nir = ac_nir_create_gs_copy_shader( - gs_stage->nir, pdev->info.gfx_level, gs_info->outinfo.clip_dist_mask | gs_info->outinfo.cull_dist_mask, + gs_stage->nir, pdev->info.gfx_level, gs_info->outinfo.clip_dist_mask | gs_info->outinfo.cull_dist_mask, false, gs_info->outinfo.vs_output_param_offset, gs_info->outinfo.param_exports, false, false, false, gs_info->force_vrs_per_vertex, &output_info); diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 70704c87b46..9d0b77b4808 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1601,6 +1601,7 @@ static void run_late_optimization_and_lowering_passes(struct si_nir_shader_ctx * NIR_PASS_V(nir, ac_nir_lower_legacy_vs, sel->screen->info.gfx_level, clip_cull_mask, + false, ctx->temp_info.vs_output_param_offset, shader->info.nr_param_exports, shader->key.ge.mono.u.vs_export_prim_id, @@ -1918,6 +1919,7 @@ si_nir_generate_gs_copy_shader(struct si_screen *sscreen, ac_nir_create_gs_copy_shader(gs_nir, sscreen->info.gfx_level, clip_cull_mask, + false, temp_info->vs_output_param_offset, shader->info.nr_param_exports, !gs_shader->info.num_streamout_vec4s,