std140 layout

Hey there,

i’ve a question regarding the std140 layout.

In my shader i have a uniform block like this:

layout(std140) uniform GeometryInfos {
ivec2 info[32];
};

and i am filling the UBO with ivec2s.

From the specification the data should be packed tightly within the buffer memory.
But unfortunately it does seem that the values are not tightly packed, because values are skipped if i access the array above. But it’s working if i declare the block like

layout(std140) uniform GeometryInfos {
ivec4 info[32];
};

Then the first ivec2 is in info[0].xy and the second is in info[0].zw.

What’s going wrong here? How can i use a ivec2 array without adding a padding to the data.

While rule 2 of the std140 spec say the base alignment of a ivec2 is 2N, rule 4 specifies the stride for arrays:

(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.

That is where the alignment of 4N is coming from.

You can do this in HLSL using a cast, so I’d expect that the same is also possible in GLSL but I’m not certain of the syntax. Here’s a HLSL example:

float4 PackedValues[MAX_PACKED_VALUES];
static float Values[MAX_VALUES] = (float[MAX_VALUES]) PackedValues;

In this case it’s unpacking an array of float4 (vec4 in GLSL) to an array of single floats, which can then be individually indexed. MAX_PACKED_VALUES is equal to MAX_VALUES / 4.

Thanks for your answers, i’ll try that out mhagain.

Regarding:

(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.

If i understand it right, then the alignment will always be rounded up to the base alignment of a vec4.
Isn’t this then superfluous:

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)

If its rounded to the base alignment of a vec4 anyway?

1 Like

Isn’t this then superfluous…If its rounded to the base alignment of a vec4 anyway?

There are dvec’s that can use up to 8N, and perhaps they were future-proofing the feature for other types that may exceed the size of a vec4.

1 Like

I see. Thanks for the clarification.