diff options
author | Timothy Arceri <[email protected]> | 2015-12-01 10:34:18 +1100 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2015-12-15 13:10:44 +1100 |
commit | 0aeb9b3e5eab57ae5d96047cee7b2c58811b455b (patch) | |
tree | 92d2368f2f6e7122cd6ec95aa4fa6167f5eb3b32 /src/glsl/ast_to_hir.cpp | |
parent | 183c606066b1b260acb189e46a40cb71e63b44aa (diff) |
glsl: add support for explicit locations inside interface blocks
This change also adds explicit location support for structs and interfaces which
is currently missing in Mesa but is allowed with SSO and GLSL 1.50+.
Reviewed-by: Edward O'Callaghan <[email protected]>
Diffstat (limited to 'src/glsl/ast_to_hir.cpp')
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 79 |
1 files changed, 74 insertions, 5 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 35a1e134dfa..1091c022703 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -6179,7 +6179,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; @@ -6200,6 +6201,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; @@ -6264,6 +6268,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 || @@ -6338,7 +6363,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; @@ -6346,6 +6370,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 @@ -6444,6 +6484,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, @@ -6454,8 +6504,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); @@ -6620,6 +6671,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, @@ -6630,7 +6691,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--; @@ -6969,6 +7031,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); @@ -6989,6 +7055,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) |