summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorJordan Justen <[email protected]>2013-03-21 10:52:19 -0700
committerJordan Justen <[email protected]>2013-05-23 09:37:11 -0700
commit4410eba598d574200764d3b0303178d6dd8a93a9 (patch)
tree0a5faccfb1bc96bc089be8b7e1a5195ca52b874f /src/glsl
parent4369acff5e96782a64adc9c1fc81d63fb07f33f4 (diff)
glsl parser: handle interface block member qualifier
An interface block member may specify the type: in { in vec4 in_var_with_qualifier; }; When specified with the member, it must match the same type as interface block type. It can also omit the qualifier: uniform { vec4 uniform_var_without_qualifier; }; When the type is not specified with the member, it will adopt the same type as the interface block. Signed-off-by: Jordan Justen <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/glsl_parser.yy44
1 files changed, 43 insertions, 1 deletions
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 70764d6dbf3..baac84568ca 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -1958,7 +1958,49 @@ basic_interface_block:
"an instance name are not allowed");
}
- block->layout.flags.i |= $1.flags.i;
+ unsigned interface_type_mask;
+ struct ast_type_qualifier temp_type_qualifier;
+
+ /* Get a bitmask containing only the in/out/uniform flags, allowing us
+ * to ignore other irrelevant flags like interpolation qualifiers.
+ */
+ temp_type_qualifier.flags.i = 0;
+ temp_type_qualifier.flags.q.uniform = true;
+ temp_type_qualifier.flags.q.in = true;
+ temp_type_qualifier.flags.q.out = true;
+ interface_type_mask = temp_type_qualifier.flags.i;
+
+ /* Get the block's interface qualifier. The interface_qualifier
+ * production rule guarantees that only one bit will be set (and
+ * it will be in/out/uniform).
+ */
+ unsigned block_interface_qualifier = $1.flags.i;
+
+ block->layout.flags.i |= block_interface_qualifier;
+
+ foreach_list_typed (ast_declarator_list, member, link, &block->declarations) {
+ ast_type_qualifier& qualifier = member->type->qualifier;
+ if ((qualifier.flags.i & interface_type_mask) == 0) {
+ /* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks):
+ * "If no optional qualifier is used in a member declaration, the
+ * qualifier of the variable is just in, out, or uniform as declared
+ * by interface-qualifier."
+ */
+ qualifier.flags.i |= block_interface_qualifier;
+ } else if ((qualifier.flags.i & interface_type_mask) !=
+ block_interface_qualifier) {
+ /* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks):
+ * "If optional qualifiers are used, they can include interpolation
+ * and storage qualifiers and they must declare an input, output,
+ * or uniform variable consistent with the interface qualifier of
+ * the block."
+ */
+ _mesa_glsl_error(& @1, state,
+ "uniform/in/out qualifier on "
+ "interface block member does not match "
+ "the interface block\n");
+ }
+ }
$$ = block;
}