summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/link_uniforms.cpp
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2016-03-11 16:15:02 +1100
committerTimothy Arceri <[email protected]>2016-03-31 12:49:47 +1100
commit8765a9e0fe2987caa6af7473cbc4c55754621806 (patch)
tree3933cacd1356feb8507449fbaccb316c61a4a530 /src/compiler/glsl/link_uniforms.cpp
parent7ebc3deaad77d11aa7086720ba4c3469a8878de3 (diff)
glsl: generate named interface block names correctly
Firstly this updates the named interface lowering pass to store the interface without the arrays removed. Note we need to remove the arrays in the interface/varying matching code to not regress things but in future this should be fixed futher as it would seem we currently successfully match interface blocks with differnt array sizes. Since we now know if the interface was an array we can reduce the IR flags from_named_ifc_block_array and from_named_ifc_block_nonarray to just from_named_ifc_block. Next rather than having a different code path for named interface blocks in program_resource_visitor we just make use of the one used by UBOs this allows us to now handle arrays of arrays correctly. Finally we add a new param to the recursion function named_ifc_member this is because we only want to process a single member at a time. Note that this is also the glsl_struct_field from the original ifc type before lowering rather than the type from the lowered variable. This fixes a bug in Mesa where we would generate the names like WithInstArray[0].g[0][0] when it should be WithInstArray[0].g[0] for the following interface. out WithInstArray { float g[3]; } instArray[2]; Reviewed-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/compiler/glsl/link_uniforms.cpp')
-rw-r--r--src/compiler/glsl/link_uniforms.cpp95
1 files changed, 24 insertions, 71 deletions
diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp
index cd487ab6dd0..0a230cad034 100644
--- a/src/compiler/glsl/link_uniforms.cpp
+++ b/src/compiler/glsl/link_uniforms.cpp
@@ -68,7 +68,7 @@ program_resource_visitor::process(const glsl_type *type, const char *name)
unsigned packing = type->interface_packing;
recursion(type, &name_copy, strlen(name), false, NULL, packing, false,
- record_array_count);
+ record_array_count, NULL);
ralloc_free(name_copy);
}
@@ -76,8 +76,6 @@ void
program_resource_visitor::process(ir_variable *var)
{
unsigned record_array_count = 1;
- const glsl_type *t = var->type;
- const glsl_type *t_without_array = var->type->without_array();
const bool row_major =
var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
@@ -85,80 +83,28 @@ program_resource_visitor::process(ir_variable *var)
var->get_interface_type()->interface_packing :
var->type->interface_packing;
+ const glsl_type *t =
+ var->data.from_named_ifc_block ? var->get_interface_type() : var->type;
+ const glsl_type *t_without_array = t->without_array();
+
/* false is always passed for the row_major parameter to the other
* processing functions because no information is available to do
* otherwise. See the warning in linker.h.
*/
-
- /* Only strdup the name if we actually will need to modify it. */
- if (var->data.from_named_ifc_block_array) {
- /* lower_named_interface_blocks created this variable by lowering an
- * interface block array to an array variable. For example if the
- * original source code was:
- *
- * out Blk { vec4 bar } foo[3];
- *
- * Then the variable is now:
- *
- * out vec4 bar[3];
- *
- * We need to visit each array element using the names constructed like
- * so:
- *
- * Blk[0].bar
- * Blk[1].bar
- * Blk[2].bar
- */
- assert(t->is_array());
- const glsl_type *ifc_type = var->get_interface_type();
- char *name = ralloc_strdup(NULL, ifc_type->name);
- size_t name_length = strlen(name);
- for (unsigned i = 0; i < t->length; i++) {
- size_t new_length = name_length;
- ralloc_asprintf_rewrite_tail(&name, &new_length, "[%u].%s", i,
- var->name);
- /* Note: row_major is only meaningful for uniform blocks, and
- * lowering is only applied to non-uniform interface blocks, so we
- * can safely pass false for row_major.
- */
- recursion(var->type, &name, new_length, row_major, NULL, packing,
- false, record_array_count);
- }
- ralloc_free(name);
- } else if (var->data.from_named_ifc_block_nonarray) {
- /* lower_named_interface_blocks created this variable by lowering a
- * named interface block (non-array) to an ordinary variable. For
- * example if the original source code was:
- *
- * out Blk { vec4 bar } foo;
- *
- * Then the variable is now:
- *
- * out vec4 bar;
- *
- * We need to visit this variable using the name:
- *
- * Blk.bar
- */
- const glsl_type *ifc_type = var->get_interface_type();
- char *name = ralloc_asprintf(NULL, "%s.%s", ifc_type->name, var->name);
- /* Note: row_major is only meaningful for uniform blocks, and lowering
- * is only applied to non-uniform interface blocks, so we can safely
- * pass false for row_major.
- */
- recursion(var->type, &name, strlen(name), row_major, NULL, packing,
- false, record_array_count);
- ralloc_free(name);
- } else if (t_without_array->is_record() ||
+ if (t_without_array->is_record() ||
(t->is_array() && t->fields.array->is_array())) {
char *name = ralloc_strdup(NULL, var->name);
recursion(var->type, &name, strlen(name), row_major, NULL, packing,
- false, record_array_count);
+ false, record_array_count, NULL);
ralloc_free(name);
} else if (t_without_array->is_interface()) {
char *name = ralloc_strdup(NULL, t_without_array->name);
- recursion(var->type, &name, strlen(name), row_major, NULL, packing,
- false, record_array_count);
+ const glsl_struct_field *ifc_member = var->data.from_named_ifc_block ?
+ &t_without_array->
+ fields.structure[t_without_array->field_index(var->name)] : NULL;
+
+ recursion(t, &name, strlen(name), row_major, NULL, packing,
+ false, record_array_count, ifc_member);
ralloc_free(name);
} else {
this->set_record_array_count(record_array_count);
@@ -172,7 +118,8 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
const glsl_type *record_type,
const unsigned packing,
bool last_field,
- unsigned record_array_count)
+ unsigned record_array_count,
+ const glsl_struct_field *named_ifc_member)
{
/* Records need to have each field processed individually.
*
@@ -180,7 +127,12 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
* individually, then each field of the resulting array elements processed
* individually.
*/
- if (t->is_record() || t->is_interface()) {
+ if (t->is_interface() && named_ifc_member) {
+ ralloc_asprintf_rewrite_tail(name, &name_length, ".%s",
+ named_ifc_member->name);
+ recursion(named_ifc_member->type, name, name_length, row_major, NULL,
+ packing, false, record_array_count, NULL);
+ } else if (t->is_record() || t->is_interface()) {
if (record_type == NULL && t->is_record())
record_type = t;
@@ -223,7 +175,7 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
field_row_major,
record_type,
packing,
- (i + 1) == t->length, record_array_count);
+ (i + 1) == t->length, record_array_count, NULL);
/* Only the first leaf-field of the record gets called with the
* record type pointer.
@@ -258,7 +210,8 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
recursion(t->fields.array, name, new_length, row_major,
record_type,
packing,
- (i + 1) == t->length, record_array_count);
+ (i + 1) == t->length, record_array_count,
+ named_ifc_member);
/* Only the first leaf-field of the record gets called with the
* record type pointer.