_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.jus...@intel.com> --- src/glsl/ast.h | 8 ++++++++ src/glsl/ast_type.cpp | 23 +++++++++++++++++++++++ src/glsl/glsl_parser.yy | 27 +++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/glsl/ast.h b/src/glsl/ast.h index e74d8a3..b3721c0 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 * diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp index f1c59da..fe15159 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) @@ -186,6 +197,7 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc, ast_type_qualifier valid_in_mask; valid_in_mask.flags.i = 0; valid_in_mask.flags.q.prim_type = 1; + valid_in_mask.flags.q.invocations = 1; /* Generate an error when invalid input layout qualifiers are used. */ if ((q.flags.i & ~valid_in_mask.flags.i) != 0) { @@ -222,5 +234,16 @@ 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; + } + return true; } diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index e368217..66ad47f 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -1291,6 +1291,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. */ @@ -2338,10 +2361,6 @@ layout_defaults: _mesa_glsl_error(& @1, state, "input layout qualifiers only valid in " "geometry shaders"); - } else if (!$1.flags.q.prim_type) { - _mesa_glsl_error(& @1, state, - "input layout qualifiers must specify a primitive" - " type"); } else { bool first_prim = $1.flags.q.prim_type && !state->in_qualifier->flags.q.prim_type; -- 1.8.5.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev