[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