[Mesa-dev] [PATCH 05/13] glsl: simplifies the merge of the default in layout qualifier

Timothy Arceri timothy.arceri at collabora.com
Thu Nov 17 05:17:57 UTC 2016


On Mon, 2016-11-14 at 19:15 +0200, Andres Gomez wrote:
> The merge into the default in layout qualifier duplicates a lot of
> code that can be reused from the generic merge method.
> 
> Now, we use the generic merge method inside the specific merge for
> the
> default in layout qualifier. The generic merge method has been
> completed with some bits that were only present in the merge for the
> default in layout qualifier and the specific validation bits have
> been
> moved to the validation method for the default in layout qualifier.
> 
> Signed-off-by: Andres Gomez <agomez at igalia.com>
> ---
>  src/compiler/glsl/ast_type.cpp | 165 ++++++++++++++++++++-----------
> ----------
>  1 file changed, 81 insertions(+), 84 deletions(-)
> 
> diff --git a/src/compiler/glsl/ast_type.cpp
> b/src/compiler/glsl/ast_type.cpp
> index 803d952..064c63b 100644
> --- a/src/compiler/glsl/ast_type.cpp
> +++ b/src/compiler/glsl/ast_type.cpp
> @@ -198,16 +198,20 @@ ast_type_qualifier::merge_qualifier(YYLTYPE
> *loc,
>     if (q.flags.q.prim_type) {
>        if (this->flags.q.prim_type && this->prim_type != q.prim_type)
> {
>           _mesa_glsl_error(loc, state,
> -                          "conflicting primitive type qualifiers
> used");
> +                          "conflicting input primitive %s
> specified",
> +                          state->stage == MESA_SHADER_GEOMETRY ?
> +                          "type" : "mode");
>           return false;
>        }
> +      this->flags.q.prim_type = 1;
>        this->prim_type = q.prim_type;
>     }
>  
>     if (q.flags.q.max_vertices) {
> -      if (this->max_vertices && !is_single_layout_merge) {
> +      if (this->flags.q.max_vertices && !is_single_layout_merge) {
>           this->max_vertices->merge_qualifier(q.max_vertices);
>        } else {
> +         this->flags.q.max_vertices = 1;
>           this->max_vertices = q.max_vertices;
>        }
>     }
> @@ -222,9 +226,10 @@ ast_type_qualifier::merge_qualifier(YYLTYPE
> *loc,
>     }
>  
>     if (q.flags.q.invocations) {
> -      if (this->invocations && !is_single_layout_merge) {
> +      if (this->flags.q.invocations && !is_single_layout_merge) {
>           this->invocations->merge_qualifier(q.invocations);
>        } else {
> +         this->flags.q.invocations = 1;
>           this->invocations = q.invocations;
>        }
>     }
> @@ -284,9 +289,10 @@ ast_type_qualifier::merge_qualifier(YYLTYPE
> *loc,
>     }
>  
>     if (q.flags.q.vertices) {
> -      if (this->vertices && !is_single_layout_merge) {
> +      if (this->flags.q.vertices && !is_single_layout_merge) {
>           this->vertices->merge_qualifier(q.vertices);
>        } else {
> +         this->flags.q.vertices = 1;
>           this->vertices = q.vertices;
>        }
>     }
> @@ -296,6 +302,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
>           _mesa_glsl_error(loc, state, "conflicting vertex spacing
> used");
>           return false;
>        }
> +      this->flags.q.vertex_spacing = 1;
>        this->vertex_spacing = q.vertex_spacing;
>     }
>  
> @@ -304,6 +311,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
>           _mesa_glsl_error(loc, state, "conflicting ordering used");
>           return false;
>        }
> +      this->flags.q.ordering = 1;
>        this->ordering = q.ordering;
>     }
>  
> @@ -312,9 +320,13 @@ ast_type_qualifier::merge_qualifier(YYLTYPE
> *loc,
>           _mesa_glsl_error(loc, state, "conflicting point mode
> used");
>           return false;
>        }
> +      this->flags.q.point_mode = 1;
>        this->point_mode = q.point_mode;
>     }
>  
> +   if (q.flags.q.early_fragment_tests)
> +      this->flags.q.early_fragment_tests = true;
> +
>     if ((q.flags.i & ubo_mat_mask.flags.i) != 0)
>        this->flags.i &= ~ubo_mat_mask.flags.i;
>     if ((q.flags.i & ubo_layout_mask.flags.i) != 0)
> @@ -330,6 +342,9 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
>        }
>     }
>  
> +   if (q.flags.q.local_size_variable)
> +      this->flags.q.local_size_variable = true;
> +
>     this->flags.i |= q.flags.i;
>  
>     if (this->flags.q.in &&
> @@ -534,6 +549,45 @@
> ast_type_qualifier::validate_in_qualifier(YYLTYPE *loc,
>        _mesa_glsl_error(loc, state, "invalid input layout qualifiers
> used");
>     }
>  
> +   /* The checks below are also performed when merging but we want
> to spit an
> +    * error against the default global input qualifier as soon as we
> can, with
> +    * the closest error location in the shader.
> +    */

This comment looks like it should be removed? Don't the below changes
remove the validation from the merge?


> +
> +   /* Input layout qualifiers can be specified multiple
> +    * times in separate declarations, as long as they match.
> +    */
> +   if (state->in_qualifier->flags.q.prim_type && this-
> >flags.q.prim_type
> +       && state->in_qualifier->prim_type != this->prim_type) {
> +      r = false;
> +      _mesa_glsl_error(loc, state,
> +                       "conflicting input primitive %s specified",
> +                       state->stage == MESA_SHADER_GEOMETRY ?
> +                       "type" : "mode");
> +   }
> +
> +   if (state->in_qualifier->flags.q.vertex_spacing
> +       && this->flags.q.vertex_spacing
> +       && state->in_qualifier->vertex_spacing != this-
> >vertex_spacing) {
> +      r = false;
> +      _mesa_glsl_error(loc, state,
> +                       "conflicting vertex spacing specified");
> +   }
> +
> +   if (state->in_qualifier->flags.q.ordering && this-
> >flags.q.ordering
> +       && state->in_qualifier->ordering != this->ordering) {
> +      r = false;
> +      _mesa_glsl_error(loc, state,
> +                       "conflicting ordering specified");
> +   }
> +
> +   if (state->in_qualifier->flags.q.point_mode && this-
> >flags.q.point_mode
> +       && state->in_qualifier->point_mode != this->point_mode) {
> +      r  = false;
           ^
There is an extra space here          
           

> +      _mesa_glsl_error(loc, state,
> +                       "conflicting point mode specified");
> +   }
> +
>     return r;
>  }
>  
> @@ -542,100 +596,43 @@
> ast_type_qualifier::merge_into_in_qualifier(YYLTYPE *loc,
>                                              _mesa_glsl_parse_state
> *state,
>                                              ast_node* &node, bool
> create_node)
>  {
> +   bool r = true;
>     void *lin_ctx = state->linalloc;
> -   bool create_gs_ast = false;
> -   bool create_cs_ast = false;
> -
> -   switch (state->stage) {
> -   case MESA_SHADER_GEOMETRY:
> -      create_gs_ast |=
> -         this->flags.q.prim_type &&
> -         !state->in_qualifier->flags.q.prim_type;
> -      break;
> -   case MESA_SHADER_COMPUTE:
> -      create_cs_ast |=
> -         this->flags.q.local_size != 0 &&
> -         state->in_qualifier->flags.q.local_size == 0;
> -      break;
> -   default:
> -      break;
> -   }
>  
> -   /* Input layout qualifiers can be specified multiple
> -    * times in separate declarations, as long as they match.
> +   /* We create the gs_input_layout node before merging so, in the
> future, no
> +    * more repeated nodes will be created as we will have the flag
> set.
>      */
> -   if (state->in_qualifier->flags.q.prim_type) {
> -      if (this->flags.q.prim_type &&
> -          state->in_qualifier->prim_type != this->prim_type) {
> -         _mesa_glsl_error(loc, state,
> -                          "conflicting input primitive %s
> specified",
> -                          state->stage == MESA_SHADER_GEOMETRY ?
> -                          "type" : "mode");
> -      }
> -   } else if (this->flags.q.prim_type) {
> -      state->in_qualifier->flags.q.prim_type = 1;
> -      state->in_qualifier->prim_type = this->prim_type;
> +   if (state->stage == MESA_SHADER_GEOMETRY
> +       && this->flags.q.prim_type && !state->in_qualifier-
> >flags.q.prim_type
> +       && create_node) {
> +      node = new(lin_ctx) ast_gs_input_layout(*loc, this-
> >prim_type);
>     }
>  
> -   if (this->flags.q.invocations) {
> -      state->in_qualifier->flags.q.invocations = 1;
> -      if (state->in_qualifier->invocations) {
> -         state->in_qualifier->invocations->merge_qualifier(this-
> >invocations);
> -      } else {
> -         state->in_qualifier->invocations = this->invocations;
> -      }
> -   }
> +   r = state->in_qualifier->merge_qualifier(loc, state, *this,
> false);
>  
> -   if (this->flags.q.early_fragment_tests) {
> +   if (state->in_qualifier->flags.q.early_fragment_tests) {
>        state->fs_early_fragment_tests = true;
> +      state->in_qualifier->flags.q.early_fragment_tests = false;
>     }
>  
> -   if (state->in_qualifier->flags.q.vertex_spacing) {
> -      if (this->flags.q.vertex_spacing &&
> -          state->in_qualifier->vertex_spacing != this-
> >vertex_spacing) {
> -         _mesa_glsl_error(loc, state,
> -                          "conflicting vertex spacing specified");
> -      }
> -   } else if (this->flags.q.vertex_spacing) {
> -      state->in_qualifier->flags.q.vertex_spacing = 1;
> -      state->in_qualifier->vertex_spacing = this->vertex_spacing;
> -   }
> -
> -   if (state->in_qualifier->flags.q.ordering) {
> -      if (this->flags.q.ordering &&
> -          state->in_qualifier->ordering != this->ordering) {
> -         _mesa_glsl_error(loc, state,
> -                          "conflicting ordering specified");
> -      }
> -   } else if (this->flags.q.ordering) {
> -      state->in_qualifier->flags.q.ordering = 1;
> -      state->in_qualifier->ordering = this->ordering;
> -   }
> -
> -   if (state->in_qualifier->flags.q.point_mode) {
> -      if (this->flags.q.point_mode &&
> -          state->in_qualifier->point_mode != this->point_mode) {
> -         _mesa_glsl_error(loc, state,
> -                          "conflicting point mode specified");
> -      }
> -   } else if (this->flags.q.point_mode) {
> -      state->in_qualifier->flags.q.point_mode = 1;
> -      state->in_qualifier->point_mode = this->point_mode;
> +   /* We allow the creation of multiple cs_input_layout nodes.
> Coherence among
> +    * all existing nodes is checked later, when the AST node is
> transformed
> +    * into HIR.
> +    */
> +   if (state->in_qualifier->flags.q.local_size) {
> +      if (create_node)
> +         node = new(lin_ctx) ast_cs_input_layout(*loc, state-
> >in_qualifier->local_size);
> +      state->in_qualifier->flags.q.local_size = 0;
> +      for (int i = 0; i < 3; i++)
> +         state->in_qualifier->local_size[i] = NULL;
>     }
>  
> -   if (this->flags.q.local_size_variable) {
> +   if (state->in_qualifier->flags.q.local_size_variable) {
>        state->cs_input_local_size_variable_specified = true;
> +      state->in_qualifier->flags.q.local_size_variable = false;
>     }
>  
> -   if (create_node) {
> -      if (create_gs_ast) {
> -         node = new(lin_ctx) ast_gs_input_layout(*loc, this-
> >prim_type);
> -      } else if (create_cs_ast) {
> -         node = new(lin_ctx) ast_cs_input_layout(*loc, this-
> >local_size);
> -      }
> -   }
> -
> -   return true;
> +   return r;
>  }
>  
>  /**


More information about the mesa-dev mailing list