Mesa (master): glsl: split default in layout qualifier merge

Andres Gomez tanty at kemper.freedesktop.org
Fri Nov 25 12:40:24 UTC 2016


Module: Mesa
Branch: master
Commit: 65df02c00287449efedc4ec3d57ceee38abaacdb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=65df02c00287449efedc4ec3d57ceee38abaacdb

Author: Andres Gomez <agomez at igalia.com>
Date:   Mon Nov 14 17:46:05 2016 +0200

glsl: split default in layout qualifier merge

Currently, the default in layout qualifier merge performs specific
validation and merge.

We want to split out the validation from the merge so they can be done
independently.

Additionally, for simplification, the direction of the validation and
merge is changed so the ast_type_qualifier calling the method is the
one validated and merged against the default in qualifier.

Reviewed-by: Timothy Arceri <timothy.arceri at collabora.com>
Signed-off-by: Andres Gomez <agomez at igalia.com>

---

 src/compiler/glsl/ast.h          |  16 +++--
 src/compiler/glsl/ast_type.cpp   | 127 ++++++++++++++++++++++-----------------
 src/compiler/glsl/glsl_parser.yy |  12 ++--
 3 files changed, 93 insertions(+), 62 deletions(-)

diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h
index 14936f1..62ccb9d 100644
--- a/src/compiler/glsl/ast.h
+++ b/src/compiler/glsl/ast.h
@@ -768,10 +768,18 @@ struct ast_type_qualifier {
                                  _mesa_glsl_parse_state *state,
                                  ast_node* &node, bool create_node);
 
