From 90bf9ed7596fce599398aad5dde6dc8b9dde957f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Wed, 29 Mar 2023 19:12:41 +0200 Subject: [PATCH] radv: Move radv_nir_export_multiview to new file. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also ran clang-format on the affected code. Signed-off-by: Timur Kristóf Reviewed-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/meson.build | 1 + src/amd/vulkan/nir/radv_nir.h | 2 + .../vulkan/nir/radv_nir_export_multiview.c | 109 ++++++++++++++++++ src/amd/vulkan/radv_pipeline.c | 88 +------------- 4 files changed, 115 insertions(+), 85 deletions(-) create mode 100644 src/amd/vulkan/nir/radv_nir_export_multiview.c diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build index a3870ad7007..b66b3f01222 100644 --- a/src/amd/vulkan/meson.build +++ b/src/amd/vulkan/meson.build @@ -72,6 +72,7 @@ libradv_files = files( 'meta/radv_meta_resolve_fs.c', 'nir/radv_nir.h', 'nir/radv_nir_apply_pipeline_layout.c', + 'nir/radv_nir_export_multiview.c', 'nir/radv_nir_lower_abi.c', 'nir/radv_nir_lower_fs_intrinsics.c', 'nir/radv_nir_lower_intrinsics_early.c', diff --git a/src/amd/vulkan/nir/radv_nir.h b/src/amd/vulkan/nir/radv_nir.h index 917b712cf47..ee0939ecca6 100644 --- a/src/amd/vulkan/nir/radv_nir.h +++ b/src/amd/vulkan/nir/radv_nir.h @@ -68,6 +68,8 @@ bool radv_nir_lower_view_index(nir_shader *nir, bool per_primitive); bool radv_nir_lower_viewport_to_zero(nir_shader *nir); +bool radv_nir_export_multiview(nir_shader *nir); + #ifdef __cplusplus } #endif diff --git a/src/amd/vulkan/nir/radv_nir_export_multiview.c b/src/amd/vulkan/nir/radv_nir_export_multiview.c new file mode 100644 index 00000000000..ab3dd01efc3 --- /dev/null +++ b/src/amd/vulkan/nir/radv_nir_export_multiview.c @@ -0,0 +1,109 @@ +/* + * Copyright © 2016 Red Hat. + * Copyright © 2016 Bas Nieuwenhuizen + * Copyright © 2023 Valve Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "nir.h" +#include "nir_builder.h" +#include "radv_nir.h" + +static nir_variable * +find_layer_out_var(nir_shader *nir) +{ + nir_variable *var = nir_find_variable_with_location(nir, nir_var_shader_out, VARYING_SLOT_LAYER); + if (var != NULL) + return var; + + var = nir_variable_create(nir, nir_var_shader_out, glsl_int_type(), "layer id"); + var->data.location = VARYING_SLOT_LAYER; + var->data.interpolation = INTERP_MODE_NONE; + + return var; +} + +bool +radv_nir_export_multiview(nir_shader *nir) +{ + nir_function_impl *impl = nir_shader_get_entrypoint(nir); + bool progress = false; + + nir_builder b; + nir_builder_init(&b, impl); + + /* This pass is not suitable for mesh shaders, because it can't know the mapping between API mesh + * shader invocations and output primitives. Needs to be handled in ac_nir_lower_ngg. + */ + assert(nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_TESS_EVAL || + nir->info.stage == MESA_SHADER_GEOMETRY); + + /* Iterate in reverse order since there should be only one deref store to POS after + * lower_io_to_temporaries for vertex shaders and inject the layer there. For geometry shaders, + * the layer is injected right before every emit_vertex_with_counter. + */ + nir_variable *layer = NULL; + nir_foreach_block_reverse (block, impl) { + nir_foreach_instr_reverse (instr, block) { + if (instr->type != nir_instr_type_intrinsic) + continue; + + if (nir->info.stage == MESA_SHADER_GEOMETRY) { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + if (intr->intrinsic != nir_intrinsic_emit_vertex_with_counter) + continue; + + b.cursor = nir_before_instr(instr); + } else { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + if (intr->intrinsic != nir_intrinsic_store_deref) + continue; + + nir_variable *var = nir_intrinsic_get_var(intr, 0); + if (var->data.mode != nir_var_shader_out || var->data.location != VARYING_SLOT_POS) + continue; + + b.cursor = nir_after_instr(instr); + } + + if (!layer) + layer = find_layer_out_var(nir); + + nir_store_var(&b, layer, nir_load_view_index(&b), 1); + + /* Update outputs_written to reflect that the pass added a new output. */ + nir->info.outputs_written |= BITFIELD64_BIT(VARYING_SLOT_LAYER); + + progress = true; + if (nir->info.stage == MESA_SHADER_VERTEX) + break; + } + if (nir->info.stage == MESA_SHADER_VERTEX && progress) + break; + } + + if (progress) + nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance); + else + nir_metadata_preserve(impl, nir_metadata_all); + + return progress; +} diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 5a5e6993ffd..9d972221ac5 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -1455,20 +1455,6 @@ get_vs_output_info(const struct radv_graphics_pipeline *pipeline) return &radv_get_last_vgt_shader(pipeline)->info.outinfo; } -static nir_variable * -find_layer_out_var(nir_shader *nir) -{ - nir_variable *var = nir_find_variable_with_location(nir, nir_var_shader_out, VARYING_SLOT_LAYER); - if (var != NULL) - return var; - - var = nir_variable_create(nir, nir_var_shader_out, glsl_int_type(), "layer id"); - var->data.location = VARYING_SLOT_LAYER; - var->data.interpolation = INTERP_MODE_NONE; - - return var; -} - static bool radv_should_export_multiview(const struct radv_pipeline_stage *producer, const struct radv_pipeline_stage *consumer, @@ -1482,74 +1468,6 @@ radv_should_export_multiview(const struct radv_pipeline_stage *producer, !(producer->nir->info.outputs_written & VARYING_BIT_LAYER); } -static bool -radv_export_multiview(nir_shader *nir) -{ - nir_function_impl *impl = nir_shader_get_entrypoint(nir); - bool progress = false; - - nir_builder b; - nir_builder_init(&b, impl); - - /* This pass is not suitable for mesh shaders, because it can't know the mapping between API mesh - * shader invocations and output primitives. Needs to be handled in ac_nir_lower_ngg. - */ - assert(nir->info.stage == MESA_SHADER_VERTEX || - nir->info.stage == MESA_SHADER_TESS_EVAL || - nir->info.stage == MESA_SHADER_GEOMETRY); - - /* Iterate in reverse order since there should be only one deref store to POS after - * lower_io_to_temporaries for vertex shaders and inject the layer there. For geometry shaders, - * the layer is injected right before every emit_vertex_with_counter. - */ - nir_variable *layer = NULL; - nir_foreach_block_reverse(block, impl) { - nir_foreach_instr_reverse(instr, block) { - if (instr->type != nir_instr_type_intrinsic) - continue; - - if (nir->info.stage == MESA_SHADER_GEOMETRY) { - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - if (intr->intrinsic != nir_intrinsic_emit_vertex_with_counter) - continue; - - b.cursor = nir_before_instr(instr); - } else { - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - if (intr->intrinsic != nir_intrinsic_store_deref) - continue; - - nir_variable *var = nir_intrinsic_get_var(intr, 0); - if (var->data.mode != nir_var_shader_out || var->data.location != VARYING_SLOT_POS) - continue; - - b.cursor = nir_after_instr(instr); - } - - if (!layer) - layer = find_layer_out_var(nir); - - nir_store_var(&b, layer, nir_load_view_index(&b), 1); - - /* Update outputs_written to reflect that the pass added a new output. */ - nir->info.outputs_written |= BITFIELD64_BIT(VARYING_SLOT_LAYER); - - progress = true; - if (nir->info.stage == MESA_SHADER_VERTEX) - break; - } - if (nir->info.stage == MESA_SHADER_VERTEX && progress) - break; - } - - if (progress) - nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance); - else - nir_metadata_preserve(impl, nir_metadata_all); - - return progress; -} - static void radv_remove_point_size(const struct radv_pipeline_key *pipeline_key, nir_shader *producer, nir_shader *consumer) @@ -1836,7 +1754,7 @@ radv_pipeline_link_vs(const struct radv_device *device, struct radv_pipeline_sta assert(vs_stage->nir->info.stage == MESA_SHADER_VERTEX); if (radv_should_export_multiview(vs_stage, next_stage, pipeline_key)) { - NIR_PASS(_, vs_stage->nir, radv_export_multiview); + NIR_PASS(_, vs_stage->nir, radv_nir_export_multiview); } if (next_stage) { @@ -1902,7 +1820,7 @@ radv_pipeline_link_tes(const struct radv_device *device, struct radv_pipeline_st assert(tes_stage->nir->info.stage == MESA_SHADER_TESS_EVAL); if (radv_should_export_multiview(tes_stage, next_stage, pipeline_key)) { - NIR_PASS(_, tes_stage->nir, radv_export_multiview); + NIR_PASS(_, tes_stage->nir, radv_nir_export_multiview); } if (next_stage) { @@ -1933,7 +1851,7 @@ radv_pipeline_link_gs(const struct radv_device *device, struct radv_pipeline_sta assert(gs_stage->nir->info.stage == MESA_SHADER_GEOMETRY); if (radv_should_export_multiview(gs_stage, fs_stage, pipeline_key)) { - NIR_PASS(_, gs_stage->nir, radv_export_multiview); + NIR_PASS(_, gs_stage->nir, radv_nir_export_multiview); } if (fs_stage) {