From 84fc5fece006f2bd95287496e32482ac08bfd399 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 13 May 2015 10:53:46 +0200 Subject: [PATCH] glsl: Implement parser support for 'buffer' qualifier This is used to identify shader storage buffer interface blocks where buffer variables are declared. Reviewed-by: Jordan Justen --- src/glsl/ast.h | 1 + src/glsl/ast_to_hir.cpp | 14 ++++++++++---- src/glsl/ast_type.cpp | 3 ++- src/glsl/glsl_lexer.ll | 1 + src/glsl/glsl_parser.yy | 30 ++++++++++++++++++++++++++---- src/glsl/glsl_parser_extras.cpp | 2 ++ 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/glsl/ast.h b/src/glsl/ast.h index ef74e5137b2..49212298e16 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -435,6 +435,7 @@ struct ast_type_qualifier { unsigned centroid:1; unsigned sample:1; unsigned uniform:1; + unsigned buffer:1; unsigned smooth:1; unsigned flat:1; unsigned noperspective:1; diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 00f35eb29df..f9f1c083f72 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2501,6 +2501,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, var->data.mode = ir_var_shader_out; else if (qual->flags.q.uniform) var->data.mode = ir_var_uniform; + else if (qual->flags.q.buffer) + var->data.mode = ir_var_shader_storage; if (!is_parameter && is_varying_var(var, state->stage)) { /* User-defined ins/outs are not permitted in compute shaders. */ @@ -5265,8 +5267,9 @@ ast_type_specifier::hir(exec_list *instructions, * \c glsl_struct_field to describe the members. * * If we're processing an interface block, var_mode should be the type of the - * interface block (ir_var_shader_in, ir_var_shader_out, or ir_var_uniform). - * If we're processing a structure, var_mode should be ir_var_auto. + * interface block (ir_var_shader_in, ir_var_shader_out, ir_var_uniform or + * ir_var_shader_storage). If we're processing a structure, var_mode should be + * ir_var_auto. * * \return * The number of fields processed. A pointer to the array structure fields is @@ -5396,10 +5399,10 @@ ast_process_structure_or_interface_block(exec_list *instructions, fields[i].stream = qual->flags.q.explicit_stream ? qual->stream : -1; if (qual->flags.q.row_major || qual->flags.q.column_major) { - if (!qual->flags.q.uniform) { + if (!qual->flags.q.uniform && !qual->flags.q.buffer) { _mesa_glsl_error(&loc, state, "row_major and column_major can only be " - "applied to uniform interface blocks"); + "applied to interface blocks"); } else validate_matrix_layout_for_type(state, &loc, field_type, NULL); } @@ -5596,6 +5599,9 @@ ast_interface_block::hir(exec_list *instructions, } else if (this->layout.flags.q.uniform) { var_mode = ir_var_uniform; iface_type_name = "uniform"; + } else if (this->layout.flags.q.buffer) { + var_mode = ir_var_shader_storage; + iface_type_name = "buffer"; } else { var_mode = ir_var_auto; iface_type_name = "UNKNOWN"; diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp index 1bcf6a2e81f..fa4806af1c0 100644 --- a/src/glsl/ast_type.cpp +++ b/src/glsl/ast_type.cpp @@ -78,7 +78,8 @@ ast_type_qualifier::has_storage() const || this->flags.q.varying || this->flags.q.in || this->flags.q.out - || this->flags.q.uniform; + || this->flags.q.uniform + || this->flags.q.buffer; } bool diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll index 10db5b8b632..845deebcd6f 100644 --- a/src/glsl/glsl_lexer.ll +++ b/src/glsl/glsl_lexer.ll @@ -308,6 +308,7 @@ in return IN_TOK; out return OUT_TOK; inout return INOUT_TOK; uniform return UNIFORM; +buffer return BUFFER; varying DEPRECATED_ES_KEYWORD(VARYING); centroid KEYWORD(120, 300, 120, 300, CENTROID); invariant KEYWORD(120, 100, 120, 100, INVARIANT); diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index 3ce9e103f20..8564cb99374 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -134,7 +134,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, } %token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK DOUBLE_TOK -%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token BREAK BUFFER CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT %token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 DVEC2 DVEC3 DVEC4 %token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING SAMPLE %token NOPERSPECTIVE FLAT SMOOTH @@ -1805,6 +1805,11 @@ storage_qualifier: memset(& $$, 0, sizeof($$)); $$.flags.q.uniform = 1; } + | BUFFER + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.buffer = 1; + } ; memory_qualifier: @@ -2507,7 +2512,17 @@ basic_interface_block: block->block_name = $2; block->declarations.push_degenerate_list_at_head(& $4->link); - if ($1.flags.q.uniform) { + 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 " @@ -2551,11 +2566,13 @@ basic_interface_block: 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. + /* 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; @@ -2642,6 +2659,11 @@ interface_qualifier: memset(& $$, 0, sizeof($$)); $$.flags.q.uniform = 1; } + | BUFFER + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.buffer = 1; + } ; instance_name_opt: diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 0d7e5215672..5412f0b7887 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -854,6 +854,8 @@ _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) printf("sample "); if (q->flags.q.uniform) printf("uniform "); + if (q->flags.q.buffer) + printf("buffer "); if (q->flags.q.smooth) printf("smooth "); if (q->flags.q.flat) -- 2.30.2