From 6775665e5eec7db3f291508a8b7ba2a792f62ec0 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 6 Feb 2019 16:45:25 -0800 Subject: [PATCH] spirv: Eliminate dead input/output variables after translation. spirv_to_nir can generate input/output variables which are illegal for the current shader stage, which would cause nir_validate_shader to balk. After my recent commit to start decorating arrays as compact, dEQP-VK.spirv_assembly.instruction.graphics.module.same_module started hitting validation errors due to outputs in a TCS (not intended for the TCS at all) not being per-vertex arrays. Thanks to Jason Ekstrand for suggesting this approach. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109573 Fixes: ef99f4c8d17 compiler: Mark clip/cull distance arrays as compact before lowering. Reviewed-by: Juan A. Suarez --- src/compiler/spirv/spirv_to_nir.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 5e8eb22..8c07542 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -4497,20 +4497,35 @@ spirv_to_nir(const uint32_t *words, size_t word_count, } } while (progress); + vtn_assert(b->entry_point->value_type == vtn_value_type_function); + nir_function *entry_point = b->entry_point->func->impl->function; + vtn_assert(entry_point); + + entry_point->is_entrypoint = true; + + /* 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. + * + * 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. + */ + nir_lower_constant_initializers(b->shader, nir_var_shader_out); + nir_remove_dead_variables(b->shader, + nir_var_shader_in | nir_var_shader_out); + /* We sometimes generate bogus derefs that, while never used, give the * validator a bit of heartburn. Run dead code to get rid of them. */ nir_opt_dce(b->shader); - vtn_assert(b->entry_point->value_type == vtn_value_type_function); - nir_function *entry_point = b->entry_point->func->impl->function; - vtn_assert(entry_point); - /* Unparent the shader from the vtn_builder before we delete the builder */ ralloc_steal(NULL, b->shader); ralloc_free(b); - entry_point->is_entrypoint = true; return entry_point; } -- 2.7.4