summaryrefslogtreecommitdiffstats
path: root/src/glsl/ast_to_hir.cpp
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-12-27 23:23:05 -0800
committerJason Ekstrand <[email protected]>2015-12-27 23:23:05 -0800
commitea77b384e8c575922eca1c05398e19fcbfda9b09 (patch)
tree4f8659bd8b48af785896daa224f6698a5ee269ec /src/glsl/ast_to_hir.cpp
parentf948767471ba83427cbcdc244a511fbb954ca9e0 (diff)
parent109c348284843054f708f4403260739b7db18275 (diff)
Merge remote-tracking branch 'mesa-public/master' into vulkan
This pulls in tessellation and the store_var changes that go with it.
Diffstat (limited to 'src/glsl/ast_to_hir.cpp')
-rw-r--r--src/glsl/ast_to_hir.cpp79
1 files changed, 74 insertions, 5 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index fc6bb3e31f1..376dfda2c84 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -6180,7 +6180,8 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
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;
@@ -6201,6 +6202,9 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
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;
@@ -6265,6 +6269,27 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
"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 ||
@@ -6339,7 +6364,6 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
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;
@@ -6347,6 +6371,22 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
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
@@ -6445,6 +6485,16 @@ ast_struct_specifier::hir(exec_list *instructions,
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,
@@ -6455,8 +6505,9 @@ ast_struct_specifier::hir(exec_list *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);
@@ -6621,6 +6672,16 @@ ast_interface_block::hir(exec_list *instructions,
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,
@@ -6631,7 +6692,8 @@ ast_interface_block::hir(exec_list *instructions,
redeclaring_per_vertex,
var_mode,
&this->layout,
- qual_stream);
+ qual_stream,
+ expl_location);
state->struct_specifier_depth--;
@@ -6970,6 +7032,10 @@ ast_interface_block::hir(exec_list *instructions,
}
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);
@@ -6990,6 +7056,9 @@ ast_interface_block::hir(exec_list *instructions,
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)