From 1942227e7339e940e0147f6837b518aafb1b5369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Tue, 4 Mar 2025 16:17:39 +0100 Subject: [PATCH] radv: Inline radv_graphics_shaders_link_varyings_{first/second}. The first step of reorganizing this code. No Fossil DB changes. Reviewed-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_pipeline_graphics.c | 171 ++++++++++-------------- 1 file changed, 70 insertions(+), 101 deletions(-) diff --git a/src/amd/vulkan/radv_pipeline_graphics.c b/src/amd/vulkan/radv_pipeline_graphics.c index bd8d03f9ed5..9bbd77b9933 100644 --- a/src/amd/vulkan/radv_pipeline_graphics.c +++ b/src/amd/vulkan/radv_pipeline_graphics.c @@ -1458,103 +1458,6 @@ radv_graphics_shaders_link(const struct radv_device *device, const struct radv_g } } -/** - * Fist pass of varying optimization. - * This function is called for each shader pair from first to last. - * - * 1. Run some NIR passes in preparation. - * 2. Optimize varyings. - * 3. If either shader changed, run algebraic optimizations. - */ -static void -radv_graphics_shaders_link_varyings_first(struct radv_shader_stage *producer_stage, - struct radv_shader_stage *consumer_stage) -{ - nir_shader *producer = producer_stage->nir; - nir_shader *consumer = consumer_stage->nir; - - /* It is expected by nir_opt_varyings that no undefined stores are present in the shader. */ - NIR_PASS(_, producer, nir_opt_undef); - - /* Update load/store alignments because inter-stage code motion may move instructions used to deduce this info. */ - NIR_PASS(_, consumer, nir_opt_load_store_update_alignments); - - /* Scalarize all I/O, because nir_opt_varyings and nir_opt_vectorize_io expect all I/O to be scalarized. */ - NIR_PASS(_, producer, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL); - NIR_PASS(_, consumer, nir_lower_io_to_scalar, nir_var_shader_in, NULL, NULL); - - /* Eliminate useless vec->mov copies resulting from scalarization. */ - NIR_PASS(_, producer, nir_copy_prop); - - const nir_opt_varyings_progress p = nir_opt_varyings(producer, consumer, true, 0, 0); - - /* Run algebraic optimizations on shaders that changed. */ - if (p & nir_progress_producer) { - radv_optimize_nir_algebraic(producer, false, false); - NIR_PASS(_, producer, nir_opt_undef); - } - if (p & nir_progress_consumer) { - radv_optimize_nir_algebraic(consumer, false, false); - NIR_PASS(_, consumer, nir_opt_undef); - } -} - -/** - * Second pass of varying optimization. - * This function is called for each shader pair from last to fist, - * after the first pass had already been called for each pair. - * Done because the previous pass might have enabled additional - * opportunities for optimization. - * - * 1. Optimize varyings again. - * 2. If either shader changed, run algebraic optimizations. - * 3. Run some NIR passes to clean up the shaders. - */ -static void -radv_graphics_shaders_link_varyings_second(struct radv_shader_stage *producer_stage, - struct radv_shader_stage *consumer_stage) -{ - nir_shader *producer = producer_stage->nir; - nir_shader *consumer = consumer_stage->nir; - - const nir_opt_varyings_progress p = nir_opt_varyings(producer, consumer, true, 0, 0); - - /* Run algebraic optimizations on shaders that changed. */ - if (p & nir_progress_producer) { - radv_optimize_nir_algebraic(producer, true, false); - NIR_PASS(_, producer, nir_opt_undef); - } - if (p & nir_progress_consumer) { - radv_optimize_nir_algebraic(consumer, true, false); - NIR_PASS(_, consumer, nir_opt_undef); - } - - /* Re-vectorize I/O for stages that output to memory (LDS or VRAM). - * Don't vectorize FS inputs, doing so just regresses shader stats without any benefit. - * There is also no benefit from re-vectorizing the outputs of the last pre-rasterization - * stage here, because ac_nir_lower_ngg/legacy already takes care of that. - */ - if (consumer->info.stage != MESA_SHADER_FRAGMENT) { - NIR_PASS(_, producer, nir_opt_vectorize_io, nir_var_shader_out); - NIR_PASS(_, consumer, nir_opt_vectorize_io, nir_var_shader_in); - } - - /* Gather shader info; at least the I/O info likely changed - * and changes to only the I/O info are not reflected in nir_opt_varyings_progress. - */ - nir_shader_gather_info(producer, nir_shader_get_entrypoint(producer)); - nir_shader_gather_info(consumer, nir_shader_get_entrypoint(consumer)); - - /* Recompute intrinsic bases of PS inputs in order to remove gaps. */ - if (consumer->info.stage == MESA_SHADER_FRAGMENT) - radv_recompute_fs_input_bases(consumer); - - /* Recreate XFB info from intrinsics (nir_opt_varyings may have changed it). */ - if (producer->xfb_info) { - nir_gather_xfb_info_from_intrinsics(producer); - } -} - static void radv_graphics_shaders_fill_linked_vs_io_info(struct radv_shader_stage *vs_stage, struct radv_shader_stage *consumer_stage) @@ -1663,8 +1566,35 @@ radv_graphics_shaders_link_varyings(struct radv_shader_stage *stages) continue; if (prev != MESA_SHADER_NONE) { - if (!stages[prev].key.optimisations_disabled && !stages[s].key.optimisations_disabled) - radv_graphics_shaders_link_varyings_first(&stages[prev], &stages[s]); + if (!stages[prev].key.optimisations_disabled && !stages[s].key.optimisations_disabled) { + nir_shader *producer = stages[prev].nir; + nir_shader *consumer = stages[s].nir; + + /* It is expected by nir_opt_varyings that no undefined stores are present in the shader. */ + NIR_PASS(_, producer, nir_opt_undef); + + /* Update load/store alignments because inter-stage code motion may move instructions used to deduce this info. */ + NIR_PASS(_, consumer, nir_opt_load_store_update_alignments); + + /* Scalarize all I/O, because nir_opt_varyings and nir_opt_vectorize_io expect all I/O to be scalarized. */ + NIR_PASS(_, producer, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL); + NIR_PASS(_, consumer, nir_lower_io_to_scalar, nir_var_shader_in, NULL, NULL); + + /* Eliminate useless vec->mov copies resulting from scalarization. */ + NIR_PASS(_, producer, nir_copy_prop); + + const nir_opt_varyings_progress p = nir_opt_varyings(producer, consumer, true, 0, 0); + + /* Run algebraic optimizations on shaders that changed. */ + if (p & nir_progress_producer) { + radv_optimize_nir_algebraic(producer, false, false); + NIR_PASS(_, producer, nir_opt_undef); + } + if (p & nir_progress_consumer) { + radv_optimize_nir_algebraic(consumer, false, false); + NIR_PASS(_, consumer, nir_opt_undef); + } + } } prev = s; @@ -1678,8 +1608,47 @@ radv_graphics_shaders_link_varyings(struct radv_shader_stage *stages) continue; if (next != MESA_SHADER_NONE) { - if (!stages[s].key.optimisations_disabled && !stages[next].key.optimisations_disabled) - radv_graphics_shaders_link_varyings_second(&stages[s], &stages[next]); + if (!stages[s].key.optimisations_disabled && !stages[next].key.optimisations_disabled) { + nir_shader *producer = stages[s].nir; + nir_shader *consumer = stages[next].nir; + + const nir_opt_varyings_progress p = nir_opt_varyings(producer, consumer, true, 0, 0); + + /* Run algebraic optimizations on shaders that changed. */ + if (p & nir_progress_producer) { + radv_optimize_nir_algebraic(producer, true, false); + NIR_PASS(_, producer, nir_opt_undef); + } + if (p & nir_progress_consumer) { + radv_optimize_nir_algebraic(consumer, true, false); + NIR_PASS(_, consumer, nir_opt_undef); + } + + /* Re-vectorize I/O for stages that output to memory (LDS or VRAM). + * Don't vectorize FS inputs, doing so just regresses shader stats without any benefit. + * There is also no benefit from re-vectorizing the outputs of the last pre-rasterization + * stage here, because ac_nir_lower_ngg/legacy already takes care of that. + */ + if (consumer->info.stage != MESA_SHADER_FRAGMENT) { + NIR_PASS(_, producer, nir_opt_vectorize_io, nir_var_shader_out); + NIR_PASS(_, consumer, nir_opt_vectorize_io, nir_var_shader_in); + } + + /* Gather shader info; at least the I/O info likely changed + * and changes to only the I/O info are not reflected in nir_opt_varyings_progress. + */ + nir_shader_gather_info(producer, nir_shader_get_entrypoint(producer)); + nir_shader_gather_info(consumer, nir_shader_get_entrypoint(consumer)); + + /* Recompute intrinsic bases of PS inputs in order to remove gaps. */ + if (consumer->info.stage == MESA_SHADER_FRAGMENT) + radv_recompute_fs_input_bases(consumer); + + /* Recreate XFB info from intrinsics (nir_opt_varyings may have changed it). */ + if (producer->xfb_info) { + nir_gather_xfb_info_from_intrinsics(producer); + } + } radv_graphics_shaders_fill_linked_io_info(&stages[s], &stages[next]); }