case GLSL_TYPE_SAMPLER:
case GLSL_TYPE_IMAGE:
case GLSL_TYPE_INTERFACE:
+ case GLSL_TYPE_FUNCTION:
case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_SUBROUTINE:
/* I assume a comparison of a struct containing a sampler just
* expressions. Const-qualified global variables must still be
* initialized with constant expressions.
*/
- if (!state->ARB_shading_language_420pack_enable
+ if (!state->has_420pack()
|| state->current_function == NULL) {
_mesa_glsl_error(& initializer_loc, state,
"initializer of %s variable `%s' must be a "
if (state->current_function->return_type != ret_type) {
YYLTYPE loc = this->get_location();
- if (state->ARB_shading_language_420pack_enable) {
+ if (state->has_420pack()) {
if (!apply_implicit_conversion(state->current_function->return_type,
ret, state)) {
_mesa_glsl_error(& loc, state,
bool allow_reserved_names,
ir_variable_mode var_mode,
ast_type_qualifier *layout,
- unsigned block_stream)
+ unsigned block_stream,
+ unsigned expl_location)
{
unsigned decl_count = 0;
glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field,
decl_count);
+ bool first_member = true;
+ bool first_member_has_explicit_location;
+
unsigned i = 0;
foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
const char *type_name;
"to struct or interface block members");
}
+ if (is_interface) {
+ if (!first_member) {
+ if (!layout->flags.q.explicit_location &&
+ ((first_member_has_explicit_location &&
+ !qual->flags.q.explicit_location) ||
+ (!first_member_has_explicit_location &&
+ qual->flags.q.explicit_location))) {
+ _mesa_glsl_error(&loc, state,
+ "when block-level location layout qualifier "
+ "is not supplied either all members must "
+ "have a location layout qualifier or all "
+ "members must not have a location layout "
+ "qualifier");
+ }
+ } else {
+ first_member = false;
+ first_member_has_explicit_location =
+ qual->flags.q.explicit_location;
+ }
+ }
+
if (qual->flags.q.std140 ||
qual->flags.q.std430 ||
qual->flags.q.packed ||
validate_array_dimensions(field_type, state, &loc);
fields[i].type = field_type;
fields[i].name = decl->identifier;
- fields[i].location = -1;
fields[i].interpolation =
interpret_interpolation_qualifier(qual, var_mode, state, &loc);
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
fields[i].patch = qual->flags.q.patch ? 1 : 0;
fields[i].precision = qual->precision;
+ if (qual->flags.q.explicit_location) {
+ unsigned qual_location;
+ if (process_qualifier_constant(state, &loc, "location",
+ qual->location, &qual_location)) {
+ fields[i].location = VARYING_SLOT_VAR0 + qual_location;
+ expl_location = fields[i].location + 1;
+ }
+ } else {
+ if (layout && layout->flags.q.explicit_location) {
+ fields[i].location = expl_location;
+ expl_location = expl_location + 1;
+ } else {
+ fields[i].location = -1;
+ }
+ }
+
/* Propogate row- / column-major information down the fields of the
* structure or interface block. Structures need this data because
* the structure may contain a structure that contains ... a matrix
state->struct_specifier_depth++;
+ unsigned expl_location = -1;
+ if (layout && layout->flags.q.explicit_location) {
+ if (!process_qualifier_constant(state, &loc, "location",
+ layout->location, &expl_location)) {
+ return NULL;
+ } else {
+ expl_location = VARYING_SLOT_VAR0 + expl_location;
+ }
+ }
+
glsl_struct_field *fields;
unsigned decl_count =
ast_process_struct_or_iface_block_members(instructions,
GLSL_MATRIX_LAYOUT_INHERITED,
false /* allow_reserved_names */,
ir_var_auto,
- NULL,
- 0 /* for interface only */);
+ layout,
+ 0, /* for interface only */
+ expl_location);
validate_identifier(this->name, loc, state);
return NULL;
}
+ unsigned expl_location = -1;
+ if (layout.flags.q.explicit_location) {
+ if (!process_qualifier_constant(state, &loc, "location",
+ layout.location, &expl_location)) {
+ return NULL;
+ } else {
+ expl_location = VARYING_SLOT_VAR0 + expl_location;
+ }
+ }
+
unsigned int num_variables =
ast_process_struct_or_iface_block_members(&declared_variables,
state,
redeclaring_per_vertex,
var_mode,
&this->layout,
- qual_stream);
+ qual_stream,
+ expl_location);
state->struct_specifier_depth--;
}
var->data.stream = qual_stream;
+ if (layout.flags.q.explicit_location) {
+ var->data.location = expl_location;
+ var->data.explicit_location = true;
+ }
state->symbols->add_variable(var);
instructions->push_tail(var);
var->data.sample = fields[i].sample;
var->data.patch = fields[i].patch;
var->data.stream = qual_stream;
+ var->data.location = fields[i].location;
+ if (fields[i].location != -1)
+ var->data.explicit_location = true;
var->init_interface_type(block_type);
if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)