This catches Mesa bug 104492 on radeonsi. The existing std140/430 tests don't assign whole struct variables, only individual struct members, which does not trigger the bug. ---
Timothy Arceri recommended that I turn my stand-alone test case for this bug into a piglit test case, which is a great idea. So here it is. On my system, it fails using a recent Mesa git version and passes after applying the patch [1] I sent to the mesa-dev list. [1] https://lists.freedesktop.org/archives/mesa-dev/2018-January/181157.html Please make extra-sure to double-check the expected buffer locations at the bottom of the new file to see if they comply with std140/430 rules. My OpenGL experience is quite limited, but to the best of my understanding of the spec, this is how it should work. I wondered if the OpenGL/GLSL requirements could be relaxed as long as the extension is available, but I'm not sure how to test this, so I kept the requirements from basic.shader_test for SSBO. .../memory-layouts-struct-deref.shader_test | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tests/spec/arb_shader_storage_buffer_object/execution/memory-layouts-struct-deref.shader_test diff --git a/tests/spec/arb_shader_storage_buffer_object/execution/memory-layouts-struct-deref.shader_test b/tests/spec/arb_shader_storage_buffer_object/execution/memory-layouts-struct-deref.shader_test new file mode 100644 index 000000000..4cd50f498 --- /dev/null +++ b/tests/spec/arb_shader_storage_buffer_object/execution/memory-layouts-struct-deref.shader_test @@ -0,0 +1,85 @@ +# Tests std140/std430 memory layouts of SSBOs when dereferencing structs that +# contain arrays and/or other structs. + +# std140 rule #4: +# If the member is an array of scalars or vectors, the base alignment and +# array stride are set to [..] and rounded up to the base alignment of a vec4. +# -> array stride and alignment of uint[] is rounded up to 16. + +# std140 rule #9: +# If the member is a structure, the base alignment of the structure is N, +# where N is the largest base alignment value of any of its members, and +# rounded up to the base alignment of a vec4. +# -> offsets for first members of sub-structs are rounded up to 16*n bytes. + +# std430: +# 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. +# -> array stride and alignment of uint[] equals the size of uint, i.e. 4. +# -> offsets for first members of sub-structs containing only uints are +# rounded up to 4*n bytes. + +# Mesa bug 104492 describes an issue where Mesa would not respect those +# std430 alignment and padding rules when accessing a struct inside a std430 +# buffer, and would assume std140 alignments and struct/array sizes instead. + +# Therefore, create 1 SSBO using std140 and 1 SSBO using std430, then assign +# a value to the struct in the buffer blocks. After the draw call, probe the +# SSBOs to make sure the values end up at the correct buffer offsets. + +[require] +GL >= 3.3 +GLSL >= 3.30 +GL_ARB_shader_storage_buffer_object + +[vertex shader passthrough] + +[fragment shader] +#version 330 +#extension GL_ARB_shader_storage_buffer_object: require + +struct T { + uint c; +}; + +struct S { + uint a; + uint b[2]; + T t; +}; + +layout(binding = 0, std140) buffer ssbo_std140 { S s140; }; +layout(binding = 1, std430) buffer ssbo_std430 { S s430; }; + +void main() { + S s = S(42u, uint[2](1337u, 4711u), T(815u)); + s140 = s; + s430 = s; +} + +[test] +ssbo 0 64 +ssbo 1 64 # 16 should be enough for std430, but assume that std140 is used + +draw rect -1 -1 2 2 + +probe ssbo uint 0 0 == 42 # a +probe ssbo uint 0 4 == 0 # b[0] should NOT end up here +probe ssbo uint 0 8 == 0 # b[1] should NOT end up here +probe ssbo uint 0 12 == 0 # c should NOT end up here +probe ssbo uint 0 16 == 1337 # b[0] +probe ssbo uint 0 20 == 0 # b[1] should NOT end up here (stride 16!) +probe ssbo uint 0 32 == 4711 # b[1] +probe ssbo uint 0 48 == 815 # c (b has padding, and T is 16n-aligned) + +probe ssbo uint 1 0 == 42 # a +probe ssbo uint 1 4 == 1337 # b[0] +probe ssbo uint 1 8 == 4711 # b[1] (array stride is 4) +probe ssbo uint 1 12 == 815 # c (base alignment for T is 4) +probe ssbo uint 1 16 == 0 # b[0] should NOT end up here +probe ssbo uint 1 20 == 0 # b[1] should NOT end up here +probe ssbo uint 1 32 == 0 # b[1] should NOT end up here +probe ssbo uint 1 48 == 0 # c should NOT end up here -- 2.14.1 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit