diff options
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 38 | ||||
-rw-r--r-- | src/glsl/ir.h | 5 | ||||
-rw-r--r-- | src/glsl/link_uniform_blocks.cpp | 2 | ||||
-rw-r--r-- | 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 d5699935e60..b4670076f61 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->without_array()->is_matrix() || field_type->without_array()->is_record()) { - 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_INHERITED, 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_INHERITED; + 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_INHERITED + ? 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_INHERITED) { + var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED + ? 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 de28f87e63b..49f74face65 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 3768205ee1f..536fcd45878 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->without_array()->is_matrix() && 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 5137e3a3910..ecd414b8ceb 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -71,6 +71,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 @@ -108,7 +110,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) { @@ -132,22 +134,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->without_array()->is_record()) { 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); } } @@ -181,8 +183,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); |