From 02dc74fbd72d82a21506a5984a92e5db08fcfc5c Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Sun, 2 Feb 2014 17:55:36 -0800 Subject: [PATCH] glsl: parse invocations layout qualifier for ARB_gpu_shader5 _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 Reviewed-by: Anuj Phogat --- src/glsl/ast.h | 8 ++++++++ src/glsl/ast_type.cpp | 12 ++++++++++++ src/glsl/glsl_parser.yy | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/src/glsl/ast.h b/src/glsl/ast.h index c4f28b0cc90..2d7333f30f0 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -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 * diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp index eba577764b0..0ee2c495aa4 100644 --- a/src/glsl/ast_type.cpp +++ b/src/glsl/ast_type.cpp @@ -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) { diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index c3fa4555e14..1df5722548d 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -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. */ -- 2.30.2