diff --git a/src/compiler/glsl/lower_buffer_access.cpp b/src/compiler/glsl/lower_buffer_access.cpp index caffaf9bfb2..219e03e550d 100644 --- a/src/compiler/glsl/lower_buffer_access.cpp +++ b/src/compiler/glsl/lower_buffer_access.cpp @@ -36,6 +36,7 @@ #include "main/macros.h" #include "util/list.h" #include "glsl_parser_extras.h" +#include "linker.h" using namespace ir_builder; @@ -58,8 +59,8 @@ lower_buffer_access::emit_access(void *mem_ctx, ir_variable *base_offset, unsigned int deref_offset, bool row_major, - int matrix_columns, - unsigned int packing, + const glsl_type *matrix_type, + enum glsl_interface_packing packing, unsigned int write_mask) { if (deref->type->is_record()) { @@ -78,7 +79,7 @@ lower_buffer_access::emit_access(void *mem_ctx, emit_access(mem_ctx, is_write, field_deref, base_offset, deref_offset + field_offset, - row_major, 1, packing, + row_major, NULL, packing, writemask_for_size(field_deref->type->vector_elements)); field_offset += field->type->std140_size(row_major); @@ -98,7 +99,7 @@ lower_buffer_access::emit_access(void *mem_ctx, element); emit_access(mem_ctx, is_write, element_deref, base_offset, deref_offset + i * array_stride, - row_major, 1, packing, + row_major, NULL, packing, writemask_for_size(element_deref->type->vector_elements)); } return; @@ -117,7 +118,7 @@ lower_buffer_access::emit_access(void *mem_ctx, int size_mul = deref->type->is_64bit() ? 8 : 4; emit_access(mem_ctx, is_write, col_deref, base_offset, deref_offset + i * size_mul, - row_major, deref->type->matrix_columns, packing, + row_major, deref->type, packing, writemask_for_size(col_deref->type->vector_elements)); } else { int size_mul; @@ -143,7 +144,7 @@ lower_buffer_access::emit_access(void *mem_ctx, emit_access(mem_ctx, is_write, col_deref, base_offset, deref_offset + i * size_mul, - row_major, deref->type->matrix_columns, packing, + row_major, deref->type, packing, writemask_for_size(col_deref->type->vector_elements)); } } @@ -159,45 +160,14 @@ lower_buffer_access::emit_access(void *mem_ctx, is_write ? write_mask : (1 << deref->type->vector_elements) - 1; insert_buffer_access(mem_ctx, deref, deref->type, offset, mask, -1); } else { - unsigned N = deref->type->is_64bit() ? 8 : 4; - /* We're dereffing a column out of a row-major matrix, so we * gather the vector from each stored row. - */ + */ assert(deref->type->is_float() || deref->type->is_double()); + assert(matrix_type != NULL); - /* Matrices, row_major or not, are stored as if they were - * arrays of vectors of the appropriate size in std140. - * Arrays have their strides rounded up to a vec4, so the - * matrix stride is always 16. However a double matrix may either be 16 - * or 32 depending on the number of columns. - */ - assert(matrix_columns <= 4); - unsigned matrix_stride = 0; - /* Matrix stride for std430 mat2xY matrices are not rounded up to - * vec4 size. From OpenGL 4.3 spec, section 7.6.2.2 "Standard Uniform - * Block Layout": - * - * "2. If the member is a two- or four-component vector with components - * consuming N basic machine units, the base alignment is 2N or 4N, - * respectively." [...] - * "4. If the member is an array of scalars or vectors, the base alignment - * and array stride are set to match the base alignment of a single array - * element, according to rules (1), (2), and (3), and rounded up to the - * base alignment of a vec4." [...] - * "7. If the member is a row-major matrix with C columns and R rows, the - * matrix is stored identically to an array of R row vectors with C - * components each, according to rule (4)." [...] - * "When using the std430 storage layout, shader storage blocks will be - * laid out in buffer storage identically to uniform and shader storage - * blocks using the std140 layout, except that the base alignment and - * stride of arrays of scalars and vectors in rule 4 and of structures in - * rule 9 are not rounded up a multiple of the base alignment of a vec4." - */ - if (packing == GLSL_INTERFACE_PACKING_STD430 && matrix_columns == 2) - matrix_stride = 2 * N; - else - matrix_stride = glsl_align(matrix_columns * N, 16); + const unsigned matrix_stride = + link_calculate_matrix_stride(matrix_type, row_major, packing); const glsl_type *deref_type = deref->type->is_float() ? glsl_type::float_type : glsl_type::double_type; @@ -325,13 +295,13 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx, ir_rvalue **offset, unsigned *const_offset, bool *row_major, - int *matrix_columns, + const glsl_type **matrix_type, const glsl_struct_field **struct_field, enum glsl_interface_packing packing) { *offset = new(mem_ctx) ir_constant(0u); *row_major = is_dereferenced_thing_row_major(deref); - *matrix_columns = 1; + *matrix_type = NULL; /* Calculate the offset to the start of the region of the UBO * dereferenced by *rvalue. This may be a variable offset if an @@ -368,7 +338,7 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx, array_stride = 4; if (deref_array->array->type->is_64bit()) array_stride *= 2; - *matrix_columns = deref_array->array->type->matrix_columns; + *matrix_type = deref_array->array->type; } else if (deref_array->type->without_array()->is_interface()) { /* We're processing an array dereference of an interface instance * array. The thing being dereferenced *must* be a variable diff --git a/src/compiler/glsl/lower_buffer_access.h b/src/compiler/glsl/lower_buffer_access.h index 9e89d324bed..bd177ca142f 100644 --- a/src/compiler/glsl/lower_buffer_access.h +++ b/src/compiler/glsl/lower_buffer_access.h @@ -48,14 +48,16 @@ public: void emit_access(void *mem_ctx, bool is_write, ir_dereference *deref, ir_variable *base_offset, unsigned int deref_offset, - bool row_major, int matrix_columns, - unsigned int packing, unsigned int write_mask); + bool row_major, const glsl_type *matrix_type, + enum glsl_interface_packing packing, + unsigned int write_mask); bool is_dereferenced_thing_row_major(const ir_rvalue *deref); void setup_buffer_access(void *mem_ctx, ir_rvalue *deref, ir_rvalue **offset, unsigned *const_offset, - bool *row_major, int *matrix_columns, + bool *row_major, + const glsl_type **matrix_type, const glsl_struct_field **struct_field, enum glsl_interface_packing packing); diff --git a/src/compiler/glsl/lower_shared_reference.cpp b/src/compiler/glsl/lower_shared_reference.cpp index 86afc5de924..5de269fde82 100644 --- a/src/compiler/glsl/lower_shared_reference.cpp +++ b/src/compiler/glsl/lower_shared_reference.cpp @@ -137,13 +137,13 @@ lower_shared_reference_visitor::handle_rvalue(ir_rvalue **rvalue) ir_rvalue *offset = NULL; unsigned const_offset = get_shared_offset(var); bool row_major; - int matrix_columns; + const glsl_type *matrix_type; assert(var->get_interface_type() == NULL); const enum glsl_interface_packing packing = GLSL_INTERFACE_PACKING_STD430; setup_buffer_access(mem_ctx, deref, &offset, &const_offset, - &row_major, &matrix_columns, NULL, packing); + &row_major, &matrix_type, NULL, packing); /* Now that we've calculated the offset to the start of the * dereference, walk over the type and emit loads into a temporary. @@ -163,7 +163,7 @@ lower_shared_reference_visitor::handle_rvalue(ir_rvalue **rvalue) deref = new(mem_ctx) ir_dereference_variable(load_var); emit_access(mem_ctx, false, deref, load_offset, const_offset, row_major, - matrix_columns, packing, 0); + matrix_type, packing, 0); *rvalue = deref; @@ -205,13 +205,13 @@ lower_shared_reference_visitor::handle_assignment(ir_assignment *ir) ir_rvalue *offset = NULL; unsigned const_offset = get_shared_offset(var); bool row_major; - int matrix_columns; + const glsl_type *matrix_type; assert(var->get_interface_type() == NULL); const enum glsl_interface_packing packing = GLSL_INTERFACE_PACKING_STD430; setup_buffer_access(mem_ctx, deref, &offset, &const_offset, - &row_major, &matrix_columns, NULL, packing); + &row_major, &matrix_type, NULL, packing); deref = new(mem_ctx) ir_dereference_variable(store_var); @@ -223,7 +223,7 @@ lower_shared_reference_visitor::handle_assignment(ir_assignment *ir) /* Now we have to write the value assigned to the temporary back to memory */ emit_access(mem_ctx, true, deref, store_offset, const_offset, row_major, - matrix_columns, packing, ir->write_mask); + matrix_type, packing, ir->write_mask); progress = true; } @@ -364,18 +364,18 @@ lower_shared_reference_visitor::lower_shared_atomic_intrinsic(ir_call *ir) ir_rvalue *offset = NULL; unsigned const_offset = get_shared_offset(var); bool row_major; - int matrix_columns; + const glsl_type *matrix_type; assert(var->get_interface_type() == NULL); const enum glsl_interface_packing packing = GLSL_INTERFACE_PACKING_STD430; buffer_access_type = shared_atomic_access; setup_buffer_access(mem_ctx, deref, &offset, &const_offset, - &row_major, &matrix_columns, NULL, packing); + &row_major, &matrix_type, NULL, packing); assert(offset); assert(!row_major); - assert(matrix_columns == 1); + assert(matrix_type == NULL); ir_rvalue *deref_offset = add(offset, new(mem_ctx) ir_constant(const_offset)); diff --git a/src/compiler/glsl/lower_ubo_reference.cpp b/src/compiler/glsl/lower_ubo_reference.cpp index e0745670df0..1e35b44d5fe 100644 --- a/src/compiler/glsl/lower_ubo_reference.cpp +++ b/src/compiler/glsl/lower_ubo_reference.cpp @@ -62,7 +62,7 @@ public: ir_rvalue **offset, unsigned *const_offset, bool *row_major, - int *matrix_columns, + const glsl_type **matrix_type, enum glsl_interface_packing packing); uint32_t ssbo_access_params(); ir_expression *ubo_load(void *mem_ctx, const struct glsl_type *type, @@ -274,7 +274,7 @@ lower_ubo_reference_visitor::setup_for_load_or_store(void *mem_ctx, ir_rvalue **offset, unsigned *const_offset, bool *row_major, - int *matrix_columns, + const glsl_type **matrix_type, enum glsl_interface_packing packing) { /* Determine the name of the interface block */ @@ -324,7 +324,7 @@ lower_ubo_reference_visitor::setup_for_load_or_store(void *mem_ctx, this->struct_field = NULL; setup_buffer_access(mem_ctx, deref, offset, const_offset, row_major, - matrix_columns, &this->struct_field, packing); + matrix_type, &this->struct_field, packing); } void @@ -346,7 +346,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue) ir_rvalue *offset = NULL; unsigned const_offset; bool row_major; - int matrix_columns; + const glsl_type *matrix_type; enum glsl_interface_packing packing = var->get_interface_type()-> @@ -362,7 +362,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue) */ setup_for_load_or_store(mem_ctx, var, deref, &offset, &const_offset, - &row_major, &matrix_columns, + &row_major, &matrix_type, packing); assert(offset); @@ -383,7 +383,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue) deref = new(mem_ctx) ir_dereference_variable(load_var); emit_access(mem_ctx, false, deref, load_offset, const_offset, - row_major, matrix_columns, packing, 0); + row_major, matrix_type, packing, 0); *rvalue = deref; progress = true; @@ -562,7 +562,7 @@ lower_ubo_reference_visitor::write_to_memory(void *mem_ctx, ir_rvalue *offset = NULL; unsigned const_offset; bool row_major; - int matrix_columns; + const glsl_type *matrix_type; enum glsl_interface_packing packing = var->get_interface_type()-> @@ -576,7 +576,7 @@ lower_ubo_reference_visitor::write_to_memory(void *mem_ctx, */ setup_for_load_or_store(mem_ctx, var, deref, &offset, &const_offset, - &row_major, &matrix_columns, + &row_major, &matrix_type, packing); assert(offset); @@ -591,7 +591,7 @@ lower_ubo_reference_visitor::write_to_memory(void *mem_ctx, deref = new(mem_ctx) ir_dereference_variable(write_var); emit_access(mem_ctx, true, deref, write_offset, const_offset, - row_major, matrix_columns, packing, write_mask); + row_major, matrix_type, packing, write_mask); } ir_visitor_status @@ -744,7 +744,7 @@ lower_ubo_reference_visitor::process_ssbo_unsized_array_length(ir_rvalue **rvalu ir_rvalue *base_offset = NULL; unsigned const_offset; bool row_major; - int matrix_columns; + const glsl_type *matrix_type; enum glsl_interface_packing packing = var->get_interface_type()-> @@ -760,7 +760,7 @@ lower_ubo_reference_visitor::process_ssbo_unsized_array_length(ir_rvalue **rvalu */ setup_for_load_or_store(mem_ctx, var, deref, &base_offset, &const_offset, - &row_major, &matrix_columns, + &row_major, &matrix_type, packing); /* array.length() = * max((buffer_object_size - offset_of_array) / stride_of_array, 0) @@ -982,7 +982,7 @@ lower_ubo_reference_visitor::lower_ssbo_atomic_intrinsic(ir_call *ir) ir_rvalue *offset = NULL; unsigned const_offset; bool row_major; - int matrix_columns; + const glsl_type *matrix_type; enum glsl_interface_packing packing = var->get_interface_type()-> @@ -993,11 +993,11 @@ lower_ubo_reference_visitor::lower_ssbo_atomic_intrinsic(ir_call *ir) setup_for_load_or_store(mem_ctx, var, deref, &offset, &const_offset, - &row_major, &matrix_columns, + &row_major, &matrix_type, packing); assert(offset); assert(!row_major); - assert(matrix_columns == 1); + assert(matrix_type == NULL); ir_rvalue *deref_offset = add(offset, new(mem_ctx) ir_constant(const_offset));