aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <[email protected]>2015-05-13 10:53:46 +0200
committerSamuel Iglesias Gonsalvez <[email protected]>2015-07-14 07:04:03 +0200
commit84fc5fece006f2bd95287496e32482ac08bfd399 (patch)
treefef204c39afaf42c877a8afbb333e98577ce63ac
parent6b09598d63b8b6069b230fbe8283c75cf86f711a (diff)
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 <[email protected]>
-rw-r--r--src/glsl/ast.h1
-rw-r--r--src/glsl/ast_to_hir.cpp14
-rw-r--r--src/glsl/ast_type.cpp3
-rw-r--r--src/glsl/glsl_lexer.ll1
-rw-r--r--src/glsl/glsl_parser.yy30
-rw-r--r--src/glsl/glsl_parser_extras.cpp2
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)