GL_ARB_enhanced_layouts: consider std140 rules
In the case of UBOs and SSBOs, the offset for a block member depends
on the base alignment of its type. When the block uses the std140
packaging we have to take into account its specific rules for the
calculation of the base alignment for such data type.
From the GL_ARB_enhanced_layouts spec:
"The specified offset must be a multiple of the base alignment of
the type of the block member it qualifies, or a compile-time
error results."
From page 61 (page 74 of the PDF) of the OpenGL 3.1 spec:
"2.11. VERTEX SHADERS
...
Standard Uniform Block Layout
...
When using the std140 storage layout, structures will be laid out
in buffer storage with its members stored in monotonically
increasing order based on their location in the declaration. A
structure and each structure member have a base offset and a base
alignment, from which an aligned offset is computed by rounding
the base offset up to a multiple of the base alignment.
...
1. If the member is a scalar consuming N basic machine units, the
base alignment is N.
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.
3. If the member is a three-component vector with components
consuming N basic machine units, the base alignment is 4N .
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. The
array may have padding at the end; the base offset of the
member following the array is rounded up to the next multiple
of the base alignment.
5. If the member is a column-major matrix with C columns and R
rows, the matrix is stored identically to an array of C column
vectors with R compo- nents each, according to rule (4)."
From page 128 (page 149 of the PDF) of the OpenGL 4.3 spec:
"7.8 Shader Buffer Variables and Shader Storage Blocks
...
Buffer variables in shader storage blocks are represented in
memory in the same way as uniforms stored in uniform blocks, as
described in section 7.6.2.1. When a program is linked
successfully, each active buffer variable is assigned an offset
relative to the base of the buffer object binding associated with
its shader storage block. For buffer variables declared as arrays
and matrices, strides between array elements or matrix columns or
rows will also be assigned. Offsets and strides of buffer
variables will be assigned in an implementation-dependent manner
unless the shader storage block is declared using the std140 or
std430 storage layout qualifiers. For std140 and std430 shader
storage blocks, offsets will be assigned using the method
described in section 7.6.2.2."
Affects:
GL44-CTS.enhanced_layouts.uniform_block_member_invalid_offset_alignment
GL44-CTS.enhanced_layouts.ssb_member_invalid_offset_alignment
Components: OpenGL
VK-GL-CTS issue: 519
Change-Id: I5176d555605a8c482377ebfa5fbf16bc0dbf741a