GL_ARB_enhanced_layouts: consider std140 rules
authorAndres Gomez <agomez@igalia.com>
Wed, 1 Mar 2017 13:43:24 +0000 (15:43 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Sat, 1 Jul 2017 10:29:50 +0000 (06:29 -0400)
commitff76012eb231ee06a23fec1612e5e15c2cee7a38
treedad762785b64f736767e1b62e10e822b39bd5653
parent9608a93248eacf37a00e892eb920986f1ceb9843
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
external/openglcts/modules/gl/gl4cEnhancedLayoutsTests.cpp
external/openglcts/modules/gl/gl4cEnhancedLayoutsTests.hpp