[Mesa-dev] [PATCH v3 3/9] glsl: parse invocations layout qualifier for ARB_gpu_shader5
Jordan Justen
jordan.l.justen at intel.com
Wed Feb 5 00:07:24 CET 2014
_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 at 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
More information about the mesa-dev
mailing list