summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Iglesias Gonsalvez <[email protected]>2015-10-01 16:46:55 +0200
committerSamuel Iglesias Gonsalvez <[email protected]>2015-10-13 15:58:54 +0200
commit6a506689db287ea41b3374bd3174a5da78b56d16 (patch)
treecd5585a6f1074f50fc3e729af99629220fa866b3
parent685335639a982b398d305b8f314fc3857fcdbead (diff)
glsl: fix matrix stride calculation for std430's row_major matrices with two columns
This is the result of applying several rules: 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." In summary: vec2 has a base alignment of 2*N, a row-major mat2xY is stored like an array of Y row vectors with 2 components each. Because of std430 storage layout, the base alignment of the array of vectors is not rounded up to vec4, so it is still 2*N. Fixes 15 dEQP tests: dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_lowp_mat2 dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_mediump_mat2 dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_highp_mat2 dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_lowp_mat2x3 dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_mediump_mat2x3 dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_highp_mat2x3 dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_lowp_mat2x4 dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_mediump_mat2x4 dEQP-GLES31.functional.ssbo.layout.single_basic_type.std430.row_major_highp_mat2x4 dEQP-GLES31.functional.ssbo.layout.single_basic_array.std430.row_major_mat2 dEQP-GLES31.functional.ssbo.layout.single_basic_array.std430.row_major_mat2x3 dEQP-GLES31.functional.ssbo.layout.single_basic_array.std430.row_major_mat2x4 dEQP-GLES31.functional.ssbo.layout.instance_array_basic_type.std430.row_major_mat2 dEQP-GLES31.functional.ssbo.layout.instance_array_basic_type.std430.row_major_mat2x3 dEQP-GLES31.functional.ssbo.layout.instance_array_basic_type.std430.row_major_mat2x4 v2: - Add spec quote in both commit log and code (Timothy) Signed-off-by: Samuel Iglesias Gonsalvez <[email protected]> Reviewed-by: Marta Lofstedt <[email protected]>
-rw-r--r--src/glsl/lower_ubo_reference.cpp26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/glsl/lower_ubo_reference.cpp b/src/glsl/lower_ubo_reference.cpp
index 247620e6148..c8ec5c19f41 100644
--- a/src/glsl/lower_ubo_reference.cpp
+++ b/src/glsl/lower_ubo_reference.cpp
@@ -744,7 +744,31 @@ lower_ubo_reference_visitor::emit_access(bool is_write,
* or 32 depending on the number of columns.
*/
assert(matrix_columns <= 4);
- unsigned matrix_stride = glsl_align(matrix_columns * N, 16);
+ 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 glsl_type *deref_type = deref->type->base_type == GLSL_TYPE_FLOAT ?
glsl_type::float_type : glsl_type::double_type;