X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fast_type.cpp;h=b596cd59ecf8ce7d614f63fc823fd19ea412dd5d;hb=0abfb80dacf80c1f2d0a6a4142b9ab84695aa9e7;hp=eba577764b0669810ee538fae6dc55a5adb2093f;hpb=738c9c3c543b985b025a4a60fcc9c2e212e2d821;p=mesa.git diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp index eba577764b0..b596cd59ecf 100644 --- a/src/glsl/ast_type.cpp +++ b/src/glsl/ast_type.cpp @@ -122,14 +122,28 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc, ubo_binding_mask.flags.q.explicit_binding = 1; ubo_binding_mask.flags.q.explicit_offset = 1; + ast_type_qualifier stream_layout_mask; + stream_layout_mask.flags.i = 0; + stream_layout_mask.flags.q.stream = 1; + /* Uniform block layout qualifiers get to overwrite each * other (rightmost having priority), while all other * qualifiers currently don't allow duplicates. */ + ast_type_qualifier allowed_duplicates_mask; + allowed_duplicates_mask.flags.i = + ubo_mat_mask.flags.i | + ubo_layout_mask.flags.i | + ubo_binding_mask.flags.i; + + /* Geometry shaders can have several layout qualifiers + * assigning different stream values. + */ + if (state->stage == MESA_SHADER_GEOMETRY) + allowed_duplicates_mask.flags.i |= + stream_layout_mask.flags.i; - if ((this->flags.i & q.flags.i & ~(ubo_mat_mask.flags.i | - ubo_layout_mask.flags.i | - ubo_binding_mask.flags.i)) != 0) { + if ((this->flags.i & q.flags.i & ~allowed_duplicates_mask.flags.i) != 0) { _mesa_glsl_error(loc, state, "duplicate layout qualifiers used"); return false; @@ -154,6 +168,49 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc, this->max_vertices = q.max_vertices; } + if (q.flags.q.invocations) { + if (this->flags.q.invocations && this->invocations != q.invocations) { + _mesa_glsl_error(loc, state, + "geometry shader set conflicting invocations " + "(%d and %d)", this->invocations, q.invocations); + return false; + } + this->invocations = q.invocations; + } + + if (state->stage == MESA_SHADER_GEOMETRY && + state->has_explicit_attrib_stream()) { + if (q.flags.q.stream && q.stream >= state->ctx->Const.MaxVertexStreams) { + _mesa_glsl_error(loc, state, + "`stream' value is larger than MAX_VERTEX_STREAMS - 1 " + "(%d > %d)", + q.stream, state->ctx->Const.MaxVertexStreams - 1); + } + if (this->flags.q.explicit_stream && + this->stream >= state->ctx->Const.MaxVertexStreams) { + _mesa_glsl_error(loc, state, + "`stream' value is larger than MAX_VERTEX_STREAMS - 1 " + "(%d > %d)", + this->stream, state->ctx->Const.MaxVertexStreams - 1); + } + + if (!this->flags.q.explicit_stream) { + if (q.flags.q.stream) { + this->flags.q.stream = 1; + this->stream = q.stream; + } else if (!this->flags.q.stream && this->flags.q.out) { + /* Assign default global stream value */ + this->flags.q.stream = 1; + this->stream = state->out_qualifier->stream; + } + } else { + if (q.flags.q.explicit_stream) { + _mesa_glsl_error(loc, state, + "duplicate layout `stream' qualifier"); + } + } + } + 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) @@ -233,6 +290,7 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc, !state->in_qualifier->flags.q.prim_type; valid_in_mask.flags.q.prim_type = 1; + valid_in_mask.flags.q.invocations = 1; break; case MESA_SHADER_FRAGMENT: if (q.flags.q.early_fragment_tests) { @@ -246,7 +304,7 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc, q.flags.q.local_size != 0 && state->in_qualifier->flags.q.local_size == 0; - valid_in_mask.flags.q.local_size = 1; + valid_in_mask.flags.q.local_size = 7; break; default: _mesa_glsl_error(loc, state, @@ -276,6 +334,17 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc, state->in_qualifier->prim_type = q.prim_type; } + if (this->flags.q.invocations && + q.flags.q.invocations && + this->invocations != q.invocations) { + _mesa_glsl_error(loc, state, + "conflicting invocations counts specified"); + return false; + } else if (q.flags.q.invocations) { + this->flags.q.invocations = 1; + this->invocations = q.invocations; + } + if (create_gs_ast) { node = new(mem_ctx) ast_gs_input_layout(*loc, q.prim_type); } else if (create_cs_ast) {