From 679421628bf89067b4cbfa85530f196ca2835717 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 30 Apr 2020 15:06:08 +0200 Subject: [PATCH] glsl: add a is_implicit_initializer flag MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Shared globals and glsl_zero_init can cause linker errors if the variable is only initialized in 1 place. This commit adds a flag to variables that have been implicitely initialized to be able in this situation to keep the explicit initialization value. Without this change the global-single-initializer-2-shaders piglit test fails when using glsl_zero_init. Reviewed-by: Marek Olšák Part-of: --- src/compiler/glsl/ast_to_hir.cpp | 5 +++++ src/compiler/glsl/ir.cpp | 1 + src/compiler/glsl/ir.h | 5 +++++ src/compiler/glsl/linker.cpp | 9 +++++++-- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index fb7c2cce924..8e617499811 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -4630,6 +4630,7 @@ process_initializer(ir_variable *var, ast_declaration *decl, if (!error_emitted) { var->constant_initializer = rhs->constant_expression_value(mem_ctx); var->data.has_initializer = true; + var->data.is_implicit_initializer = false; /* If the declared variable is an unsized array, it must inherrit * its full type from the initializer. A declaration such as @@ -5269,6 +5270,7 @@ ast_declarator_list::hir(exec_list *instructions, (var->type->is_numeric() || var->type->is_boolean())) { const ir_constant_data data = { { 0 } }; var->data.has_initializer = true; + var->data.is_implicit_initializer = true; var->constant_initializer = new(var) ir_constant(var->type, &data); } @@ -5863,6 +5865,7 @@ ast_parameter_declarator::hir(exec_list *instructions, (var->type->is_numeric() || var->type->is_boolean())) { const ir_constant_data data = { { 0 } }; var->data.has_initializer = true; + var->data.is_implicit_initializer = true; var->constant_initializer = new(var) ir_constant(var->type, &data); } @@ -8776,6 +8779,7 @@ ast_cs_input_layout::hir(exec_list *instructions, var->constant_initializer = new(var) ir_constant(glsl_type::uvec3_type, &data); var->data.has_initializer = true; + var->data.is_implicit_initializer = false; return NULL; } @@ -8807,6 +8811,7 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, if (!var->constant_initializer && state->zero_init) { const ir_constant_data data = { { 0 } }; var->data.has_initializer = true; + var->data.is_implicit_initializer = true; var->constant_initializer = new(var) ir_constant(var->type, &data); } } diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp index 922dcd3c819..66660c73c75 100644 --- a/src/compiler/glsl/ir.cpp +++ b/src/compiler/glsl/ir.cpp @@ -1834,6 +1834,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, this->data.explicit_binding = false; this->data.explicit_component = false; this->data.has_initializer = false; + this->data.is_implicit_initializer = false; this->data.is_unmatched_generic_inout = false; this->data.is_xfb_only = false; this->data.explicit_xfb_buffer = false; diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index e84da9a5027..c6edffea34a 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -758,6 +758,11 @@ public: */ unsigned has_initializer:1; + /** + * Is the initializer created by the compiler (glsl_zero_init) + */ + unsigned is_implicit_initializer:1; + /** * Is this variable a generic output or input that has not yet been matched * up to a variable in another stage of the pipeline? diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index a49c5e6ccc2..a674726312f 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -1064,9 +1064,13 @@ cross_validate_globals(struct gl_context *ctx, struct gl_shader_program *prog, * no vendor actually implemented that behavior. The 4.20 * behavior matches the implemented behavior of at least one other * vendor, so we'll implement that for all GLSL versions. + * If (at least) one of these constant expressions is implicit, + * because it was added by glsl_zero_init, we skip the verification. */ if (var->constant_initializer != NULL) { - if (existing->constant_initializer != NULL) { + if (existing->constant_initializer != NULL && + !existing->data.is_implicit_initializer && + !var->data.is_implicit_initializer) { if (!var->constant_initializer->has_value(existing->constant_initializer)) { linker_error(prog, "initializers for %s " "`%s' have differing values\n", @@ -1078,7 +1082,8 @@ cross_validate_globals(struct gl_context *ctx, struct gl_shader_program *prog, * not have an initializer but a later instance does, * replace the former with the later. */ - variables->replace_variable(existing->name, var); + if (!var->data.is_implicit_initializer) + variables->replace_variable(existing->name, var); } } -- 2.30.2