[Mesa-dev] [PATCH 2/9] glsl: merge layouts into the default one as the last step in interface blocks

Timothy Arceri timothy.arceri at collabora.com
Mon Oct 24 01:23:23 UTC 2016


On Sat, 2016-10-22 at 23:09 +0300, Andres Gomez wrote:
> Consider this example:
> 
>     " #version 150 core
>       #extension GL_ARB_shading_language_420pack: require
>       #extension GL_ARB_explicit_attrib_location: require
> 
>       layout(location=0) out vec4 o;
>       layout(binding=2) layout(binding=3, std140) uniform U {
>           vec4 a;
>       } u[2];"
> 
> As there is 2 layout-qualifiers for the uniform U and the binding
> layout-qualifier-id is duplicated, the rules set by the
> ARB_shading_language_420pack spec state that the rightmost should
> prevail.
> 
> Our ast_type_qualifier merges with others in a way that if the value
> for a layout-qualifier-id is set in both, the object being merged
> overwrites the value of the object invoking the merge. Hence, the
> merge has to happen from the left layout towards the right one and
> this was not happening for interface blocks because we were merging
> into the default layout qualifier.
> 
> Now, the merge is done from left to right and, as a last step, we
> merge into the default layout qualifier if needed, so the values of
> the explicit layouts prevail over it.
> 
> Signed-off-by: Andres Gomez <agomez at igalia.com>

That patch looks logically correct. However I'd really like it if you
could rename the existing layout member to default_layout and make the
new one layout rather than layout_helper.

I understand this will likely be a few more changes but the end result
will be much easier to follow.


> ---
>  src/compiler/glsl/ast.h                  |  9 ++++++---
>  src/compiler/glsl/ast_type.cpp           |  9 +++++++++
>  src/compiler/glsl/glsl_parser.yy         | 16 +++++++++++-----
>  src/compiler/glsl/glsl_parser_extras.cpp |  2 --
>  4 files changed, 26 insertions(+), 10 deletions(-)
> 
> diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h
> index 55f009a..54119b7 100644
> --- a/src/compiler/glsl/ast.h
> +++ b/src/compiler/glsl/ast.h
> @@ -725,9 +725,6 @@ struct ast_type_qualifier {
>      */
>     glsl_base_type image_base_type;
>  
> -   /** Flag to know if this represents a default value for a
> qualifier */
> -   bool is_default_qualifier;
> -
>     /**
>      * Return true if and only if an interpolation qualifier is
> present.
>      */
> @@ -748,6 +745,11 @@ struct ast_type_qualifier {
>      */
>     bool has_auxiliary_storage() const;
>  
> +   /**
> +    * Return true if and only if a memory qualifier is present.
> +    */
> +   bool has_memory() const;
> +
>     bool merge_qualifier(YYLTYPE *loc,
>  			_mesa_glsl_parse_state *state,
>                          const ast_type_qualifier &q,
> @@ -1140,6 +1142,7 @@ public:
>  			  struct _mesa_glsl_parse_state *state);
>  
>     ast_type_qualifier layout;
> +   ast_type_qualifier layout_helper;
>     const char *block_name;
>  
>     /**
> diff --git a/src/compiler/glsl/ast_type.cpp
> b/src/compiler/glsl/ast_type.cpp
> index 35acce3..f5bd936 100644
> --- a/src/compiler/glsl/ast_type.cpp
> +++ b/src/compiler/glsl/ast_type.cpp
> @@ -107,6 +107,15 @@ ast_type_qualifier::has_auxiliary_storage()
> const
>            || this->flags.q.patch;
>  }
>  
> +bool ast_type_qualifier::has_memory() const
> +{
> +   return this->flags.q.coherent
> +          || this->flags.q._volatile
> +          || this->flags.q.restrict_flag
> +          || this->flags.q.read_only
> +          || this->flags.q.write_only;
> +}
> +
>  /**
>   * This function merges both duplicate identifies within a single
> layout and
>   * multiple layout qualifiers on a single variable declaration. The
> diff --git a/src/compiler/glsl/glsl_parser.yy
> b/src/compiler/glsl/glsl_parser.yy
> index 38cbd3f..b2e9e6a 100644
> --- a/src/compiler/glsl/glsl_parser.yy
> +++ b/src/compiler/glsl/glsl_parser.yy
> @@ -838,6 +838,12 @@ declaration:
>     }
>     | interface_block
>     {
> +      ast_interface_block *block = (ast_interface_block *) $1;
> +      if (block->layout_helper.has_layout() || block-
> >layout_helper.has_memory()) {
> +         if (!block->layout.merge_qualifier(& @1, state, block-
> >layout_helper, false)) {
> +            YYERROR;
> +         }
> +      }
>        $$ = $1;
>     }
>     ;
> @@ -2701,17 +2707,16 @@ interface_block:
>     {
>        ast_interface_block *block = (ast_interface_block *) $2;
>  
> -      if (!state->has_420pack_or_es31() && block-
> >layout.has_layout() &&
> -          !block->layout.is_default_qualifier) {
> +      if (!state->has_420pack_or_es31() && block-
> >layout_helper.has_layout()) {
>           _mesa_glsl_error(&@1, state, "duplicate layout(...)
> qualifiers");
>           YYERROR;
>        }
>  
> -      if (!block->layout.merge_qualifier(& @1, state, $1, false)) {
> +      if (!$1.merge_qualifier(& @1, state, block->layout_helper,
> false)) {
>           YYERROR;
>        }
>  
> -      block->layout.is_default_qualifier = false;
> +      block->layout_helper = $1;
>  
>        $$ = block;
>     }
> @@ -2724,9 +2729,10 @@ interface_block:
>                               "memory qualifiers can only be used in
> the "
>                               "declaration of shader storage
> blocks");
>        }
> -      if (!block->layout.merge_qualifier(& @1, state, $1, false)) {
> +      if (!$1.merge_qualifier(& @1, state, block->layout_helper,
> false)) {
>           YYERROR;
>        }
> +      block->layout_helper = $1;
>        $$ = block;
>     }
>     ;
> diff --git a/src/compiler/glsl/glsl_parser_extras.cpp
> b/src/compiler/glsl/glsl_parser_extras.cpp
> index b351180..3b487b3 100644
> --- a/src/compiler/glsl/glsl_parser_extras.cpp
> +++ b/src/compiler/glsl/glsl_parser_extras.cpp
> @@ -273,12 +273,10 @@
> _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context
> *_ctx,
>     this->default_uniform_qualifier = new(this) ast_type_qualifier();
>     this->default_uniform_qualifier->flags.q.shared = 1;
>     this->default_uniform_qualifier->flags.q.column_major = 1;
> -   this->default_uniform_qualifier->is_default_qualifier = true;
>  
>     this->default_shader_storage_qualifier = new(this)
> ast_type_qualifier();
>     this->default_shader_storage_qualifier->flags.q.shared = 1;
>     this->default_shader_storage_qualifier->flags.q.column_major = 1;
> -   this->default_shader_storage_qualifier->is_default_qualifier =
> true;
>  
>     this->fs_uses_gl_fragcoord = false;
>     this->fs_redeclares_gl_fragcoord = false;


More information about the mesa-dev mailing list