From ea9bde151f1394ff82b73d028c2a3a747723e525 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Tue, 4 Sep 2018 11:42:04 +0300 Subject: [PATCH] glsl: Cross validate variable's invariance by explicit invariance only 'invariant' qualifier is propagated on variables which are used to calculate other invariant variables, however when we are matching variable's declarations we should take into account only explicitly declared invariance because invariance propagation is an implementation specific detail. Thus new flag is added to ir_variable_data which indicates 'invariant' qualifier being explicitly set in the shader. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100316 Fixes: 89b60492 ('glsl: Add a pass to propagate the "invariant" and "precise" qualifiers') Signed-off-by: Danylo Piliaiev Reviewed-by: Jordan Justen --- src/compiler/glsl/ast_to_hir.cpp | 8 ++++++-- src/compiler/glsl/ir.cpp | 1 + src/compiler/glsl/ir.h | 13 +++++++++++++ src/compiler/glsl/ir_print_visitor.cpp | 5 +++-- src/compiler/glsl/ir_reader.cpp | 4 +++- src/compiler/glsl/link_varyings.cpp | 6 +++--- src/compiler/glsl/linker.cpp | 2 +- 7 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index 3875fa1e384..2a71a13d545 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -3942,7 +3942,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, "`invariant' after being used", var->name); } else { - var->data.invariant = 1; + var->data.explicit_invariant = true; + var->data.invariant = true; } } @@ -4150,8 +4151,10 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } } - if (state->all_invariant && var->data.mode == ir_var_shader_out) + if (state->all_invariant && var->data.mode == ir_var_shader_out) { + var->data.explicit_invariant = true; var->data.invariant = true; + } var->data.interpolation = interpret_interpolation_qualifier(qual, var->type, @@ -4862,6 +4865,7 @@ ast_declarator_list::hir(exec_list *instructions, "`invariant' after being used", earlier->name); } else { + earlier->data.explicit_invariant = true; earlier->data.invariant = true; } } diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp index 060bd3ae7f5..6b455cdf510 100644 --- a/src/compiler/glsl/ir.cpp +++ b/src/compiler/glsl/ir.cpp @@ -1732,6 +1732,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, this->data.centroid = false; this->data.sample = false; this->data.patch = false; + this->data.explicit_invariant = false; this->data.invariant = false; this->data.how_declared = ir_var_declared_normally; this->data.mode = mode; diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index 9ec332ab46c..4dc2a5f6bc7 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -657,6 +657,19 @@ public: unsigned centroid:1; unsigned sample:1; unsigned patch:1; + /** + * Was an 'invariant' qualifier explicitly set in the shader? + * + * This is used to cross validate qualifiers. + */ + unsigned explicit_invariant:1; + /** + * Is the variable invariant? + * + * It can happen either by having the 'invariant' qualifier + * explicitly set in the shader or by being used in calculations + * of other invariant variables. + */ unsigned invariant:1; unsigned precise:1; diff --git a/src/compiler/glsl/ir_print_visitor.cpp b/src/compiler/glsl/ir_print_visitor.cpp index 119e3ee1e2e..e208aaef888 100644 --- a/src/compiler/glsl/ir_print_visitor.cpp +++ b/src/compiler/glsl/ir_print_visitor.cpp @@ -199,6 +199,7 @@ void ir_print_visitor::visit(ir_variable *ir) const char *const samp = (ir->data.sample) ? "sample " : ""; const char *const patc = (ir->data.patch) ? "patch " : ""; const char *const inv = (ir->data.invariant) ? "invariant " : ""; + const char *const explicit_inv = (ir->data.explicit_invariant) ? "explicit_invariant " : ""; const char *const prec = (ir->data.precise) ? "precise " : ""; const char *const bindless = (ir->data.bindless) ? "bindless " : ""; const char *const bound = (ir->data.bound) ? "bound " : ""; @@ -215,11 +216,11 @@ void ir_print_visitor::visit(ir_variable *ir) const char *const interp[] = { "", "smooth", "flat", "noperspective" }; STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_MODE_COUNT); - fprintf(f, "(%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s) ", + fprintf(f, "(%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s) ", binding, loc, component, cent, bindless, bound, image_format, memory_read_only, memory_write_only, memory_coherent, memory_volatile, memory_restrict, - samp, patc, inv, prec, mode[ir->data.mode], + samp, patc, inv, explicit_inv, prec, mode[ir->data.mode], stream, interp[ir->data.interpolation]); diff --git a/src/compiler/glsl/ir_reader.cpp b/src/compiler/glsl/ir_reader.cpp index b87933ba511..d4f0e58b155 100644 --- a/src/compiler/glsl/ir_reader.cpp +++ b/src/compiler/glsl/ir_reader.cpp @@ -419,8 +419,10 @@ ir_reader::read_declaration(s_expression *expr) var->data.sample = 1; } else if (strcmp(qualifier->value(), "patch") == 0) { var->data.patch = 1; + } else if (strcmp(qualifier->value(), "explicit_invariant") == 0) { + var->data.explicit_invariant = true; } else if (strcmp(qualifier->value(), "invariant") == 0) { - var->data.invariant = 1; + var->data.invariant = true; } else if (strcmp(qualifier->value(), "uniform") == 0) { var->data.mode = ir_var_uniform; } else if (strcmp(qualifier->value(), "shader_storage") == 0) { diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp index 618610039ea..352cd7e522b 100644 --- a/src/compiler/glsl/link_varyings.cpp +++ b/src/compiler/glsl/link_varyings.cpp @@ -309,16 +309,16 @@ cross_validate_types_and_qualifiers(struct gl_context *ctx, * "The invariance of varyings that are declared in both the vertex * and fragment shaders must match." */ - if (input->data.invariant != output->data.invariant && + if (input->data.explicit_invariant != output->data.explicit_invariant && prog->data->Version < (prog->IsES ? 300 : 430)) { linker_error(prog, "%s shader output `%s' %s invariant qualifier, " "but %s shader input %s invariant qualifier\n", _mesa_shader_stage_to_string(producer_stage), output->name, - (output->data.invariant) ? "has" : "lacks", + (output->data.explicit_invariant) ? "has" : "lacks", _mesa_shader_stage_to_string(consumer_stage), - (input->data.invariant) ? "has" : "lacks"); + (input->data.explicit_invariant) ? "has" : "lacks"); return; } diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 53887ab71da..c6664e98ce3 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -1090,7 +1090,7 @@ cross_validate_globals(struct gl_context *ctx, struct gl_shader_program *prog, } } - if (existing->data.invariant != var->data.invariant) { + if (existing->data.explicit_invariant != var->data.explicit_invariant) { linker_error(prog, "declarations for %s `%s' have " "mismatching invariant qualifiers\n", mode_string(var), var->name); -- 2.30.2