glsl: allow default qualifiers for shader storage block definitions
authorSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Thu, 3 Sep 2015 10:00:16 +0000 (12:00 +0200)
committerSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Fri, 25 Sep 2015 06:39:21 +0000 (08:39 +0200)
This kind of definitions:

    layout(xxx) buffer;

was not supported by commit 84fc5fece006.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
src/glsl/glsl_parser.yy
src/glsl/glsl_parser_extras.cpp
src/glsl/glsl_parser_extras.h

index 7f00929d1e4a20dcd1b9bc535be60e0020600c42..028974e7eb9614174bc829081ec79eeaa348a98e 100644 (file)
@@ -169,6 +169,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
 %token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
 %type <identifier> any_identifier
 %type <interface_block> instance_name_opt
+%type <interface_block> buffer_instance_name_opt
 %token <real> FLOATCONSTANT
 %token <dreal> DOUBLECONSTANT
 %token <n> INTCONSTANT UINTCONSTANT BOOLCONSTANT
@@ -218,6 +219,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
 %type <type_qualifier> subroutine_qualifier
 %type <subroutine_list> subroutine_type_list
 %type <type_qualifier> interface_qualifier
+%type <type_qualifier> buffer_interface_qualifier
 %type <type_specifier> type_specifier
 %type <type_specifier> type_specifier_nonarray
 %type <array_specifier> array_specifier
@@ -2638,6 +2640,17 @@ basic_interface_block:
 
       $$ = block;
    }
+   | buffer_interface_qualifier NEW_IDENTIFIER '{' member_list '}' buffer_instance_name_opt ';'
+   {
+      ast_interface_block *const block = $6;
+
+      block->block_name = $2;
+      block->declarations.push_degenerate_list_at_head(& $4->link);
+
+      _mesa_ast_process_interface_block(& @1, state, block, $1);
+
+      $$ = block;
+   }
    ;
 
 interface_qualifier:
@@ -2656,7 +2669,10 @@ interface_qualifier:
       memset(& $$, 0, sizeof($$));
       $$.flags.q.uniform = 1;
    }
-   | BUFFER
+   ;
+
+buffer_interface_qualifier:
+   BUFFER
    {
       memset(& $$, 0, sizeof($$));
       $$.flags.q.buffer = 1;
@@ -2683,6 +2699,26 @@ instance_name_opt:
    }
    ;
 
+buffer_instance_name_opt:
+   /* empty */
+   {
+      $$ = new(state) ast_interface_block(*state->default_shader_storage_qualifier,
+                                          NULL, NULL);
+   }
+   | NEW_IDENTIFIER
+   {
+      $$ = new(state) ast_interface_block(*state->default_shader_storage_qualifier,
+                                          $1, NULL);
+      $$->set_location(@1);
+   }
+   | NEW_IDENTIFIER array_specifier
+   {
+      $$ = new(state) ast_interface_block(*state->default_shader_storage_qualifier,
+                                          $1, $2);
+      $$->set_location_range(@1, @2);
+   }
+   ;
+
 member_list:
    member_declaration
    {
@@ -2729,6 +2765,14 @@ layout_defaults:
       $$ = NULL;
    }
 
+   | layout_qualifier BUFFER ';'
+   {
+      if (!state->default_shader_storage_qualifier->merge_qualifier(& @1, state, $1)) {
+         YYERROR;
+      }
+      $$ = NULL;
+   }
+
    | layout_qualifier IN_TOK ';'
    {
       $$ = NULL;
index 67ef014c06874660584951cb24f6df0db8e315e7..223596be79880672109f3ea5a22fa4d31d4e90d8 100644 (file)
@@ -244,6 +244,11 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
    this->default_uniform_qualifier->flags.q.column_major = 1;
    this->default_uniform_qualifier->is_default_qualifier = true;
 
+   this->default_shader_storage_qualifier = new(this) ast_type_qualifier();
+   this->default_shader_storage_qualifier->flags.q.shared = 1;
+   this->default_shader_storage_qualifier->flags.q.column_major = 1;
+   this->default_shader_storage_qualifier->is_default_qualifier = true;
+
    this->fs_uses_gl_fragcoord = false;
    this->fs_redeclares_gl_fragcoord = false;
    this->fs_origin_upper_left = false;
@@ -865,7 +870,17 @@ _mesa_ast_process_interface_block(YYLTYPE *locp,
                                   ast_interface_block *const block,
                                   const struct ast_type_qualifier q)
 {
-   if (q.flags.q.uniform) {
+   if (q.flags.q.buffer) {
+      if (!state->has_shader_storage_buffer_objects()) {
+         _mesa_glsl_error(locp, 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(locp, state,
+                            "#version 430 / GL_ARB_shader_storage_buffer_object "
+                            "required for defining shader storage blocks");
+      }
+   } else if (q.flags.q.uniform) {
       if (!state->has_uniform_buffer_objects()) {
          _mesa_glsl_error(locp, state,
                           "#version 140 / GL_ARB_uniform_buffer_object "
@@ -909,7 +924,7 @@ _mesa_ast_process_interface_block(YYLTYPE *locp,
    uint64_t interface_type_mask;
    struct ast_type_qualifier temp_type_qualifier;
 
-   /* Get a bitmask containing only the in/out/uniform
+   /* Get a bitmask containing only the in/out/uniform/buffer
     * flags, allowing us to ignore other irrelevant flags like
     * interpolation qualifiers.
     */
@@ -917,6 +932,7 @@ _mesa_ast_process_interface_block(YYLTYPE *locp,
    temp_type_qualifier.flags.q.uniform = true;
    temp_type_qualifier.flags.q.in = true;
    temp_type_qualifier.flags.q.out = true;
+   temp_type_qualifier.flags.q.buffer = true;
    interface_type_mask = temp_type_qualifier.flags.i;
 
    /* Get the block's interface qualifier.  The interface_qualifier
index d3b091d9dce6cd7f45b92a526d30c9f17dd7d59a..5b757d3716fe394b659394e627925d05319d751d 100644 (file)
@@ -274,6 +274,13 @@ struct _mesa_glsl_parse_state {
     */
    struct ast_type_qualifier *default_uniform_qualifier;
 
+   /**
+    * Default shader storage layout qualifiers tracked during parsing.
+    * Currently affects shader storage blocks and shader storage buffer
+    * variables in those blocks.
+    */
+   struct ast_type_qualifier *default_shader_storage_qualifier;
+
    /**
     * Variables to track different cases if a fragment shader redeclares
     * built-in variable gl_FragCoord.