<div dir="ltr">On 20 November 2013 11:26, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>On 11/19/2013 05:55 PM, Paul Berry wrote:<br>
> From section 7.1 (Built-In Language Variables) of the GLSL 4.10<br>
> spec:<br>
><br>
> Also, if a built-in interface block is redeclared, no member of<br>
> the built-in declaration can be redeclared outside the block<br>
> redeclaration.<br>
><br>
> We have been regarding this text as a clarification to the behaviour<br>
> established for gl_PerVertex by GLSL 1.50, so we apply it regardless<br>
> of GLSL version.<br>
><br>
> This patch enforces the rule by adding a boolean to ir_variable to<br>
<br>
</div>But it's not a boolean. :) Tri-state?<br></blockquote><div><br></div><div>Oops, sorry. This comment was left over from a previous (failed) attempt to implement the correct functionality. I've changed this paragraph to:<br>
<br>This patch enforces the rule by adding an enum to ir_variable to track<br>how the variable was declared: implicitly, normally, or in an<br>interface block.<br><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div><br>
> track how the variable was declared: implicitly, normally, or in an<br>
> interface block.<br>
><br>
> Fixes piglit tests:<br>
> - gs-redeclares-pervertex-out-after-global-redeclaration.geom<br>
> - vs-redeclares-pervertex-out-after-global-redeclaration.vert<br>
> - gs-redeclares-pervertex-out-after-other-global-redeclaration.geom<br>
> - vs-redeclares-pervertex-out-after-other-global-redeclaration.vert<br>
> - gs-redeclares-pervertex-out-before-global-redeclaration<br>
> - vs-redeclares-pervertex-out-before-global-redeclaration<br>
><br>
> Cc: "10.0" <<a href="mailto:mesa-stable@lists.freedesktop.org" target="_blank">mesa-stable@lists.freedesktop.org</a>><br>
><br>
> v2: Don't set "how_declared" redundantly in builtin_variables.cpp.<br>
> Properly clone "how_declared".<br>
> ---<br>
> src/glsl/ast_to_hir.cpp | 20 ++++++++++++++++++++<br>
> src/glsl/builtin_variables.cpp | 1 +<br>
> src/glsl/ir.cpp | 3 ++-<br>
> src/glsl/ir.h | 36 ++++++++++++++++++++++++++++++++++++<br>
> src/glsl/ir_clone.cpp | 1 +<br>
> 5 files changed, 60 insertions(+), 1 deletion(-)<br>
><br>
> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp<br>
> index 76b256c..0128047 100644<br>
> --- a/src/glsl/ast_to_hir.cpp<br>
> +++ b/src/glsl/ast_to_hir.cpp<br>
> @@ -3355,6 +3355,15 @@ ast_declarator_list::hir(exec_list *instructions,<br>
> ir_variable *earlier =<br>
> get_variable_being_redeclared(var, decl->get_location(), state,<br>
> false /* allow_all_redeclarations */);<br>
> + if (earlier != NULL) {<br>
> + if (strncmp(var->name, "gl_", 3) == 0 &&<br>
> + earlier->how_declared == ir_var_declared_in_block) {<br>
> + _mesa_glsl_error(&loc, state,<br>
> + "`%s' has already been redeclared using "<br>
> + "gl_PerVertex", var->name);<br>
> + }<br>
> + earlier->how_declared = ir_var_declared_normally;<br>
> + }<br>
><br>
> if (decl->initializer != NULL) {<br>
> result = process_initializer((earlier == NULL) ? var : earlier,<br>
> @@ -5048,6 +5057,7 @@ ast_interface_block::hir(exec_list *instructions,<br>
> _mesa_glsl_error(&loc, state, "`%s' redeclared",<br>
> this->instance_name);<br>
> }<br>
> + earlier->how_declared = ir_var_declared_normally;<br>
<br>
</div></div>Is this correct? At this point redeclaring_per_vertex is true, so it<br>
seems like this should be ir_var_declared_in_block.<br></blockquote><div><br></div><div>It's correct as is. This block of code handles the case where a named interface block (i.e. the gl_PerVertex interface block representing geometry shader inputs) is being redeclared. In this case, the ir_variable represents the entire interface block, so it is ir_var_declared_normally (see the comment below: "Note: an ir_variable that represents a named interface block uses ir_var_declared_normally.").<br>
<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div><br>
> earlier->type = var->type;<br>
> earlier->reinit_interface_type(block_type);<br>
> delete var;<br>
> @@ -5078,7 +5088,11 @@ ast_interface_block::hir(exec_list *instructions,<br>
> _mesa_glsl_error(&loc, state,<br>
> "redeclaration of gl_PerVertex can only "<br>
> "include built-in variables");<br>
> + } else if (earlier->how_declared == ir_var_declared_normally) {<br>
> + _mesa_glsl_error(&loc, state,<br>
> + "`%s' has already been redeclared", var->name);<br>
> } else {<br>
> + earlier->how_declared = ir_var_declared_in_block;<br>
> earlier->reinit_interface_type(block_type);<br>
> }<br>
> continue;<br>
> @@ -5125,6 +5139,12 @@ ast_interface_block::hir(exec_list *instructions,<br>
> if (var != NULL &&<br>
> var->get_interface_type() == earlier_per_vertex &&<br>
> var->mode == var_mode) {<br>
> + if (var->how_declared == ir_var_declared_normally) {<br>
> + _mesa_glsl_error(&loc, state,<br>
> + "redeclaration of gl_PerVertex cannot "<br>
> + "follow a redeclaration of `%s'",<br>
> + var->name);<br>
> + }<br>
> state->symbols->disable_variable(var->name);<br>
> var->remove();<br>
> }<br>
> diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp<br>
> index 4d44104..d57324c 100644<br>
> --- a/src/glsl/builtin_variables.cpp<br>
> +++ b/src/glsl/builtin_variables.cpp<br>
> @@ -434,6 +434,7 @@ builtin_variable_generator::add_variable(const char *name,<br>
> enum ir_variable_mode mode, int slot)<br>
> {<br>
> ir_variable *var = new(symtab) ir_variable(type, name, mode);<br>
> + var->how_declared = ir_var_declared_implicitly;<br>
><br>
> switch (var->mode) {<br>
> case ir_var_auto:<br>
> diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp<br>
> index 1b49736..ffff297 100644<br>
> --- a/src/glsl/ir.cpp<br>
> +++ b/src/glsl/ir.cpp<br>
> @@ -1586,7 +1586,8 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,<br>
> ir_variable_mode mode)<br>
> : max_array_access(0), max_ifc_array_access(NULL),<br>
> read_only(false), centroid(false), invariant(false),<br>
> - mode(mode), interpolation(INTERP_QUALIFIER_NONE), atomic()<br>
> + how_declared(ir_var_declared_normally), mode(mode),<br>
> + interpolation(INTERP_QUALIFIER_NONE), atomic()<br>
> {<br>
> this->ir_type = ir_type_variable;<br>
> this->type = type;<br>
> diff --git a/src/glsl/ir.h b/src/glsl/ir.h<br>
> index 7859702..4f775da 100644<br>
> --- a/src/glsl/ir.h<br>
> +++ b/src/glsl/ir.h<br>
> @@ -294,6 +294,34 @@ enum ir_variable_mode {<br>
> };<br>
><br>
> /**<br>
> + * Enum keeping track of how a variable was declared. For error checking of<br>
> + * the gl_PerVertex redeclaration rules.<br>
> + */<br>
> +enum ir_var_declaration_type {<br>
> + /**<br>
> + * Normal declaration (for most variables, this means an explicit<br>
> + * declaration. Exception: temporaries are always implicitly declared, but<br>
> + * they still use ir_var_declared_normally).<br>
> + *<br>
> + * Note: an ir_variable that represents a named interface block uses<br>
> + * ir_var_declared_normally.<br>
> + */<br>
> + ir_var_declared_normally = 0,<br>
> +<br>
> + /**<br>
> + * Variable was explicitly declared (or re-declared) in an unnamed<br>
> + * interface block.<br>
> + */<br>
> + ir_var_declared_in_block,<br>
> +<br>
> + /**<br>
> + * Variable is an implicitly declared built-in that has not been explicitly<br>
> + * re-declared by the shader.<br>
> + */<br>
> + ir_var_declared_implicitly,<br>
> +};<br>
> +<br>
> +/**<br>
> * \brief Layout qualifiers for gl_FragDepth.<br>
> *<br>
> * The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared<br>
> @@ -526,6 +554,14 @@ public:<br>
> unsigned assigned:1;<br>
><br>
> /**<br>
> + * Enum indicating how the variable was declared. See<br>
> + * ir_var_declaration_type.<br>
> + *<br>
> + * This is used to detect certain kinds of illegal variable redeclarations.<br>
> + */<br>
> + unsigned how_declared:2;<br>
> +<br>
> + /**<br>
> * Storage class of the variable.<br>
> *<br>
> * \sa ir_variable_mode<br>
> diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp<br>
> index b0f173a..40ed33a 100644<br>
> --- a/src/glsl/ir_clone.cpp<br>
> +++ b/src/glsl/ir_clone.cpp<br>
> @@ -68,6 +68,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const<br>
> var->has_initializer = this->has_initializer;<br>
> var->depth_layout = this->depth_layout;<br>
> var->assigned = this->assigned;<br>
> + var->how_declared = this->how_declared;<br>
> var->used = this->used;<br>
><br>
> var->num_state_slots = this->num_state_slots;<br>
><br>
<br>
</div></div></blockquote></div><br></div></div>