glsl: parse invocations layout qualifier for ARB_gpu_shader5
authorJordan Justen <jordan.l.justen@intel.com>
Mon, 3 Feb 2014 01:55:36 +0000 (17:55 -0800)
committerJordan Justen <jordan.l.justen@intel.com>
Thu, 20 Feb 2014 18:33:08 +0000 (10:33 -0800)
_mesa_glsl_parse_state in_qualifier->invocations will store the
invocations count.

v3:
 * Use in_qualifier to allow the primitive to be specied
   separately from the invocations count (merge_qualifiers)

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
src/glsl/ast.h
src/glsl/ast_type.cpp
src/glsl/glsl_parser.yy

index c4f28b0cc90f7223149c78f501961246a843978e..2d7333f30f04d036cf4e58c71cb709c69024f22a 100644 (file)
@@ -477,6 +477,11 @@ struct ast_type_qualifier {
         unsigned read_only:1; /**< "readonly" qualifier. */
         unsigned write_only:1; /**< "writeonly" qualifier. */
         /** \} */
+
+         /** \name Layout qualifiers for GL_ARB_gpu_shader5 */
+         /** \{ */
+         unsigned invocations:1;
+         /** \} */
       }
       /** \brief Set of flags, accessed by name. */
       q;
@@ -488,6 +493,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
     *
index eba577764b0669810ee538fae6dc55a5adb2093f..0ee2c495aa4fa4f5f8a45badfa9df3cfb96c0991 100644 (file)
@@ -233,6 +233,7 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
          !state->in_qualifier->flags.q.prim_type;
 
       valid_in_mask.flags.q.prim_type = 1;
+      valid_in_mask.flags.q.invocations = 1;
       break;
    case MESA_SHADER_FRAGMENT:
       if (q.flags.q.early_fragment_tests) {
@@ -276,6 +277,17 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
       state->in_qualifier->prim_type = q.prim_type;
    }
 
+   if (this->flags.q.invocations &&
+       q.flags.q.invocations &&
+       this->invocations != q.invocations) {
+      _mesa_glsl_error(loc, state,
+                       "conflicting invocations counts specified");
+      return false;
+   } else if (q.flags.q.invocations) {
+      this->flags.q.invocations = 1;
+      this->invocations = q.invocations;
+   }
+
    if (create_gs_ast) {
       node = new(mem_ctx) ast_gs_input_layout(*loc, q.prim_type);
    } else if (create_cs_ast) {
index c3fa4555e14c92de5b5abc5d15b91f335e86a754..1df5722548df78c9fcb806d0c8c4d6ffa6d26298 100644 (file)
@@ -1387,6 +1387,29 @@ 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 if ($3 > MAX_GEOMETRY_SHADER_INVOCATIONS) {
+            _mesa_glsl_error(& @3, state,
+                             "invocations (%d) exceeds "
+                             "GL_MAX_GEOMETRY_SHADER_INVOCATIONS", $3);
+            YYERROR;
+         } else {
+            $$.invocations = $3;
+            if (!state->is_version(400, 0) &&
+                !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.
        */