[Mesa-dev] [PATCH v5 23/70] glsl: refactor parser processing of an interface block definition
Samuel Iglesias Gonsálvez
siglesias at igalia.com
Mon Sep 21 03:02:51 PDT 2015
On 19/09/15 01:44, Kristian Høgsberg wrote:
> On Thu, Sep 10, 2015 at 03:35:39PM +0200, Iago Toral Quiroga wrote:
>> From: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
>
> I'd be more specific in the subject and say:
>
> 'glsl: Move interface block processing to glsl_parser_extras.cpp
>
> 'Refactor' can mean many different things. Maybe even clarify in the
> commit message that there are no other changes.
>
OK, I am going to update it.
Thanks,
Sam
>> ---
>> src/glsl/ast.h | 5 ++
>> src/glsl/glsl_parser.yy | 127 +---------------------------------------
>> src/glsl/glsl_parser_extras.cpp | 122 ++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 128 insertions(+), 126 deletions(-)
>>
>> diff --git a/src/glsl/ast.h b/src/glsl/ast.h
>> index 335f426..cca32b3 100644
>> --- a/src/glsl/ast.h
>> +++ b/src/glsl/ast.h
>> @@ -1172,4 +1172,9 @@ extern void
>> check_builtin_array_max_size(const char *name, unsigned size,
>> YYLTYPE loc, struct _mesa_glsl_parse_state *state);
>>
>> +extern void _mesa_ast_process_interface_block(YYLTYPE *locp,
>> + _mesa_glsl_parse_state *state,
>> + ast_interface_block *const block,
>> + const struct ast_type_qualifier q);
>> +
>> #endif /* AST_H */
>> diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
>> index 42108a3..7f00929 100644
>> --- a/src/glsl/glsl_parser.yy
>> +++ b/src/glsl/glsl_parser.yy
>> @@ -2634,132 +2634,7 @@ basic_interface_block:
>> block->block_name = $2;
>> block->declarations.push_degenerate_list_at_head(& $4->link);
>>
>> - if ($1.flags.q.buffer) {
>> - if (!state->has_shader_storage_buffer_objects()) {
>> - _mesa_glsl_error(& @1, state,
>> - "#version 430 / GL_ARB_shader_storage_buffer_object "
>> - "required for defining shader storage blocks");
>> - } else if (state->ARB_shader_storage_buffer_object_warn) {
>> - _mesa_glsl_warning(& @1, state,
>> - "#version 430 / GL_ARB_shader_storage_buffer_object "
>> - "required for defining shader storage blocks");
>> - }
>> - } else if ($1.flags.q.uniform) {
>> - if (!state->has_uniform_buffer_objects()) {
>> - _mesa_glsl_error(& @1, state,
>> - "#version 140 / GL_ARB_uniform_buffer_object "
>> - "required for defining uniform blocks");
>> - } else if (state->ARB_uniform_buffer_object_warn) {
>> - _mesa_glsl_warning(& @1, state,
>> - "#version 140 / GL_ARB_uniform_buffer_object "
>> - "required for defining uniform blocks");
>> - }
>> - } else {
>> - if (state->es_shader || state->language_version < 150) {
>> - _mesa_glsl_error(& @1, state,
>> - "#version 150 required for using "
>> - "interface blocks");
>> - }
>> - }
>> -
>> - /* From the GLSL 1.50.11 spec, section 4.3.7 ("Interface Blocks"):
>> - * "It is illegal to have an input block in a vertex shader
>> - * or an output block in a fragment shader"
>> - */
>> - if ((state->stage == MESA_SHADER_VERTEX) && $1.flags.q.in) {
>> - _mesa_glsl_error(& @1, state,
>> - "`in' interface block is not allowed for "
>> - "a vertex shader");
>> - } else if ((state->stage == MESA_SHADER_FRAGMENT) && $1.flags.q.out) {
>> - _mesa_glsl_error(& @1, state,
>> - "`out' interface block is not allowed for "
>> - "a fragment shader");
>> - }
>> -
>> - /* Since block arrays require names, and both features are added in
>> - * the same language versions, we don't have to explicitly
>> - * version-check both things.
>> - */
>> - if (block->instance_name != NULL) {
>> - state->check_version(150, 300, & @1, "interface blocks with "
>> - "an instance name are not allowed");
>> - }
>> -
>> - uint64_t interface_type_mask;
>> - struct ast_type_qualifier temp_type_qualifier;
>> -
>> - /* Get a bitmask containing only the in/out/uniform/buffer
>> - * 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.buffer = 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).
>> - */
>> - uint64_t block_interface_qualifier = $1.flags.i;
>> -
>> - block->layout.flags.i |= block_interface_qualifier;
>> -
>> - if (state->stage == MESA_SHADER_GEOMETRY &&
>> - state->has_explicit_attrib_stream()) {
>> - /* Assign global layout's stream value. */
>> - block->layout.flags.q.stream = 1;
>> - block->layout.flags.q.explicit_stream = 0;
>> - block->layout.stream = state->out_qualifier->stream;
>> - }
>> -
>> - 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");
>> - }
>> -
>> - /* From GLSL ES 3.0, chapter 4.3.7 "Interface Blocks":
>> - *
>> - * "GLSL ES 3.0 does not support interface blocks for shader inputs or
>> - * outputs."
>> - *
>> - * And from GLSL ES 3.0, chapter 4.6.1 "The invariant qualifier":.
>> - *
>> - * "Only variables output from a shader can be candidates for
>> - * invariance."
>> - *
>> - * From GLSL 4.40 and GLSL 1.50, section "Interface Blocks":
>> - *
>> - * "If optional qualifiers are used, they can include interpolation
>> - * qualifiers, auxiliary storage qualifiers, and storage qualifiers
>> - * and they must declare an input, output, or uniform member
>> - * consistent with the interface qualifier of the block"
>> - */
>> - if (qualifier.flags.q.invariant)
>> - _mesa_glsl_error(&@1, state,
>> - "invariant qualifiers cannot be used "
>> - "with interface blocks members");
>> - }
>> + _mesa_ast_process_interface_block(& @1, state, block, $1);
>>
>> $$ = block;
>> }
>> diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
>> index 20bbe6e..0a3f745 100644
>> --- a/src/glsl/glsl_parser_extras.cpp
>> +++ b/src/glsl/glsl_parser_extras.cpp
>> @@ -858,6 +858,128 @@ _mesa_ast_set_aggregate_type(const glsl_type *type,
>> }
>> }
>>
>> +void
>> +_mesa_ast_process_interface_block(YYLTYPE *locp,
>> + _mesa_glsl_parse_state *state,
>> + ast_interface_block *const block,
>> + const struct ast_type_qualifier q)
>> +{
>> + if (q.flags.q.uniform) {
>> + if (!state->has_uniform_buffer_objects()) {
>> + _mesa_glsl_error(locp, state,
>> + "#version 140 / GL_ARB_uniform_buffer_object "
>> + "required for defining uniform blocks");
>> + } else if (state->ARB_uniform_buffer_object_warn) {
>> + _mesa_glsl_warning(locp, state,
>> + "#version 140 / GL_ARB_uniform_buffer_object "
>> + "required for defining uniform blocks");
>> + }
>> + } else {
>> + if (state->es_shader || state->language_version < 150) {
>> + _mesa_glsl_error(locp, state,
>> + "#version 150 required for using "
>> + "interface blocks");
>> + }
>> + }
>> +
>> + /* From the GLSL 1.50.11 spec, section 4.3.7 ("Interface Blocks"):
>> + * "It is illegal to have an input block in a vertex shader
>> + * or an output block in a fragment shader"
>> + */
>> + if ((state->stage == MESA_SHADER_VERTEX) && q.flags.q.in) {
>> + _mesa_glsl_error(locp, state,
>> + "`in' interface block is not allowed for "
>> + "a vertex shader");
>> + } else if ((state->stage == MESA_SHADER_FRAGMENT) && q.flags.q.out) {
>> + _mesa_glsl_error(locp, state,
>> + "`out' interface block is not allowed for "
>> + "a fragment shader");
>> + }
>> +
>> + /* Since block arrays require names, and both features are added in
>> + * the same language versions, we don't have to explicitly
>> + * version-check both things.
>> + */
>> + if (block->instance_name != NULL) {
>> + state->check_version(150, 300, locp, "interface blocks with "
>> + "an instance name are not allowed");
>> + }
>> +
>> + uint64_t 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).
>> + */
>> + uint64_t block_interface_qualifier = q.flags.i;
>> +
>> + block->layout.flags.i |= block_interface_qualifier;
>> +
>> + if (state->stage == MESA_SHADER_GEOMETRY &&
>> + state->has_explicit_attrib_stream()) {
>> + /* Assign global layout's stream value. */
>> + block->layout.flags.q.stream = 1;
>> + block->layout.flags.q.explicit_stream = 0;
>> + block->layout.stream = state->out_qualifier->stream;
>> + }
>> +
>> + 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(locp, state,
>> + "uniform/in/out qualifier on "
>> + "interface block member does not match "
>> + "the interface block");
>> + }
>> +
>> + /* From GLSL ES 3.0, chapter 4.3.7 "Interface Blocks":
>> + *
>> + * "GLSL ES 3.0 does not support interface blocks for shader inputs or
>> + * outputs."
>> + *
>> + * And from GLSL ES 3.0, chapter 4.6.1 "The invariant qualifier":.
>> + *
>> + * "Only variables output from a shader can be candidates for
>> + * invariance."
>> + *
>> + * From GLSL 4.40 and GLSL 1.50, section "Interface Blocks":
>> + *
>> + * "If optional qualifiers are used, they can include interpolation
>> + * qualifiers, auxiliary storage qualifiers, and storage qualifiers
>> + * and they must declare an input, output, or uniform member
>> + * consistent with the interface qualifier of the block"
>> + */
>> + if (qualifier.flags.q.invariant)
>> + _mesa_glsl_error(locp, state,
>> + "invariant qualifiers cannot be used "
>> + "with interface blocks members");
>> + }
>> +}
>>
>> void
>> _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
>> --
>> 1.9.1
>>
>
More information about the mesa-dev
mailing list