12 KiB
Memory Layout Examples
Note, this is how we'll layout the data in Amber. Some of these types don't exist in standard GLSL (they exist in GL_EXT_shader_explicit_arithmetic_types). We allow them in Amber to give flexibility in the data provided, but attempt to follow the layout rules with all types for consistency.
For the purposes of this document, all scalars are stored in little-endian. The lower number components of a vector appear earlier than higher numbered ones. Similar for columns and rows of matrices.
All type names used in the file are the Amber names. They differ from GLSL but are a bit more explicit, so are used here for clarity.
Scalars
Name | Bytes |
---|---|
int8 | [b] |
uint8 | [b] |
int16 | [bb] |
uint16 | [bb] |
float16 | [bb] |
int32 | [bbbb] |
uint32 | [bbbb] |
float | [bbbb] |
int64 | [bbbb][bbbb] |
uint64 | [bbbb][bbbb] |
double | [bbbb][bbbb] |
Vectors
STD140 & STD430
Name | Bytes |
---|---|
vec2<float> | [bbbb][bbbb] |
vec3<float> | [bbbb][bbbb][bbbb][----] |
vec4<float> | [bbbb][bbbb][bbbb][bbbb] |
vec2<int8> | [bb] |
vec3<int8> | [bbb-] |
vec4<int8> | [bbbb] |
vec2<int16> | [bbbb] |
vec3<int16> | [bbbb][bb--] |
vec4<int16> | [bbbb][bbbb] |
vec2<int32> | [bbbb][bbbb] |
vec3<int32> | [bbbb][bbbb][bbbb][----] |
vec4<int32> | [bbbb][bbbb][bbbb][bbbb] |
Scalar Arrays
STD140
Name | Bytes |
---|---|
int8[] | [b---][----][----][----] |
int16[] | [bb--][----][----][----] |
int32[] | [bbbb][----][----][----] |
int64[] | [bbbb][bbbb][----][----] |
float[] | [bbbb][----][----][----] |
STD430
Name | Bytes |
---|---|
int8[] | [b] |
int16[] | [bb] |
int32[] | [bbbb] |
int64[] | [bbbb][bbbb] |
float[] | [bbbb] |
Vector Arrays
STD140
Name | Bytes |
---|---|
vec2<float>[] | [bbbb][bbbb][----][----] |
vec3<float>[] | [bbbb][bbbb][bbbb][----] |
vec4<float>[] | [bbbb][bbbb][bbbb][bbbb] |
vec2<int8>[] | [bb--][----][----][----] |
vec2<int16>[] | [bbbb][----][----][----] |
vec2<int32>[] | [bbbb][bbbb][----][----] |
vec3<int8>[] | [bbb-][----][----][----] |
vec3<int16>[] | [bbbb][bb--][----][----] |
vec3<int32>[] | [bbbb][bbbb][bbbb][----] |
vec4<int8>[] | [bbbb][----][----][----] |
vec4<int16>[] | [bbbb][bbbb][----][----] |
vec4<int32>[] | [bbbb][bbbb][bbbb][bbbb] |
STD430
Name | Bytes |
---|---|
vec2<float>[] | [bbbb][bbbb] |
vec3<float>[] | [bbbb][bbbb][bbbb][----] |
vec4<float>[] | [bbbb][bbbb][bbbb][bbbb] |
vec2<int8>[] | [bb] |
vec2<int16>[] | [bbbb] |
vec2<int32>[] | [bbbb][bbbb] |
vec3<int8>[] | [bbb-] |
vec3<int16>[] | [bbbb][bb--] |
vec3<int32>[] | [bbbb][bbbb][bbbb][----] |
vec4<int8>[] | [bbbb] |
vec4<int16>[] | [bbbb][bbbb] |
vec4<int32>[] | [bbbb][bbbb][bbbb][bbbb] |
Matrices (All matrices are column-major matrices, format is matCxR)
Note, GLSL does not have matrices with integer components although they exist in other shader languages.
STD140
Name | Bytes |
---|---|
mat2x2<int8> | [bb--][----][----][----] [bb--][----][----][----] |
mat2x2<fp16> | [bbbb][----][----][----] [bbbb][----][----][----] |
mat2x2<float> | [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] |
mat2x3<float> | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
mat2x4<float> | [bbbb][bbbb][bbbb][bbbb] [bbbb][bbbb][bbbb][bbbb] |
mat3x2<float> | [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] |
mat4x2<float> | [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] |
mat4x3<float> | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
STD430
Name | Bytes |
---|---|
mat2x2<fp16> | [bbbb] [bbbb] |
mat2x2<float> | [bbbb][bbbb] [bbbb][bbbb] |
mat2x3<float> | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
mat2x4<float> | [bbbb][bbbb][bbbb][bbbb] [bbbb][bbbb][bbbb][bbbb] |
mat2x2<int8> | [bb] [bb] |
mat3x2<float> | [bbbb][bbbb] [bbbb][bbbb] [bbbb][bbbb] |
mat3x3<float> | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
mat4x2<float> | [bbbb][bbbb][bbbb][bbbb] [bbbb][bbbb][bbbb][bbbb] |
mat4x3<float> | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
Matrix Array (All matrices are column-major matrices).
In the examples shown the array stride is equal to the base alignment of the matrix so no extra padding is added between elements.
STD140
Name | Bytes |
---|---|
mat2x2<int8>[] | [bb--][----][----][----] [bb--][----][----][----] |
mat2x2<fp16>[] | [bbbb][----][----][----] [bbbb][----][----][----] |
mat2x2<float>[] | [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] |
mat2x3<float>[] | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
mat2x4<float>[] | [bbbb][bbbb][bbbb][bbbb] [bbbb][bbbb][bbbb][bbbb] |
mat3x2<float>[] | [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] |
mat4x2<float>[] | [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] [bbbb][bbbb][----][----] |
mat4x3<float>[] | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
STD430
Name | Bytes |
---|---|
mat2x2<fp16>[] | [bbbb] [bbbb] |
mat2x2<float>[] | [bbbb][bbbb] [bbbb][bbbb] |
mat2x3<float>[] | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
mat2x4<float>[] | [bbbb][bbbb][bbbb][bbbb] [bbbb][bbbb][bbbb][bbbb] |
mat2x2<int8>[] | [bb] [bb] |
mat3x2<float>[] | [bbbb][bbbb][bbbb][bbbb] [bbbb][bbbb] |
mat3x3<float>[] | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
mat4x2<float>[] | [bbbb][bbbb][bbbb][bbbb] [bbbb][bbbb][bbbb][bbbb] |
mat4x3<float>[] | [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] [bbbb][bbbb][bbbb][----] |
Structures
struct {
int32 w;
float x;
}
The STD140 pads 8 bytes at the end to become a multiple of 16 bytes.
STD | Array Stride | Bytes |
---|---|---|
140 | 16 | {w [bbbb]} {x [bbbb]} [----][----] |
430 | 8 | {w [bbbb]} {x [bbbb]} |
struct {
struct {
int32 a;
float b;
} x;
float y;
}
The STD140 pads 8 bytes at the end to become a multiple of 16 bytes.
STD | Array Stride | Bytes |
---|---|---|
140 | 32 | {x {a [bbbb]} {b [bbbb]} [----][----] {y [bbbb][----][----][----]} |
430 | 12 | {x {a [bbbb]} {b [bbbb]} {y [bbbb]} |
struct {
int32 w;
vec2<float> x;
float y;
}
For both cases, the vec2
is the member with the largest base alignment
requirement, so giving a base alignment of 8 bytes. The STD140 cases pads 8
bytes at the end (in the array element case) to become a multiple of 16.
STD | Array Stride | Bytes |
---|---|---|
140 | 32 | {w [bbbb][----]} {x [bbbb][bbbb]} {y [bbbb][----]} [----][----] |
430 | 24 | {w [bbbb][----]} {x [bbbb][bbbb]} {y [bbbb][----]} |
struct {
int32 w;
vec3<float> x;
float y;
}
The vec3
expands to a vec4
. This gives a base alignment of 16 bytes. So
the w
pads to 16 bytes. the float y
is packed into the vec3
as there is
space (effectively making it a vec4).
STD | Array Stride | Bytes |
---|---|---|
140 | 32 | {w [bbbb][----][----][----]} {x [bbbb][bbbb][bbbb]} {y [bbbb]} |
430 | 32 | {w [bbbb][----][----][----]} {x [bbbb][bbbb][bbbb]} {y [bbbb]} |
struct {
int32 w;
vec3<float> x;
vec2<float> y;
}
The vec3
expands to a vec4
. This gives a base alignment of 16 bytes. So
the w
pads to 16 bytes.
STD | Array Stride | Bytes |
---|---|---|
140 | 48 | {w [bbbb][----][----][----]} {x [bbbb][bbbb][bbbb][----]} {y [bbbb][bbbb]} [----][----] |
430 | 48 | {w [bbbb][----][----][----]} {x [bbbb][bbbb][bbbb][----]} {y [bbbb][bbbb]} [----][----] |
struct {
int32 w;
mat2x2<float> x;
float y;
}
In STD140 the mat2x2<float>
has a base alignment of 16 bytes (the mat2x2 is, effectively,
an array of vec2's The vec2's have a size of 8 bytes this size rounds up to a vec4, so 16 bytes).
In STD430, the round up doesn't happen, so the base alignment is 8 bytes.
STD | Array Stride | Bytes |
---|---|---|
140 | 64 | {w [bbbb][----][----][----]} {x [bbbb][bbbb][----][----] [bbbb][bbbb][----][----]} {y [bbbb][----][----][----]} |
430 | 32 | {w [bbbb][----]} {x [bbbb][bbbb][bbbb][bbbb]} {y [bbbb][----]} |
struct {
int32 w;
struct {
int32 a;
int32 b;
float c;
} x;
float y;
}
The base alignment of the largest item is 4 bytes. In STD140, this rounds up to 16 bytes because of the substructure.
STD | Array Stride | Bytes |
---|---|---|
140 | 48 | {w [bbbb][----][----][----]} {x a{[bbbb]} b{[bbbb]} c{[bbbb]} [----] {y [bbbb][----][----][----]} |
430 | 20 | {w [bbbb]} {x a{[bbbb]} b{[bbbb]} c{[bbbb]} {y [bbbb]} |
struct {
int32 w;
struct {
int32 a;
int32 b;
float c[3];
} x;
float y;
}
The int a
and int b
end up packing together so 16 bytes of padding are added (instead of 24 bytes).
The float c[3]
has an array stride of 16 bytes in STD140 and 4 bytes in STD430.
STD | Array Stride | Bytes |
---|---|---|
140 | 96 | {w [bbbb][----][----][----]} {x {a [bbbb]} {b [bbbb]} [----][----] {c [bbbb][----][----][----] [bbbb][----][----][----] [bbbb][----][----][----]}} {y [bbbb][----][----][----]} |
430 | 28 | {w [bbbb]} {x a{[bbbb]} {b [bbbb]} {c [bbbb][bbbb][bbbb] }} {y [bbbb]} |