summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2015-11-13 18:47:55 +1100
committerTimothy Arceri <[email protected]>2015-11-21 07:27:15 +1100
commit17e224e8ec9c190fb856a60a22d8e19b8f20837e (patch)
treea9df2a3b975c1dbeef0428a32a7b6dfe7d852fdf /src
parentefa34e4a1d09c6f140fba7ff339a989ea079e212 (diff)
glsl: move stream layout qualifier validation
We are moving this out of the parser in preparation for compile time constant support. The reason a validation function is used rather than an apply function like what is used with bindings is because glsl allows streams to be defined on members of blocks even though they must match the stream thats associated with the current block, this means we need access to the value after validation to do this comparision. V2: Fix typo in comment (Emil) Reviewed-by: Samuel Iglesias Gonsálvez <[email protected]> Reviewed-by: Emil Velikov <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/glsl/ast_to_hir.cpp44
-rw-r--r--src/glsl/glsl_parser.yy11
2 files changed, 35 insertions, 20 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index fde3df5d9b6..7104aa0a633 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -3034,7 +3034,11 @@ apply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual,
if (state->stage == MESA_SHADER_GEOMETRY &&
qual->flags.q.out && qual->flags.q.stream) {
- var->data.stream = qual->stream;
+ unsigned qual_stream;
+ if (process_qualifier_constant(state, loc, "stream", qual->stream,
+ &qual_stream)) {
+ var->data.stream = qual_stream;
+ }
}
if (var->type->contains_atomic()) {
@@ -6080,7 +6084,8 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
enum glsl_matrix_layout matrix_layout,
bool allow_reserved_names,
ir_variable_mode var_mode,
- ast_type_qualifier *layout)
+ ast_type_qualifier *layout,
+ unsigned block_stream)
{
unsigned decl_count = 0;
@@ -6188,11 +6193,16 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
* the specified stream must match the stream associated with the
* containing block."
*/
- if (qual->flags.q.explicit_stream &&
- qual->stream != layout->stream) {
- _mesa_glsl_error(&loc, state, "stream layout qualifier on interface "
- "block member does not match the interface block "
- "(%d vs %d)", qual->stream, layout->stream);
+ if (qual->flags.q.explicit_stream) {
+ unsigned qual_stream;
+ if (process_qualifier_constant(state, &loc, "stream",
+ qual->stream, &qual_stream) &&
+ qual_stream != block_stream) {
+ _mesa_glsl_error(&loc, state, "stream layout qualifier on "
+ "interface block member does not match "
+ "the interface block (%d vs %d)", qual->stream,
+ block_stream);
+ }
}
if (qual->flags.q.uniform && qual->has_interpolation()) {
@@ -6350,7 +6360,8 @@ ast_struct_specifier::hir(exec_list *instructions,
GLSL_MATRIX_LAYOUT_INHERITED,
false /* allow_reserved_names */,
ir_var_auto,
- NULL);
+ NULL,
+ 0 /* for interface only */);
validate_identifier(this->name, loc, state);
@@ -6504,6 +6515,16 @@ ast_interface_block::hir(exec_list *instructions,
"Interface block sets both readonly and writeonly");
}
+ unsigned qual_stream;
+ if (!process_qualifier_constant(state, &loc, "stream", this->layout.stream,
+ &qual_stream)) {
+ /* If the stream qualifier is invalid it doesn't make sense to continue
+ * on and try to compare stream layouts on member variables against it
+ * so just return early.
+ */
+ return NULL;
+ }
+
unsigned int num_variables =
ast_process_struct_or_iface_block_members(&declared_variables,
state,
@@ -6513,7 +6534,8 @@ ast_interface_block::hir(exec_list *instructions,
matrix_layout,
redeclaring_per_vertex,
var_mode,
- &this->layout);
+ &this->layout,
+ qual_stream);
state->struct_specifier_depth--;
@@ -6859,7 +6881,7 @@ ast_interface_block::hir(exec_list *instructions,
var->data.explicit_binding = this->layout.flags.q.explicit_binding;
var->data.binding = this->layout.binding;
- var->data.stream = this->layout.stream;
+ var->data.stream = qual_stream;
state->symbols->add_variable(var);
instructions->push_tail(var);
@@ -6879,7 +6901,7 @@ ast_interface_block::hir(exec_list *instructions,
var->data.centroid = fields[i].centroid;
var->data.sample = fields[i].sample;
var->data.patch = fields[i].patch;
- var->data.stream = this->layout.stream;
+ var->data.stream = qual_stream;
var->init_interface_type(block_type);
if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index a96b18087b8..b4a1652a14c 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -1514,15 +1514,8 @@ layout_qualifier_id:
if (match_layout_qualifier("stream", $1, state) == 0 &&
state->check_explicit_attrib_stream_allowed(& @3)) {
$$.flags.q.stream = 1;
-
- if ($3 < 0) {
- _mesa_glsl_error(& @3, state,
- "invalid stream %d specified", $3);
- YYERROR;
- } else {
- $$.flags.q.explicit_stream = 1;
- $$.stream = $3;
- }
+ $$.flags.q.explicit_stream = 1;
+ $$.stream = $3;
}
}