From 4410eba598d574200764d3b0303178d6dd8a93a9 Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Thu, 21 Mar 2013 10:52:19 -0700 Subject: 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 Reviewed-by: Kenneth Graunke --- src/glsl/glsl_parser.yy | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'src') 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; } -- cgit v1.2.3