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

Andres Gomez agomez at igalia.com
Mon Nov 14 17:15:06 UTC 2016


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.
+    */
+
+   /* 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;
+      _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;
 }
 
 /**
-- 
2.9.3



More information about the mesa-dev mailing list