summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Gomez <agomez@igalia.com>2016-11-14 17:49:33 +0200
committerAndres Gomez <agomez@igalia.com>2016-11-25 13:18:30 +0200
commit0ecfff0d08a7ca48f1b284c11c48f158c723e0c2 (patch)
treee8556815387a67254711344cf2ded9575565a2cd
parent65df02c00287449efedc4ec3d57ceee38abaacdb (diff)
glsl: simplifies the merge of the default in layout qualifier
The merge into the default in layout qualifier duplicates a lot of code that can be reused from the generic merge method. Now, we use the generic merge method inside the specific merge for the default in layout qualifier. The generic merge method has been completed with some bits that were only present in the merge for the default in layout qualifier and the specific validation bits have been moved to the validation method for the default in layout qualifier. Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com> Signed-off-by: Andres Gomez <agomez@igalia.com>
-rw-r--r--src/compiler/glsl/ast_type.cpp165
1 files changed, 81 insertions, 84 deletions
diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp
index 65e4ca6c77..6aedeaa62d 100644
--- a/src/compiler/glsl/ast_type.cpp
+++ b/src/compiler/glsl/ast_type.cpp
@@ -198,16 +198,20 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
if (q.flags.q.prim_type) {
if (this->flags.q.prim_type && this->prim_type != q.prim_type) {
_mesa_glsl_error(loc, state,
- "conflicting primitive type qualifiers used");
+ "conflicting input primitive %s specified",
+ state->stage == MESA_SHADER_GEOMETRY ?
+ "type" : "mode");
return false;
}
+ this->flags.q.prim_type = 1;
this->prim_type = q.prim_type;
}
if (q.flags.q.max_vertices) {
- if (this->max_vertices && !is_single_layout_merge) {
+ if (this->flags.q.max_vertices && !is_single_layout_merge) {
this->max_vertices->merge_qualifier(q.max_vertices);
} else {
+ this->flags.q.max_vertices = 1;
this->max_vertices = q.max_vertices;
}
}
@@ -222,9 +226,10 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
}
if (q.flags.q.invocations) {
- if (this->invocations && !is_single_layout_merge) {
+ if (this->flags.q.invocations && !is_single_layout_merge) {
this->invocations->merge_qualifier(q.invocations);
} else {
+ this->flags.q.invocations = 1;
this->invocations = q.invocations;
}
}
@@ -284,9 +289,10 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
}
if (q.flags.q.vertices) {
- if (this->vertices && !is_single_layout_merge) {
+ if (this->flags.q.vertices && !is_single_layout_merge) {
this->vertices->merge_qualifier(q.vertices);
} else {
+ this->flags.q.vertices = 1;
this->vertices = q.vertices;
}
}
@@ -296,6 +302,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
_mesa_glsl_error(loc, state, "conflicting vertex spacing used");
return false;
}
+ this->flags.q.vertex_spacing = 1;
this->vertex_spacing = q.vertex_spacing;
}
@@ -304,6 +311,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
_mesa_glsl_error(loc, state, "conflicting ordering used");
return false;
}
+ this->flags.q.ordering = 1;
this->ordering = q.ordering;
}
@@ -312,9 +320,13 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
_mesa_glsl_error(loc, state, "conflicting point mode used");
return false;
}
+ this->flags.q.point_mode = 1;
this->point_mode = q.point_mode;
}
+ if (q.flags.q.early_fragment_tests)
+ this->flags.q.early_fragment_tests = true;
+
if ((q.flags.i & ubo_mat_mask.flags.i) != 0)
this->flags.i &= ~ubo_mat_mask.flags.i;
if ((q.flags.i & ubo_layout_mask.flags.i) != 0)
@@ -330,6 +342,9 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
}
}
+ if (q.flags.q.local_size_variable)
+ this->flags.q.local_size_variable = true;
+
this->flags.i |= q.flags.i;
if (this->flags.q.in &&
@@ -535,6 +550,45 @@ ast_type_qualifier::validate_in_qualifier(YYLTYPE *loc,
_mesa_glsl_error(loc, state, "invalid input layout qualifiers used");
}
+ /* The checks below are also performed when merging but we want to spit an
+ * error against the default global input qualifier as soon as we can, with
+ * the closest error location in the shader.
+ */
+
+ /* Input layout qualifiers can be specified multiple
+ * times in separate declarations, as long as they match.
+ */
+ if (state->in_qualifier->flags.q.prim_type && this->flags.q.prim_type
+ && state->in_qualifier->prim_type != this->prim_type) {
+ r = false;
+ _mesa_glsl_error(loc, state,
+ "conflicting input primitive %s specified",
+ state->stage == MESA_SHADER_GEOMETRY ?
+ "type" : "mode");
+ }
+
+ if (state->in_qualifier->flags.q.vertex_spacing
+ && this->flags.q.vertex_spacing
+ && state->in_qualifier->vertex_spacing != this->vertex_spacing) {
+ r = false;
+ _mesa_glsl_error(loc, state,
+ "conflicting vertex spacing specified");
+ }
+
+ if (state->in_qualifier->flags.q.ordering && this->flags.q.ordering
+ && state->in_qualifier->ordering != this->ordering) {
+ r = false;
+ _mesa_glsl_error(loc, state,
+ "conflicting ordering specified");
+ }
+
+ if (state->in_qualifier->flags.q.point_mode && this->flags.q.point_mode
+ && state->in_qualifier->point_mode != this->point_mode) {
+ r = false;
+ _mesa_glsl_error(loc, state,
+ "conflicting point mode specified");
+ }
+
return r;
}
@@ -543,100 +597,43 @@ ast_type_qualifier::merge_into_in_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
ast_node* &node, bool create_node)
{
+ bool r = true;
void *lin_ctx = state->linalloc;
- bool create_gs_ast = false;
- bool create_cs_ast = false;
- switch (state->stage) {
- case MESA_SHADER_GEOMETRY:
- create_gs_ast |=
- this->flags.q.prim_type &&
- !state->in_qualifier->flags.q.prim_type;
- break;
- case MESA_SHADER_COMPUTE:
- create_cs_ast |=
- this->flags.q.local_size != 0 &&
- state->in_qualifier->flags.q.local_size == 0;
- break;
- default:
- break;
- }
-
- /* Input layout qualifiers can be specified multiple
- * times in separate declarations, as long as they match.
+ /* We create the gs_input_layout node before merging so, in the future, no
+ * more repeated nodes will be created as we will have the flag set.
*/
- if (state->in_qualifier->flags.q.prim_type) {
- if (this->flags.q.prim_type &&
- state->in_qualifier->prim_type != this->prim_type) {
- _mesa_glsl_error(loc, state,
- "conflicting input primitive %s specified",
- state->stage == MESA_SHADER_GEOMETRY ?
- "type" : "mode");
- }
- } else if (this->flags.q.prim_type) {
- state->in_qualifier->flags.q.prim_type = 1;
- state->in_qualifier->prim_type = this->prim_type;
+ if (state->stage == MESA_SHADER_GEOMETRY
+ && this->flags.q.prim_type && !state->in_qualifier->flags.q.prim_type
+ && create_node) {
+ node = new(lin_ctx) ast_gs_input_layout(*loc, this->prim_type);
}
- if (this->flags.q.invocations) {
- state->in_qualifier->flags.q.invocations = 1;
- if (state->in_qualifier->invocations) {
- state->in_qualifier->invocations->merge_qualifier(this->invocations);
- } else {
- state->in_qualifier->invocations = this->invocations;
- }
- }
+ r = state->in_qualifier->merge_qualifier(loc, state, *this, false);
- if (this->flags.q.early_fragment_tests) {
+ if (state->in_qualifier->flags.q.early_fragment_tests) {
state->fs_early_fragment_tests = true;
+ state->in_qualifier->flags.q.early_fragment_tests = false;
}
- if (state->in_qualifier->flags.q.vertex_spacing) {
- if (this->flags.q.vertex_spacing &&
- state->in_qualifier->vertex_spacing != this->vertex_spacing) {
- _mesa_glsl_error(loc, state,
- "conflicting vertex spacing specified");
- }
- } else if (this->flags.q.vertex_spacing) {
- state->in_qualifier->flags.q.vertex_spacing = 1;
- state->in_qualifier->vertex_spacing = this->vertex_spacing;
- }
-
- if (state->in_qualifier->flags.q.ordering) {
- if (this->flags.q.ordering &&
- state->in_qualifier->ordering != this->ordering) {
- _mesa_glsl_error(loc, state,
- "conflicting ordering specified");
- }
- } else if (this->flags.q.ordering) {
- state->in_qualifier->flags.q.ordering = 1;
- state->in_qualifier->ordering = this->ordering;
- }
-
- if (state->in_qualifier->flags.q.point_mode) {
- if (this->flags.q.point_mode &&
- state->in_qualifier->point_mode != this->point_mode) {
- _mesa_glsl_error(loc, state,
- "conflicting point mode specified");
- }
- } else if (this->flags.q.point_mode) {
- state->in_qualifier->flags.q.point_mode = 1;
- state->in_qualifier->point_mode = this->point_mode;
+ /* We allow the creation of multiple cs_input_layout nodes. Coherence among
+ * all existing nodes is checked later, when the AST node is transformed
+ * into HIR.
+ */
+ if (state->in_qualifier->flags.q.local_size) {
+ if (create_node)
+ node = new(lin_ctx) ast_cs_input_layout(*loc, state->in_qualifier->local_size);
+ state->in_qualifier->flags.q.local_size = 0;
+ for (int i = 0; i < 3; i++)
+ state->in_qualifier->local_size[i] = NULL;
}
- if (this->flags.q.local_size_variable) {
+ if (state->in_qualifier->flags.q.local_size_variable) {
state->cs_input_local_size_variable_specified = true;
+ state->in_qualifier->flags.q.local_size_variable = false;
}
- if (create_node) {
- if (create_gs_ast) {
- node = new(lin_ctx) ast_gs_input_layout(*loc, this->prim_type);
- } else if (create_cs_ast) {
- node = new(lin_ctx) ast_cs_input_layout(*loc, this->local_size);
- }
- }
-
- return true;
+ return r;
}
/**