[Mesa-dev] [PATCH v2 1/7] glsl: parse invocations layout qualifier for ARB_gpu_shader5

Jordan Justen jordan.l.justen at intel.com
Tue Jan 28 11:22:20 PST 2014


_mesa_glsl_parse_state::gs_invocations will store the
invocation count.

Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
---
 src/glsl/ast.h                | 15 +++++++++++++--
 src/glsl/ast_to_hir.cpp       | 14 ++++++++++++++
 src/glsl/ast_type.cpp         | 11 +++++++++++
 src/glsl/glsl_parser.yy       | 19 ++++++++++++++++++-
 src/glsl/glsl_parser_extras.h |  3 +++
 5 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 0bda28d..abe9190 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -460,6 +460,11 @@ struct ast_type_qualifier {
 	 unsigned prim_type:1;
 	 unsigned max_vertices:1;
 	 /** \} */
+
+         /** \name Layout qualifiers for GL_ARB_gpu_shader5 */
+         /** \{ */
+         unsigned invocations:1;
+         /** \} */
       }
       /** \brief Set of flags, accessed by name. */
       q;
@@ -471,6 +476,9 @@ struct ast_type_qualifier {
    /** Precision of the type (highp/medium/lowp). */
    unsigned precision:2;
 
+   /** Geometry shader invocations for GL_ARB_gpu_shader5. */
+   int invocations;
+
    /**
     * Location specified via GL_ARB_explicit_attrib_location layout
     *
@@ -977,8 +985,8 @@ public:
 class ast_gs_input_layout : public ast_node
 {
 public:
-   ast_gs_input_layout(const struct YYLTYPE &locp, GLenum prim_type)
-      : prim_type(prim_type)
+   ast_gs_input_layout(const struct YYLTYPE &locp, const ast_type_qualifier &qual)
+      : prim_type(qual.prim_type), invocations(qual.invocations)
    {
       set_location(locp);
    }
@@ -988,6 +996,9 @@ public:
 
 private:
    const GLenum prim_type;
+
+   /** Geometry shader invocations for GL_ARB_gpu_shader5. */
+   int invocations;
 };
 
 /*@}*/
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 1bfb4e5..45b1efd 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -5256,8 +5256,22 @@ ast_gs_input_layout::hir(exec_list *instructions,
       return NULL;
    }
 
+   /* Make sure all shader inputs specify the same number of invocations.
+    */
+   if ((state->gs_invocations != 0 && this->invocations != 0) &&
+       state->gs_invocations != this->invocations) {
+      _mesa_glsl_error(&loc, state,
+                       "different geometry shader invocation counts were"
+                       " specified (%d and %d)",
+                       state->gs_invocations, this->invocations
+                       );
+      return NULL;
+   }
+
    state->gs_input_prim_type_specified = true;
    state->gs_input_prim_type = this->prim_type;
+   if (this->invocations != 0)
+      state->gs_invocations = this->invocations;
 
    /* If any shader inputs occurred before this declaration and did not
     * specify an array size, their size is determined now.
diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp
index 637da0d..30213af 100644
--- a/src/glsl/ast_type.cpp
+++ b/src/glsl/ast_type.cpp
@@ -153,6 +153,17 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
       this->max_vertices = q.max_vertices;
    }
 
+   if (q.flags.q.invocations) {
+      if (this->flags.q.invocations && this->invocations != q.invocations) {
+	 _mesa_glsl_error(loc, state,
+			  "geometry shader set conflicting invocations "
+			  "(%d and %d)", this->invocations, q.invocations);
+	 return false;
+      }
+      this->invocations = q.invocations;
+      this->flags.q.invocations = 1;
+   }
+
    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)
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 928c57e..66fb3c3 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -1291,6 +1291,23 @@ layout_qualifier_id:
          }
       }
 
+      if (match_layout_qualifier("invocations", $1, state) == 0) {
+         $$.flags.q.invocations = 1;
+
+         if ($3 < 0) {
+            _mesa_glsl_error(& @3, state,
+                             "invalid invocations %d specified", $3);
+            YYERROR;
+         } else {
+            $$.invocations = $3;
+            if (!state->ARB_gpu_shader5_enable) {
+               _mesa_glsl_error(& @3, state,
+                                "GL_ARB_gpu_shader5 invocations "
+                                "qualifier specified", $3);
+            }
+         }
+      }
+
       /* If the identifier didn't match any known layout identifiers,
        * emit an error.
        */
@@ -2350,7 +2367,7 @@ layout_defaults:
          case GL_LINES_ADJACENCY:
          case GL_TRIANGLES:
          case GL_TRIANGLES_ADJACENCY:
-            $$ = new(ctx) ast_gs_input_layout(@1, $1.prim_type);
+            $$ = new(ctx) ast_gs_input_layout(@1, $1);
             break;
          default:
             _mesa_glsl_error(&@1, state,
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 8a4cbf1..f35df27 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -196,6 +196,9 @@ struct _mesa_glsl_parse_state {
     */
    GLenum gs_input_prim_type;
 
+   /** Geometry shader invocations for GL_ARB_gpu_shader5. */
+   int gs_invocations;
+
    /** Output layout qualifiers from GLSL 1.50. (geometry shader controls)*/
    struct ast_type_qualifier *out_qualifier;
 
-- 
1.8.5.3



More information about the mesa-dev mailing list