-   bool merge_in_qualifier(YYLTYPE *loc,
-                           _mesa_glsl_parse_state *state,
-                           const ast_type_qualifier &q,
-                           ast_node* &node, bool create_node);
+   /**
+    * Validate current qualifier against the global in one.
+    */
+   bool validate_in_qualifier(YYLTYPE *loc,
+                              _mesa_glsl_parse_state *state);
+
+   /**
+    * Merge current qualifier into the global in one.
+    */
+   bool merge_into_in_qualifier(YYLTYPE *loc,
+                                _mesa_glsl_parse_state *state,
+                                ast_node* &node, bool create_node);
 
    bool validate_flags(YYLTYPE *loc,
                        _mesa_glsl_parse_state *state,
diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp
index b61e1a7..65e4ca6 100644
--- a/src/compiler/glsl/ast_type.cpp
+++ b/src/compiler/glsl/ast_type.cpp
@@ -462,27 +462,25 @@ ast_type_qualifier::merge_into_out_qualifier(YYLTYPE *loc,
    return r;
 }
 
-ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
-                                       _mesa_glsl_parse_state *state,
-                                       const ast_type_qualifier &q,
-                                       ast_node* &node, bool create_node)
+bool
+ast_type_qualifier::validate_in_qualifier(YYLTYPE *loc,
+                                          _mesa_glsl_parse_state *state)
 {
-   void *lin_ctx = state->linalloc;
-   bool create_gs_ast = false;
-   bool create_cs_ast = false;
+   bool r = true;
    ast_type_qualifier valid_in_mask;
    valid_in_mask.flags.i = 0;
 
    switch (state->stage) {
    case MESA_SHADER_TESS_EVAL:
-      if (q.flags.q.prim_type) {
+      if (this->flags.q.prim_type) {
          /* Make sure this is a valid input primitive type. */
-         switch (q.prim_type) {
+         switch (this->prim_type) {
          case GL_TRIANGLES:
          case GL_QUADS:
          case GL_ISOLINES:
             break;
          default:
+            r = false;
             _mesa_glsl_error(loc, state,
                              "invalid tessellation evaluation "
                              "shader input primitive type");
@@ -496,9 +494,9 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
       valid_in_mask.flags.q.point_mode = 1;
       break;
    case MESA_SHADER_GEOMETRY:
-      if (q.flags.q.prim_type) {
+      if (this->flags.q.prim_type) {
          /* Make sure this is a valid input primitive type. */
-         switch (q.prim_type) {
+         switch (this->prim_type) {
          case GL_POINTS:
          case GL_LINES:
          case GL_LINES_ADJACENCY:
@@ -506,16 +504,13 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
          case GL_TRIANGLES_ADJACENCY:
             break;
          default:
+            r = false;
             _mesa_glsl_error(loc, state,
                              "invalid geometry shader input primitive type");
             break;
          }
       }
 
-      create_gs_ast |=
-         q.flags.q.prim_type &&
-         !state->in_qualifier->flags.q.prim_type;
-
       valid_in_mask.flags.q.prim_type = 1;
       valid_in_mask.flags.q.invocations = 1;
       break;
@@ -523,97 +518,121 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
       valid_in_mask.flags.q.early_fragment_tests = 1;
       break;
    case MESA_SHADER_COMPUTE:
-      create_cs_ast |=
-         q.flags.q.local_size != 0 &&
-         state->in_qualifier->flags.q.local_size == 0;
-
       valid_in_mask.flags.q.local_size = 7;
       valid_in_mask.flags.q.local_size_variable = 1;
       break;
    default:
+      r = false;
       _mesa_glsl_error(loc, state,
                        "input layout qualifiers only valid in "
-                       "geometry, fragment and compute shaders");
+                       "geometry, tessellation, fragment and compute shaders");
       break;
    }
 
    /* Generate an error when invalid input layout qualifiers are used. */
-   if ((q.flags.i & ~valid_in_mask.flags.i) != 0) {
+   if ((this->flags.i & ~valid_in_mask.flags.i) != 0) {
+      r = false;
       _mesa_glsl_error(loc, state, "invalid input layout qualifiers used");
-      return false;
+   }
+
+   return r;
+}
+
+bool
+ast_type_qualifier::merge_into_in_qualifier(YYLTYPE *loc,
+                                            _mesa_glsl_parse_state *state,
+                                            ast_node* &node, bool create_node)
+{
+   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.
     */
-   if (this->flags.q.prim_type) {
-      if (q.flags.q.prim_type &&
-          this->prim_type != q.prim_type) {
+   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 (q.flags.q.prim_type) {
+   } else if (this->flags.q.prim_type) {
       state->in_qualifier->flags.q.prim_type = 1;
-      state->in_qualifier->prim_type = q.prim_type;
+      state->in_qualifier->prim_type = this->prim_type;
    }
 
-   if (q.flags.q.invocations) {
-      this->flags.q.invocations = 1;
-      if (this->invocations) {
-         this->invocations->merge_qualifier(q.invocations);
+   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 {
-         this->invocations = q.invocations;
+         state->in_qualifier->invocations = this->invocations;
       }
    }
 
-   if (q.flags.q.early_fragment_tests) {
+   if (this->flags.q.early_fragment_tests) {
       state->fs_early_fragment_tests = true;
    }
 
-   if (this->flags.q.vertex_spacing) {
-      if (q.flags.q.vertex_spacing &&
-          this->vertex_spacing != q.vertex_spacing) {
+   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 (q.flags.q.vertex_spacing) {
-      this->flags.q.vertex_spacing = 1;
-      this->vertex_spacing = q.vertex_spacing;
+   } else if (this->flags.q.vertex_spacing) {
+      state->in_qualifier->flags.q.vertex_spacing = 1;
+      state->in_qualifier->vertex_spacing = this->vertex_spacing;
    }
 
-   if (this->flags.q.ordering) {
-      if (q.flags.q.ordering &&
-          this->ordering != q.ordering) {
+   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 (q.flags.q.ordering) {
-      this->flags.q.ordering = 1;
-      this->ordering = q.ordering;
+   } else if (this->flags.q.ordering) {
+      state->in_qualifier->flags.q.ordering = 1;
+      state->in_qualifier->ordering = this->ordering;
    }
 
-   if (this->flags.q.point_mode) {
-      if (q.flags.q.point_mode &&
-          this->point_mode != q.point_mode) {
+   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 (q.flags.q.point_mode) {
-      this->flags.q.point_mode = 1;
-      this->point_mode = q.point_mode;
+   } else if (this->flags.q.point_mode) {
+      state->in_qualifier->flags.q.point_mode = 1;
+      state->in_qualifier->point_mode = this->point_mode;
    }
 
-   if (q.flags.q.local_size_variable) {
+   if (this->flags.q.local_size_variable) {
       state->cs_input_local_size_variable_specified = true;
    }
 
    if (create_node) {
       if (create_gs_ast) {
-         node = new(lin_ctx) ast_gs_input_layout(*loc, q.prim_type);
+         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, q.local_size);
+         node = new(lin_ctx) ast_cs_input_layout(*loc, this->local_size);
       }
    }
 
diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy
index a96989b..82501af 100644
--- a/src/compiler/glsl/glsl_parser.yy
+++ b/src/compiler/glsl/glsl_parser.yy
@@ -2917,8 +2917,10 @@ layout_in_defaults:
          _mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
          YYERROR;
       } else {
-         if (!state->in_qualifier->
-                merge_in_qualifier(& @1, state, $1, $$, false)) {
+         if (!$1.validate_in_qualifier(& @1, state)) {
+            YYERROR;
+         }
+         if (!$1.merge_into_in_qualifier(& @1, state, $$, false)) {
             YYERROR;
          }
          $$ = $2;
@@ -2927,8 +2929,10 @@ layout_in_defaults:
    | layout_qualifier IN_TOK ';'
    {
       $$ = NULL;
-      if (!state->in_qualifier->
-             merge_in_qualifier(& @1, state, $1, $$, true)) {
+      if (!$1.validate_in_qualifier(& @1, state)) {
+         YYERROR;
+      }
+      if (!$1.merge_into_in_qualifier(& @1, state, $$, true)) {
          YYERROR;
       }
    }




More information about the mesa-commit mailing list