}
bool
-ast_fully_specified_type::has_qualifiers() const
+ast_fully_specified_type::has_qualifiers(_mesa_glsl_parse_state *state) const
{
/* 'subroutine' isnt a real qualifier. */
ast_type_qualifier subroutine_only;
subroutine_only.flags.i = 0;
subroutine_only.flags.q.subroutine = 1;
subroutine_only.flags.q.subroutine_def = 1;
+ if (state->has_explicit_uniform_location()) {
+ subroutine_only.flags.q.explicit_index = 1;
+ }
return (this->qualifier.flags.i & ~subroutine_only.flags.i) != 0;
}
bool
ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q)
+ const ast_type_qualifier &q)
{
ast_type_qualifier ubo_mat_mask;
ubo_mat_mask.flags.i = 0;
}
if (q.flags.q.max_vertices) {
- if (this->flags.q.max_vertices && this->max_vertices != q.max_vertices) {
+ if (this->max_vertices) {
+ this->max_vertices->merge_qualifier(q.max_vertices);
+ } else {
+ this->max_vertices = q.max_vertices;
+ }
+ }
+
+ if (q.flags.q.subroutine_def) {
+ if (this->flags.q.subroutine_def) {
_mesa_glsl_error(loc, state,
- "geometry shader set conflicting max_vertices "
- "(%d and %d)", this->max_vertices, q.max_vertices);
- return false;
+ "conflicting subroutine qualifiers used");
+ } else {
+ this->subroutine_list = q.subroutine_list;
}
- 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;
+ if (this->invocations) {
+ this->invocations->merge_qualifier(q.invocations);
+ } else {
+ this->invocations = q.invocations;
}
- this->invocations = q.invocations;
}
if (state->stage == MESA_SHADER_GEOMETRY &&
}
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;
+ if (this->vertices) {
+ this->vertices->merge_qualifier(q.vertices);
+ } else {
+ this->vertices = q.vertices;
}
- this->vertices = q.vertices;
}
if (q.flags.q.vertex_spacing) {
for (int i = 0; i < 3; i++) {
if (q.flags.q.local_size & (1 << i)) {
- if ((this->flags.q.local_size & (1 << i)) &&
- this->local_size[i] != q.local_size[i]) {
- _mesa_glsl_error(loc, state,
- "compute shader set conflicting values for "
- "local_size_%c (%d and %d)", 'x' + i,
- this->local_size[i], q.local_size[i]);
- return false;
+ if (this->local_size[i]) {
+ this->local_size[i]->merge_qualifier(q.local_size[i]);
+ } else {
+ this->local_size[i] = q.local_size[i];
}
- this->local_size[i] = q.local_size[i];
}
}
bool
ast_type_qualifier::merge_out_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q,
+ const 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);
+ node = new(mem_ctx) ast_tcs_output_layout(*loc);
}
return r;
bool
ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q,
+ const ast_type_qualifier &q,
ast_node* &node)
{
void *mem_ctx = state;
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) {
+ if (q.flags.q.invocations) {
this->flags.q.invocations = 1;
- this->invocations = q.invocations;
+ if (this->invocations) {
+ this->invocations->merge_qualifier(q.invocations);
+ } else {
+ this->invocations = q.invocations;
+ }
}
if (q.flags.q.early_fragment_tests) {
if (create_gs_ast) {
node = new(mem_ctx) ast_gs_input_layout(*loc, q.prim_type);
} else if (create_cs_ast) {
- /* Infer a local_size of 1 for every unspecified dimension */
- unsigned local_size[3];
- for (int i = 0; i < 3; i++) {
- if (q.flags.q.local_size & (1 << i))
- local_size[i] = q.local_size[i];
- else
- local_size[i] = 1;
- }
- node = new(mem_ctx) ast_cs_input_layout(*loc, local_size);
+ node = new(mem_ctx) ast_cs_input_layout(*loc, q.local_size);
}
return true;