summaryrefslogtreecommitdiffstats
path: root/src/glsl/ast_type.cpp
diff options
context:
space:
mode:
authorFabian Bieler <fabianbieler@fastmail.fm>2014-03-20 22:44:43 +0100
committerMarek Olšák <marek.olsak@amd.com>2015-07-23 00:59:26 +0200
commit497eb295838baccde1420adfcc4ef7e8fdddd774 (patch)
tree517e56ea50330d128fca0ae95b4f7bf6a324fa6a /src/glsl/ast_type.cpp
parent206af9d049cab6e794db5abf63e3d11281343423 (diff)
downloadexternal_mesa3d-497eb295838baccde1420adfcc4ef7e8fdddd774.zip
external_mesa3d-497eb295838baccde1420adfcc4ef7e8fdddd774.tar.gz
external_mesa3d-497eb295838baccde1420adfcc4ef7e8fdddd774.tar.bz2
glsl: add tessellation shader parsing support (v2)
v2: Fixed things that Ken suggested. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'src/glsl/ast_type.cpp')
-rw-r--r--src/glsl/ast_type.cpp112
1 files changed, 111 insertions, 1 deletions
diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp
index fa4806a..f5c08d8 100644
--- a/src/glsl/ast_type.cpp
+++ b/src/glsl/ast_type.cpp
@@ -212,6 +212,44 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
}
}
+ if (q.flags.q.vertices) {
+ if (this->flags.q.vertices && this->vertices != q.vertices) {
+ _mesa_glsl_error(loc, state,
+ "tessellation control shader set conflicting "
+ "vertices (%d and %d)",
+ this->vertices, q.vertices);
+ return false;
+ }
+ this->vertices = q.vertices;
+ }
+
+ if (q.flags.q.vertex_spacing) {
+ if (this->flags.q.vertex_spacing && this->vertex_spacing != q.vertex_spacing) {
+ _mesa_glsl_error(loc, state,
+ "conflicting vertex spacing used");
+ return false;
+ }
+ this->vertex_spacing = q.vertex_spacing;
+ }
+
+ if (q.flags.q.ordering) {
+ if (this->flags.q.ordering && this->ordering != q.ordering) {
+ _mesa_glsl_error(loc, state,
+ "conflicting ordering used");
+ return false;
+ }
+ this->ordering = q.ordering;
+ }
+
+ if (q.flags.q.point_mode) {
+ if (this->flags.q.point_mode && this->point_mode != q.point_mode) {
+ _mesa_glsl_error(loc, state,
+ "conflicting point mode used");
+ return false;
+ }
+ this->point_mode = q.point_mode;
+ }
+
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)
@@ -257,6 +295,22 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
}
bool
+ast_type_qualifier::merge_out_qualifier(YYLTYPE *loc,
+ _mesa_glsl_parse_state *state,
+ ast_type_qualifier q,
+ ast_node* &node)
+{
+ void *mem_ctx = state;
+ const bool r = this->merge_qualifier(loc, state, q);
+
+ if (state->stage == MESA_SHADER_TESS_CTRL) {
+ node = new(mem_ctx) ast_tcs_output_layout(*loc, q.vertices);
+ }
+
+ return r;
+}
+
+bool
ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
ast_type_qualifier q,
@@ -269,6 +323,27 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
valid_in_mask.flags.i = 0;
switch (state->stage) {
+ case MESA_SHADER_TESS_EVAL:
+ if (q.flags.q.prim_type) {
+ /* Make sure this is a valid input primitive type. */
+ switch (q.prim_type) {
+ case GL_TRIANGLES:
+ case GL_QUADS:
+ case GL_ISOLINES:
+ break;
+ default:
+ _mesa_glsl_error(loc, state,
+ "invalid tessellation evaluation "
+ "shader input primitive type");
+ break;
+ }
+ }
+
+ valid_in_mask.flags.q.prim_type = 1;
+ valid_in_mask.flags.q.vertex_spacing = 1;
+ valid_in_mask.flags.q.ordering = 1;
+ valid_in_mask.flags.q.point_mode = 1;
+ break;
case MESA_SHADER_GEOMETRY:
if (q.flags.q.prim_type) {
/* Make sure this is a valid input primitive type. */
@@ -324,7 +399,9 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
if (q.flags.q.prim_type &&
this->prim_type != q.prim_type) {
_mesa_glsl_error(loc, state,
- "conflicting input primitive types specified");
+ "conflicting input primitive %s specified",
+ state->stage == MESA_SHADER_GEOMETRY ?
+ "type" : "mode");
}
} else if (q.flags.q.prim_type) {
state->in_qualifier->flags.q.prim_type = 1;
@@ -346,6 +423,39 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
state->fs_early_fragment_tests = true;
}
+ if (this->flags.q.vertex_spacing) {
+ if (q.flags.q.vertex_spacing &&
+ this->vertex_spacing != q.vertex_spacing) {
+ _mesa_glsl_error(loc, state,
+ "conflicting vertex spacing specified");
+ }
+ } else if (q.flags.q.vertex_spacing) {
+ this->flags.q.vertex_spacing = 1;
+ this->vertex_spacing = q.vertex_spacing;
+ }
+
+ if (this->flags.q.ordering) {
+ if (q.flags.q.ordering &&
+ this->ordering != q.ordering) {
+ _mesa_glsl_error(loc, state,
+ "conflicting ordering specified");
+ }
+ } else if (q.flags.q.ordering) {
+ this->flags.q.ordering = 1;
+ this->ordering = q.ordering;
+ }
+
+ if (this->flags.q.point_mode) {
+ if (q.flags.q.point_mode &&
+ this->point_mode != q.point_mode) {
+ _mesa_glsl_error(loc, state,
+ "conflicting point mode specified");
+ }
+ } else if (q.flags.q.point_mode) {
+ this->flags.q.point_mode = 1;
+ this->point_mode = q.point_mode;
+ }
+
if (create_gs_ast) {
node = new(mem_ctx) ast_gs_input_layout(*loc, q.prim_type);
} else if (create_cs_ast) {