[Mesa-dev] [PATCH 13/16] glsl: Track matrix layout of variables using two bits
Ian Romanick
idr at freedesktop.org
Mon Jul 21 14:04:29 PDT 2014
From: Ian Romanick <ian.d.romanick at intel.com>
Fixes gles3conform failures in:
ES3-CTS.shaders.uniform_block.random.nested_structs_arrays_instance_arrays.3
ES3-CTS.shaders.uniform_block.random.all_per_block_buffers.13
Causes gles3conform failures in:
ES3-CTS.shaders.uniform_block.random.all_per_block_buffers.9
This failure will be fixed shortly.
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
src/glsl/ast_to_hir.cpp | 38 +++++++++++++++++++++++++++++++-------
src/glsl/ir.h | 5 +++++
src/glsl/link_uniform_blocks.cpp | 2 +-
src/glsl/link_uniforms.cpp | 31 ++++++++++++++++++++++++-------
4 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index eeafb44..a616be2 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -5072,7 +5072,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
YYLTYPE &loc,
glsl_struct_field **fields_ret,
bool is_interface,
- bool block_row_major,
+ enum glsl_matrix_layout matrix_layout,
bool allow_reserved_names,
ir_variable_mode var_mode)
{
@@ -5210,13 +5210,22 @@ ast_process_structure_or_interface_block(exec_list *instructions,
*/
if (field_type->is_matrix_or_array_of()
|| field_type->is_record_or_array_of()) {
- fields[i].matrix_layout = block_row_major
- ? GLSL_MATRIX_LAYOUT_ROW_MAJOR
- : GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
+ /* If no layout is specified for the field, inherit the layout
+ * from the block.
+ */
+ fields[i].matrix_layout = matrix_layout;
+
if (qual->flags.q.row_major)
fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR;
else if (qual->flags.q.column_major)
fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
+
+ /* If we're processing an interface block, the matrix layout must
+ * be decided by this point.
+ */
+ assert(!is_interface
+ || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR
+ || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR);
}
i++;
@@ -5271,7 +5280,7 @@ ast_struct_specifier::hir(exec_list *instructions,
loc,
&fields,
false,
- false,
+ GLSL_MATRIX_LAYOUT_DEFAULT,
false /* allow_reserved_names */,
ir_var_auto);
@@ -5371,8 +5380,13 @@ ast_interface_block::hir(exec_list *instructions,
assert(!"interface block layout qualifier not found!");
}
+ enum glsl_matrix_layout matrix_layout = GLSL_MATRIX_LAYOUT_DEFAULT;
+ if (this->layout.flags.q.row_major)
+ matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR;
+ else if (this->layout.flags.q.column_major)
+ matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
+
bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0;
- bool block_row_major = this->layout.flags.q.row_major;
exec_list declared_variables;
glsl_struct_field *fields;
@@ -5388,7 +5402,7 @@ ast_interface_block::hir(exec_list *instructions,
loc,
&fields,
true,
- block_row_major,
+ matrix_layout,
redeclaring_per_vertex,
var_mode);
@@ -5596,6 +5610,9 @@ ast_interface_block::hir(exec_list *instructions,
var_mode);
}
+ var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_DEFAULT
+ ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
+
if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
handle_geometry_shader_input_decl(state, loc, var);
@@ -5636,6 +5653,13 @@ ast_interface_block::hir(exec_list *instructions,
var->data.sample = fields[i].sample;
var->init_interface_type(block_type);
+ if (fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_DEFAULT) {
+ var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_DEFAULT
+ ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
+ } else {
+ var->data.matrix_layout = fields[i].matrix_layout;
+ }
+
if (fields[i].stream != -1 &&
((unsigned)fields[i].stream) != this->layout.stream) {
_mesa_glsl_error(&loc, state,
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index ea19924..889c7e2 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -660,6 +660,11 @@ public:
unsigned location_frac:2;
/**
+ * Layout of the matrix. Uses glsl_matrix_layout values.
+ */
+ unsigned matrix_layout:2;
+
+ /**
* Non-zero if this variable was created by lowering a named interface
* block which was not an array.
*
diff --git a/src/glsl/link_uniform_blocks.cpp b/src/glsl/link_uniform_blocks.cpp
index 8db5296..e6a0508 100644
--- a/src/glsl/link_uniform_blocks.cpp
+++ b/src/glsl/link_uniform_blocks.cpp
@@ -77,7 +77,7 @@ private:
v->Name = ralloc_strdup(mem_ctx, name);
v->Type = type;
- v->RowMajor = row_major;
+ v->RowMajor = type->is_matrix_or_array_of() && row_major;
if (this->is_array_instance) {
v->IndexName = ralloc_strdup(mem_ctx, name);
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index 68553f1..939c4ed 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -70,6 +70,8 @@ void
program_resource_visitor::process(ir_variable *var)
{
const glsl_type *t = var->type;
+ const bool row_major =
+ var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
/* false is always passed for the row_major parameter to the other
* processing functions because no information is available to do
@@ -107,7 +109,7 @@ program_resource_visitor::process(ir_variable *var)
* lowering is only applied to non-uniform interface blocks, so we
* can safely pass false for row_major.
*/
- recursion(var->type, &name, new_length, false, NULL, false);
+ recursion(var->type, &name, new_length, row_major, NULL, false);
}
ralloc_free(name);
} else if (var->data.from_named_ifc_block_nonarray) {
@@ -131,22 +133,22 @@ program_resource_visitor::process(ir_variable *var)
* is only applied to non-uniform interface blocks, so we can safely
* pass false for row_major.
*/
- recursion(var->type, &name, strlen(name), false, NULL, false);
+ recursion(var->type, &name, strlen(name), row_major, NULL, false);
ralloc_free(name);
} else if (t->is_record_or_array_of()) {
char *name = ralloc_strdup(NULL, var->name);
- recursion(var->type, &name, strlen(name), false, NULL, false);
+ recursion(var->type, &name, strlen(name), row_major, NULL, false);
ralloc_free(name);
} else if (t->is_interface()) {
char *name = ralloc_strdup(NULL, var->type->name);
- recursion(var->type, &name, strlen(name), false, NULL, false);
+ recursion(var->type, &name, strlen(name), row_major, NULL, false);
ralloc_free(name);
} else if (t->is_array() && t->fields.array->is_interface()) {
char *name = ralloc_strdup(NULL, var->type->fields.array->name);
- recursion(var->type, &name, strlen(name), false, NULL, false);
+ recursion(var->type, &name, strlen(name), row_major, NULL, false);
ralloc_free(name);
} else {
- this->visit_field(t, var->name, false, NULL, false);
+ this->visit_field(t, var->name, row_major, NULL, false);
}
}
@@ -180,8 +182,23 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field);
}
+ /* The layout of structures at the top level of the block is set
+ * during parsing. For matrices contained in multiple levels of
+ * structures in the block, the inner structures have no layout.
+ * These cases must potentially inherit the layout from the outer
+ * levels.
+ */
+ bool field_row_major = row_major;
+ const enum glsl_matrix_layout matrix_layout =
+ glsl_matrix_layout(t->fields.structure[i].matrix_layout);
+ if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) {
+ field_row_major = true;
+ } else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) {
+ field_row_major = false;
+ }
+
recursion(t->fields.structure[i].type, name, new_length,
- t->fields.structure[i].matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR,
+ field_row_major,
record_type,
(i + 1) == t->length);
--
1.8.1.4
More information about the mesa-dev
mailing list