diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build index 2ff369a7232..323de5a6900 100644 --- a/src/amd/vulkan/meson.build +++ b/src/amd/vulkan/meson.build @@ -79,6 +79,7 @@ libradv_files = files( 'nir/radv_nir_lower_view_index.c', 'nir/radv_nir_lower_viewport_to_zero.c', 'nir/radv_nir_lower_vs_inputs.c', + 'nir/radv_nir_opt_fs_builtins.c', 'nir/radv_nir_opt_tid_function.c', 'nir/radv_nir_remap_color_attachment.c', 'nir/radv_nir_rt_common.c', diff --git a/src/amd/vulkan/nir/radv_nir.h b/src/amd/vulkan/nir/radv_nir.h index aa5d8ce21b8..462a1e761c0 100644 --- a/src/amd/vulkan/nir/radv_nir.h +++ b/src/amd/vulkan/nir/radv_nir.h @@ -90,6 +90,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); + #ifdef __cplusplus } #endif diff --git a/src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c b/src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c new file mode 100644 index 00000000000..5b08e17449f --- /dev/null +++ b/src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c @@ -0,0 +1,43 @@ +/* + * Copyright © 2025 Valve Corporation + * + * SPDX-License-Identifier: MIT + */ + +#include "nir/nir.h" +#include "nir/nir_builder.h" +#include "radv_nir.h" +#include "radv_pipeline_graphics.h" + +static bool +pass(nir_builder *b, nir_intrinsic_instr *intr, void *data) +{ + const struct radv_graphics_state_key *gfx_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); + } + } else if (intr->intrinsic == nir_intrinsic_load_sample_id) { + if (!gfx_state->dynamic_rasterization_samples && gfx_state->ms.rasterization_samples == 0) { + replacement = nir_imm_intN_t(b, 0, intr->def.bit_size); + } + } + + if (!replacement) + return false; + + nir_def_replace(&intr->def, replacement); + return true; +} + +bool +radv_nir_opt_fs_builtins(nir_shader *shader, const struct radv_graphics_state_key *gfx_state) +{ + return nir_shader_intrinsics_pass(shader, pass, nir_metadata_control_flow, (void *)gfx_state); +} \ No newline at end of file diff --git a/src/amd/vulkan/radv_pipeline_graphics.c b/src/amd/vulkan/radv_pipeline_graphics.c index 8d5a972d4e5..0953736f531 100644 --- a/src/amd/vulkan/radv_pipeline_graphics.c +++ b/src/amd/vulkan/radv_pipeline_graphics.c @@ -1914,8 +1914,12 @@ radv_generate_graphics_state_key(const struct radv_device *device, const struct key.unknown_rast_prim = true; } - if (pdev->info.gfx_level >= GFX10 && state->rs) { - key.rs.provoking_vtx_last = state->rs->provoking_vertex == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; + if (state->rs) { + if (pdev->info.gfx_level >= GFX10) + key.rs.provoking_vtx_last = state->rs->provoking_vertex == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; + + if (!BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_RS_CULL_MODE)) + key.rs.cull_mode = state->rs->cull_mode; } key.ps.force_vrs_enabled = device->force_vrs_enabled && !radv_is_static_vrs_enabled(state); @@ -2708,6 +2712,8 @@ radv_graphics_shaders_compile(struct radv_device *device, struct vk_pipeline_cac if ((gfx_state->lib_flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) && !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); } if (stages[MESA_SHADER_VERTEX].nir && !gfx_state->vs.has_prolog) diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index 205f3c8cf15..ea855388840 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -146,6 +146,7 @@ struct radv_graphics_state_key { struct { uint32_t provoking_vtx_last : 1; + uint32_t cull_mode : 2; } rs; struct {