From af375c675601f2ab6f3871145312355682a2b2d0 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Sat, 28 Dec 2024 14:05:07 +0100 Subject: [PATCH] radv: Optimize fs builtins using static gfx state The values of some builtins are known at compile time when the application creates pipelines with static state. Stats for graphics pipelines: Totals from 568 (0.71% of 80536) affected shaders: MaxWaves: 12364 -> 12502 (+1.12%); split: +1.26%, -0.15% Instrs: 515696 -> 501182 (-2.81%); split: -2.85%, +0.04% CodeSize: 2815736 -> 2741464 (-2.64%); split: -2.69%, +0.05% VGPRs: 29528 -> 29160 (-1.25%); split: -1.71%, +0.46% SpillSGPRs: 212 -> 215 (+1.42%) Latency: 5515421 -> 5409125 (-1.93%); split: -2.05%, +0.13% InvThroughput: 1293512 -> 1277913 (-1.21%); split: -1.27%, +0.06% VClause: 10570 -> 10295 (-2.60%); split: -2.74%, +0.14% SClause: 19040 -> 18531 (-2.67%); split: -2.83%, +0.16% Copies: 37189 -> 35431 (-4.73%); split: -5.31%, +0.58% Branches: 11391 -> 11070 (-2.82%); split: -2.92%, +0.11% PreSGPRs: 27848 -> 27313 (-1.92%); split: -1.95%, +0.03% PreVGPRs: 24847 -> 24106 (-2.98%); split: -3.00%, +0.02% VALU: 359356 -> 348779 (-2.94%); split: -2.97%, +0.03% SALU: 59135 -> 57448 (-2.85%); split: -3.11%, +0.26% VMEM: 14674 -> 14313 (-2.46%) SMEM: 30901 -> 30342 (-1.81%); split: -1.84%, +0.03% Reviewed-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/meson.build | 1 + src/amd/vulkan/nir/radv_nir.h | 2 + src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c | 43 +++++++++++++++++++ src/amd/vulkan/radv_pipeline_graphics.c | 10 ++++- src/amd/vulkan/radv_shader.h | 1 + 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/amd/vulkan/nir/radv_nir_opt_fs_builtins.c 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 {