* Note: Whole-array assignments are not permitted in GLSL 1.10, but this
* is handled by ir_dereference::is_lvalue.
*/
- if (is_initializer && lhs_type->is_unsized_array() && rhs->type->is_array()
+ if (lhs_type->is_unsized_array() && rhs->type->is_array()
&& (lhs_type->element_type() == rhs->type->element_type())) {
- return rhs;
+ if (is_initializer) {
+ return rhs;
+ } else {
+ _mesa_glsl_error(&loc, state,
+ "implicitly sized arrays cannot be assigned");
+ return NULL;
+ }
}
/* Check for implicit conversion in GLSL 1.20 */
"exceeds the maximum number of texture image units "
"(%d)", qual->binding, elements, limit);
+ return false;
+ }
+ } else if (var->type->contains_atomic()) {
+ assert(ctx->Const.MaxAtomicBufferBindings <= MAX_COMBINED_ATOMIC_BUFFERS);
+ if (unsigned(qual->binding) >= ctx->Const.MaxAtomicBufferBindings) {
+ _mesa_glsl_error(loc, state, "layout(binding = %d) exceeds the "
+ " maximum number of atomic counter buffer bindings"
+ "(%d)", qual->binding,
+ ctx->Const.MaxAtomicBufferBindings);
+
return false;
}
} else {
_mesa_glsl_error(loc, state,
"the \"binding\" qualifier only applies to uniform "
- "blocks, samplers, or arrays of samplers");
+ "blocks, samplers, atomic counters, or arrays thereof");
return false;
}
YYLTYPE *loc)
{
bool fail = false;
- const char *string = "";
/* In the vertex shader only shader inputs can be given explicit
* locations.
*/
switch (state->target) {
case vertex_shader:
- if (var->mode != ir_var_shader_in) {
- fail = true;
- string = "input";
+ if (var->mode == ir_var_shader_in) {
+ if (!state->check_explicit_attrib_location_allowed(loc, var))
+ return;
+
+ break;
}
+
+ fail = true;
break;
case geometry_shader:
return;
case fragment_shader:
- if (var->mode != ir_var_shader_out) {
- fail = true;
- string = "output";
+ if (var->mode == ir_var_shader_out) {
+ if (!state->check_explicit_attrib_location_allowed(loc, var))
+ return;
+
+ break;
}
+
+ fail = true;
break;
};
if (fail) {
_mesa_glsl_error(loc, state,
- "only %s shader %s variables can be given an "
- "explicit location",
- _mesa_glsl_shader_target_name(state->target),
- string);
+ "%s cannot be given an explicit location in %s shader",
+ mode_string(var),
+ _mesa_glsl_shader_target_name(state->target));
} else {
var->explicit_location = true;
}
}
}
+
+ return;
}
static void
if (qual->flags.q.centroid)
var->centroid = 1;
+ if (qual->flags.q.sample)
+ var->sample = 1;
+
if (qual->flags.q.attribute && state->target != vertex_shader) {
var->type = glsl_type::error_type;
_mesa_glsl_error(loc, state,
var->binding = qual->binding;
}
+ if (var->type->contains_atomic()) {
+ if (var->mode == ir_var_uniform) {
+ if (var->explicit_binding) {
+ unsigned *offset = &state->atomic_counter_offsets[var->binding];
+
+ if (*offset % ATOMIC_COUNTER_SIZE)
+ _mesa_glsl_error(loc, state,
+ "misaligned atomic counter offset");
+
+ var->atomic.offset = *offset;
+ *offset += var->type->atomic_size();
+
+ } else {
+ _mesa_glsl_error(loc, state,
+ "atomic counters require explicit binding point");
+ }
+ } else if (var->mode != ir_var_function_in) {
+ _mesa_glsl_error(loc, state, "atomic counters may only be declared as "
+ "function parameters or uniform-qualified "
+ "global variables");
+ }
+ }
+
/* Does the declaration use the deprecated 'attribute' or 'varying'
* keywords?
*/
(void) this->type->specifier->hir(instructions, state);
decl_type = this->type->glsl_type(& type_name, state);
+
+ /* An offset-qualified atomic counter declaration sets the default
+ * offset for the next declaration within the same atomic counter
+ * buffer.
+ */
+ if (decl_type && decl_type->contains_atomic()) {
+ if (type->qualifier.flags.q.explicit_binding &&
+ type->qualifier.flags.q.explicit_offset)
+ state->atomic_counter_offsets[type->qualifier.binding] =
+ type->qualifier.offset;
+ }
+
if (this->declarations.is_empty()) {
/* If there is no structure involved in the program text, there are two
* possible scenarios:
_mesa_glsl_error(&loc, state,
"invalid type `%s' in empty declaration",
type_name);
+ } else if (decl_type->base_type == GLSL_TYPE_ATOMIC_UINT) {
+ /* Empty atomic counter declarations are allowed and useful
+ * to set the default offset qualifier.
+ */
+ return NULL;
} else if (this->type->qualifier.precision != ast_precision_none) {
if (this->type->specifier->structure != NULL) {
_mesa_glsl_error(&loc, state,
precision_names[this->type->qualifier.precision],
type_name);
}
- } else {
+ } else if (this->type->specifier->structure == NULL) {
_mesa_glsl_warning(&loc, state, "empty declaration");
}
}
"'centroid in' cannot be used in a vertex shader");
}
+ if (state->target == vertex_shader
+ && this->type->qualifier.flags.q.sample
+ && this->type->qualifier.flags.q.in) {
+
+ _mesa_glsl_error(&loc, state,
+ "'sample in' cannot be used in a vertex shader");
+ }
+
/* Section 4.3.6 of the GLSL 1.30 specification states:
* "It is an error to use centroid out in a fragment shader."
*
ir_variable *earlier =
get_variable_being_redeclared(var, decl->get_location(), state,
false /* allow_all_redeclarations */);
+ if (earlier != NULL) {
+ if (strncmp(var->name, "gl_", 3) == 0 &&
+ earlier->how_declared == ir_var_declared_in_block) {
+ _mesa_glsl_error(&loc, state,
+ "`%s' has already been redeclared using "
+ "gl_PerVertex", var->name);
+ }
+ earlier->how_declared = ir_var_declared_normally;
+ }
if (decl->initializer != NULL) {
result = process_initializer((earlier == NULL) ? var : earlier,
"uniform in non-default uniform block contains sampler");
}
+ if (field_type->contains_atomic()) {
+ /* FINISHME: Add a spec quotation here once updated spec
+ * FINISHME: language is available. See Khronos bug #10903
+ * FINISHME: on whether atomic counters are allowed in
+ * FINISHME: structures.
+ */
+ YYLTYPE loc = decl_list->get_location();
+ _mesa_glsl_error(&loc, state, "atomic counter in structure or "
+ "uniform block");
+ }
+
const struct ast_type_qualifier *const qual =
& decl_list->type->qualifier;
if (qual->flags.q.std140 ||
fields[i].interpolation =
interpret_interpolation_qualifier(qual, var_mode, state, &loc);
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
+ fields[i].sample = qual->flags.q.sample ? 1 : 0;
if (qual->flags.q.row_major || qual->flags.q.column_major) {
if (!qual->flags.q.uniform) {
earlier_per_vertex->fields.structure[j].interpolation;
fields[i].centroid =
earlier_per_vertex->fields.structure[j].centroid;
+ fields[i].sample =
+ earlier_per_vertex->fields.structure[j].sample;
}
}
_mesa_glsl_error(&loc, state, "`%s' redeclared",
this->instance_name);
}
+ earlier->how_declared = ir_var_declared_normally;
earlier->type = var->type;
earlier->reinit_interface_type(block_type);
delete var;
var_mode);
var->interpolation = fields[i].interpolation;
var->centroid = fields[i].centroid;
+ var->sample = fields[i].sample;
var->init_interface_type(block_type);
if (redeclaring_per_vertex) {
_mesa_glsl_error(&loc, state,
"redeclaration of gl_PerVertex can only "
"include built-in variables");
+ } else if (earlier->how_declared == ir_var_declared_normally) {
+ _mesa_glsl_error(&loc, state,
+ "`%s' has already been redeclared", var->name);
} else {
+ earlier->how_declared = ir_var_declared_in_block;
earlier->reinit_interface_type(block_type);
}
continue;
if (var != NULL &&
var->get_interface_type() == earlier_per_vertex &&
var->mode == var_mode) {
+ if (var->how_declared == ir_var_declared_normally) {
+ _mesa_glsl_error(&loc, state,
+ "redeclaration of gl_PerVertex cannot "
+ "follow a redeclaration of `%s'",
+ var->name);
+ }
state->symbols->disable_variable(var->name);
var->remove();
}