From c4c9c780b131939fa10ede84e079a90fc090e17a Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 16 Dec 2020 14:31:32 -0800 Subject: [PATCH] spirv: Remove more dead variables SPIR-V modules can have multiple shaders (including of the same stage), but the global variables are all declared for the whole module. This can result in variables with same Binding but incompatible types, so those need to be removed before we use. Previously, a similar issue but with a narrower scope was fixed by 6775665e5ee ("spirv: Eliminate dead input/output variables after translation."). This patch depends on the previous patch that prevents variables used only in pointer initializers to be considered dead. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3686 Fixes: 3a266a18 ("nir/spirv: Add support for declaring variables") Reviewed-by: Jason Ekstrand Part-of: --- src/compiler/spirv/spirv_to_nir.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 266375a..264acbc 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -5842,19 +5842,23 @@ spirv_to_nir(const uint32_t *words, size_t word_count, /* structurize the CFG */ nir_lower_goto_ifs(b->shader); - /* When multiple shader stages exist in the same SPIR-V module, we - * generate input and output variables for every stage, in the same - * NIR program. These dead variables can be invalid NIR. For example, - * TCS outputs must be per-vertex arrays (or decorated 'patch'), while - * VS output variables wouldn't be. + /* A SPIR-V module can have multiple shaders stages and also multiple + * shaders of the same stage. Global variables are declared per-module, so + * they are all collected when parsing a single shader. These dead + * variables can result in invalid NIR, e.g. * - * To ensure we have valid NIR, we eliminate any dead inputs and outputs - * right away. In order to do so, we must lower any constant initializers - * on outputs so nir_remove_dead_variables sees that they're written to. + * - TCS outputs must be per-vertex arrays (or decorated 'patch'), while VS + * output variables wouldn't be; + * - Two vertex shaders have two different typed blocks associated to the + * same Binding. + * + * Before cleaning the dead variables, we must lower any constant + * initializers on outputs so nir_remove_dead_variables sees that they're + * written to. */ - nir_lower_variable_initializers(b->shader, nir_var_shader_out); - nir_remove_dead_variables(b->shader, - nir_var_shader_in | nir_var_shader_out, NULL); + nir_lower_variable_initializers(b->shader, nir_var_shader_out | + nir_var_system_value); + nir_remove_dead_variables(b->shader, ~nir_var_function_temp, NULL); /* We sometimes generate bogus derefs that, while never used, give the * validator a bit of heartburn. Run dead code to get rid of them. -- 2.7.4