[Mesa-dev] [PATCH] glsl: Prohibit illegal mixing of redeclarations inside/outside gl_PerVertex.
Paul Berry
stereotype441 at gmail.com
Tue Nov 19 17:02:22 PST 2013
>From section 7.1 (Built-In Language Variables) of the GLSL 4.10
spec:
Also, if a built-in interface block is redeclared, no member of
the built-in declaration can be redeclared outside the block
redeclaration.
We have been regarding this text as a clarification to the behaviour
established for gl_PerVertex by GLSL 1.50, so we apply it regardless
of GLSL version.
This patch enforces the rule by adding a boolean to ir_variable to
track how the variable was declared: implicitly, normally, or in an
interface block.
Fixes piglit tests:
- gs-redeclares-pervertex-out-after-global-redeclaration.geom
- vs-redeclares-pervertex-out-after-global-redeclaration.vert
- gs-redeclares-pervertex-out-after-other-global-redeclaration.geom
- vs-redeclares-pervertex-out-after-other-global-redeclaration.vert
- gs-redeclares-pervertex-out-before-global-redeclaration
- vs-redeclares-pervertex-out-before-global-redeclaration
Cc: "10.0" <mesa-stable at lists.freedesktop.org>
---
src/glsl/ast_to_hir.cpp | 20 ++++++++++++++++++++
src/glsl/builtin_variables.cpp | 3 +++
src/glsl/ir.cpp | 3 ++-
src/glsl/ir.h | 36 ++++++++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 76b256c..0128047 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -3355,6 +3355,15 @@ ast_declarator_list::hir(exec_list *instructions,
ir_variable *earlier =
get_variable_being_redeclared(var, decl->get_location(), state,
false /* allow_all_redeclarations */);
+ if (earlier != NULL) {
+ if (strncmp(var->name, "gl_", 3) == 0 &&
+ earlier->how_declared == ir_var_declared_in_block) {
+ _mesa_glsl_error(&loc, state,
+ "`%s' has already been redeclared using "
+ "gl_PerVertex", var->name);
+ }
+ earlier->how_declared = ir_var_declared_normally;
+ }
if (decl->initializer != NULL) {
result = process_initializer((earlier == NULL) ? var : earlier,
@@ -5048,6 +5057,7 @@ ast_interface_block::hir(exec_list *instructions,
_mesa_glsl_error(&loc, state, "`%s' redeclared",
this->instance_name);
}
+ earlier->how_declared = ir_var_declared_normally;
earlier->type = var->type;
earlier->reinit_interface_type(block_type);
delete var;
@@ -5078,7 +5088,11 @@ ast_interface_block::hir(exec_list *instructions,
_mesa_glsl_error(&loc, state,
"redeclaration of gl_PerVertex can only "
"include built-in variables");
+ } else if (earlier->how_declared == ir_var_declared_normally) {
+ _mesa_glsl_error(&loc, state,
+ "`%s' has already been redeclared", var->name);
} else {
+ earlier->how_declared = ir_var_declared_in_block;
earlier->reinit_interface_type(block_type);
}
continue;
@@ -5125,6 +5139,12 @@ ast_interface_block::hir(exec_list *instructions,
if (var != NULL &&
var->get_interface_type() == earlier_per_vertex &&
var->mode == var_mode) {
+ if (var->how_declared == ir_var_declared_normally) {
+ _mesa_glsl_error(&loc, state,
+ "redeclaration of gl_PerVertex cannot "
+ "follow a redeclaration of `%s'",
+ var->name);
+ }
state->symbols->disable_variable(var->name);
var->remove();
}
diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp
index 4d44104..257a36d 100644
--- a/src/glsl/builtin_variables.cpp
+++ b/src/glsl/builtin_variables.cpp
@@ -434,6 +434,7 @@ builtin_variable_generator::add_variable(const char *name,
enum ir_variable_mode mode, int slot)
{
ir_variable *var = new(symtab) ir_variable(type, name, mode);
+ var->how_declared = ir_var_declared_implicitly;
switch (var->mode) {
case ir_var_auto:
@@ -472,6 +473,7 @@ builtin_variable_generator::add_uniform(const glsl_type *type,
const char *name)
{
ir_variable *const uni = add_variable(name, type, ir_var_uniform, -1);
+ uni->how_declared = ir_var_declared_implicitly;
unsigned i;
for (i = 0; _mesa_builtin_uniform_desc[i].name != NULL; i++) {
@@ -520,6 +522,7 @@ builtin_variable_generator::add_const(const char *name, int value)
{
ir_variable *const var = add_variable(name, glsl_type::int_type,
ir_var_auto, -1);
+ var->how_declared = ir_var_declared_implicitly;
var->constant_value = new(var) ir_constant(value);
var->constant_initializer = new(var) ir_constant(value);
var->has_initializer = true;
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 1b49736..ffff297 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1586,7 +1586,8 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
ir_variable_mode mode)
: max_array_access(0), max_ifc_array_access(NULL),
read_only(false), centroid(false), invariant(false),
- mode(mode), interpolation(INTERP_QUALIFIER_NONE), atomic()
+ how_declared(ir_var_declared_normally), mode(mode),
+ interpolation(INTERP_QUALIFIER_NONE), atomic()
{
this->ir_type = ir_type_variable;
this->type = type;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 7859702..4f775da 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -294,6 +294,34 @@ enum ir_variable_mode {
};
/**
+ * Enum keeping track of how a variable was declared. For error checking of
+ * the gl_PerVertex redeclaration rules.
+ */
+enum ir_var_declaration_type {
+ /**
+ * Normal declaration (for most variables, this means an explicit
+ * declaration. Exception: temporaries are always implicitly declared, but
+ * they still use ir_var_declared_normally).
+ *
+ * Note: an ir_variable that represents a named interface block uses
+ * ir_var_declared_normally.
+ */
+ ir_var_declared_normally = 0,
+
+ /**
+ * Variable was explicitly declared (or re-declared) in an unnamed
+ * interface block.
+ */
+ ir_var_declared_in_block,
+
+ /**
+ * Variable is an implicitly declared built-in that has not been explicitly
+ * re-declared by the shader.
+ */
+ ir_var_declared_implicitly,
+};
+
+/**
* \brief Layout qualifiers for gl_FragDepth.
*
* The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared
@@ -526,6 +554,14 @@ public:
unsigned assigned:1;
/**
+ * Enum indicating how the variable was declared. See
+ * ir_var_declaration_type.
+ *
+ * This is used to detect certain kinds of illegal variable redeclarations.
+ */
+ unsigned how_declared:2;
+
+ /**
* Storage class of the variable.
*
* \sa ir_variable_mode
--
1.8.4.2
More information about the mesa-dev
mailing list