From e4bbf92ed30a953988307e33a295b438c0bcc975 Mon Sep 17 00:00:00 2001 From: Florian Will Date: Wed, 10 Jan 2018 12:04:46 +0100 Subject: [PATCH] glsl: respect matrix row stride for m[i][j] Using an array_stride of 4 (or 8 if type is 64-bit) for the j index is correct in many cases, including column_major matrices, but row_major matrices need to use the matrix row stride for the j index. Use link_calculate_matrix_stride() to calculate the matrix row stride in that case. --- src/compiler/glsl/lower_buffer_access.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/compiler/glsl/lower_buffer_access.cpp b/src/compiler/glsl/lower_buffer_access.cpp index ff6f9c1fcf..b08980bb86 100644 --- a/src/compiler/glsl/lower_buffer_access.cpp +++ b/src/compiler/glsl/lower_buffer_access.cpp @@ -309,6 +309,26 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx, array_stride = 4; if (deref_array->array->type->is_64bit()) array_stride *= 2; + + /* Loading a scalar out of a row-major matrix using m[i][j] + * requires extra work. In that case, this loop iteration is about + * the [j] index, so find out if the thing we try to index is + * another array deref, and indexes a matrix. + */ + const ir_rvalue *parent_deref = deref_array->array; + if (parent_deref->ir_type == ir_type_dereference_array) { + const ir_dereference_array *parent_deref_array = + (ir_dereference_array *) parent_deref; + const glsl_type *parent_type = parent_deref_array->array->type; + if (*row_major && parent_type->is_matrix()) { + /* This is the m[i][j] row-major matrix case. The correct + * row stride to use for calculating the offset resulting + * from the j index depends on the matrix type and packing. + */ + array_stride = link_calculate_matrix_stride(parent_type, + true, packing); + } + } } else if (deref_array->array->type->is_matrix() && *row_major) { /* When loading a vector out of a row major matrix, the * step between the columns (vectors) is the size of a -- 2.14.1