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
6775665e5e ("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 <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8133>
This commit is contained in:
Caio Marcelo de Oliveira Filho 2020-12-16 14:31:32 -08:00 committed by Marge Bot
parent acce4ce04e
commit c4c9c780b1

View file

@ -5842,19 +5842,23 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
/* structurize the CFG */ /* structurize the CFG */
nir_lower_goto_ifs(b->shader); nir_lower_goto_ifs(b->shader);
/* When multiple shader stages exist in the same SPIR-V module, we /* A SPIR-V module can have multiple shaders stages and also multiple
* generate input and output variables for every stage, in the same * shaders of the same stage. Global variables are declared per-module, so
* NIR program. These dead variables can be invalid NIR. For example, * they are all collected when parsing a single shader. These dead
* TCS outputs must be per-vertex arrays (or decorated 'patch'), while * variables can result in invalid NIR, e.g.
* VS output variables wouldn't be.
* *
* To ensure we have valid NIR, we eliminate any dead inputs and outputs * - TCS outputs must be per-vertex arrays (or decorated 'patch'), while VS
* right away. In order to do so, we must lower any constant initializers * output variables wouldn't be;
* on outputs so nir_remove_dead_variables sees that they're written to. * - 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_lower_variable_initializers(b->shader, nir_var_shader_out |
nir_remove_dead_variables(b->shader, nir_var_system_value);
nir_var_shader_in | nir_var_shader_out, NULL); nir_remove_dead_variables(b->shader, ~nir_var_function_temp, NULL);
/* We sometimes generate bogus derefs that, while never used, give the /* We sometimes generate bogus derefs that, while never used, give the
* validator a bit of heartburn. Run dead code to get rid of them. * validator a bit of heartburn. Run dead code to get rid of them.