From 044e7f601754c079734fb9157da33e30ddae2e4c Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 19 Dec 2025 18:17:26 +0100 Subject: [PATCH] radv/nir: fix front_face opts for points/lines and unknown prim Fixes new VKCTS coverage dEQP-VK.glsl.builtin_var.frontfacing.*. Fixes: af375c67560 ("radv: Optimize fs builtins using static gfx state") Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/nir/radv_nir.h | 3 +- src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c | 52 ++++++++++++++----- src/amd/vulkan/radv_pipeline_graphics.c | 2 +- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/amd/vulkan/nir/radv_nir.h b/src/amd/vulkan/nir/radv_nir.h index d7a23ec5188..20248781b47 100644 --- a/src/amd/vulkan/nir/radv_nir.h +++ b/src/amd/vulkan/nir/radv_nir.h @@ -97,7 +97,8 @@ typedef struct radv_nir_opt_tid_function_options { bool radv_nir_opt_tid_function(nir_shader *shader, const radv_nir_opt_tid_function_options *options); -bool radv_nir_opt_fs_builtins(nir_shader *shader, const struct radv_graphics_state_key *gfx_state); +bool radv_nir_opt_fs_builtins(nir_shader *shader, const struct radv_graphics_state_key *gfx_state, + unsigned vgt_outprim_type); bool radv_nir_lower_immediate_samplers(nir_shader *shader, struct radv_device *device, const struct radv_shader_stage *stage); diff --git a/src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c b/src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c index 4974425b0cc..94931e4967e 100644 --- a/src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c +++ b/src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c @@ -9,28 +9,47 @@ #include "radv_nir.h" #include "radv_pipeline_graphics.h" +typedef struct { + const struct radv_graphics_state_key *gfx; + unsigned vgt_outprim_type; +} opt_fs_builtins_state; + static bool pass(nir_builder *b, nir_intrinsic_instr *intr, void *data) { - const struct radv_graphics_state_key *gfx_state = data; + opt_fs_builtins_state *state = data; b->cursor = nir_before_instr(&intr->instr); nir_def *replacement = NULL; - if (intr->intrinsic == nir_intrinsic_load_front_face) { - if (gfx_state->rs.cull_mode == VK_CULL_MODE_FRONT_BIT) { - replacement = nir_imm_false(b); - } else if (gfx_state->rs.cull_mode == VK_CULL_MODE_BACK_BIT) { - replacement = nir_imm_true(b); + if (intr->intrinsic == nir_intrinsic_load_front_face || intr->intrinsic == nir_intrinsic_load_front_face_fsign) { + int force_front_face = 0; + + switch (state->vgt_outprim_type) { + case V_028A6C_POINTLIST: + case V_028A6C_LINESTRIP: + force_front_face = 1; + break; + case V_028A6C_TRISTRIP: + if (state->gfx->rs.cull_mode == VK_CULL_MODE_FRONT_BIT) { + force_front_face = -1; + } else if (state->gfx->rs.cull_mode == VK_CULL_MODE_BACK_BIT) { + force_front_face = 1; + } + break; + default: + break; } - } else if (intr->intrinsic == nir_intrinsic_load_front_face_fsign) { - if (gfx_state->rs.cull_mode == VK_CULL_MODE_FRONT_BIT) { - replacement = nir_imm_float(b, -1.0); - } else if (gfx_state->rs.cull_mode == VK_CULL_MODE_BACK_BIT) { - replacement = nir_imm_float(b, 1.0); + + if (force_front_face) { + if (intr->intrinsic == nir_intrinsic_load_front_face) { + replacement = nir_imm_bool(b, force_front_face == 1); + } else { + replacement = nir_imm_float(b, force_front_face == 1 ? 1.0 : -1.0); + } } } else if (intr->intrinsic == nir_intrinsic_load_sample_id) { - if (!gfx_state->dynamic_rasterization_samples && gfx_state->ms.rasterization_samples == 0) { + if (!state->gfx->dynamic_rasterization_samples && state->gfx->ms.rasterization_samples == 0) { replacement = nir_imm_intN_t(b, 0, intr->def.bit_size); } } @@ -43,7 +62,12 @@ pass(nir_builder *b, nir_intrinsic_instr *intr, void *data) } bool -radv_nir_opt_fs_builtins(nir_shader *shader, const struct radv_graphics_state_key *gfx_state) +radv_nir_opt_fs_builtins(nir_shader *shader, const struct radv_graphics_state_key *gfx_state, unsigned vgt_outprim_type) { - return nir_shader_intrinsics_pass(shader, pass, nir_metadata_control_flow, (void *)gfx_state); + opt_fs_builtins_state state = { + .gfx = gfx_state, + .vgt_outprim_type = vgt_outprim_type, + }; + + return nir_shader_intrinsics_pass(shader, pass, nir_metadata_control_flow, &state); } diff --git a/src/amd/vulkan/radv_pipeline_graphics.c b/src/amd/vulkan/radv_pipeline_graphics.c index 5ec00bd66c9..1070cf25419 100644 --- a/src/amd/vulkan/radv_pipeline_graphics.c +++ b/src/amd/vulkan/radv_pipeline_graphics.c @@ -2883,7 +2883,7 @@ radv_graphics_shaders_compile(struct radv_device *device, struct vk_pipeline_cac !gfx_state->dynamic_rasterization_samples && gfx_state->ms.rasterization_samples == 0) NIR_PASS(_, stages[MESA_SHADER_FRAGMENT].nir, nir_opt_fragdepth); - NIR_PASS(_, stages[MESA_SHADER_FRAGMENT].nir, radv_nir_opt_fs_builtins, gfx_state); + NIR_PASS(_, stages[MESA_SHADER_FRAGMENT].nir, radv_nir_opt_fs_builtins, gfx_state, vgt_outprim_type); } if (stages[MESA_SHADER_VERTEX].nir && !gfx_state->vs.has_prolog)