<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>