summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Justen <[email protected]>2014-02-02 17:55:36 -0800
committerJordan Justen <[email protected]>2014-02-20 10:33:08 -0800
commit02dc74fbd72d82a21506a5984a92e5db08fcfc5c (patch)
tree2a8ea357a78c1c0b2293558390475462f926cb98
parent738c9c3c543b985b025a4a60fcc9c2e212e2d821 (diff)
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 <[email protected]> Reviewed-by: Anuj Phogat <[email protected]>
-rw-r--r--src/glsl/ast.h8
-rw-r--r--src/glsl/ast_type.cpp12
-rw-r--r--src/glsl/glsl_parser.yy23
3 files changed, 43 insertions, 0 deletions
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.
*/