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

NameBytes
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

NameBytes
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

NameBytes
int8[][b---][----][----][----]
int16[][bb--][----][----][----]
int32[][bbbb][----][----][----]
int64[][bbbb][bbbb][----][----]
float[][bbbb][----][----][----]

STD430

NameBytes
int8[][b]
int16[][bb]
int32[][bbbb]
int64[][bbbb][bbbb]
float[][bbbb]

Vector Arrays

STD140

NameBytes
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

NameBytes
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

NameBytes
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

NameBytes
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

NameBytes
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

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

STDArray StrideBytes
14016{w [bbbb]}
{x [bbbb]}
[----][----]
4308{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.

STDArray StrideBytes
14032{x {a [bbbb]}
   {b [bbbb]}
   [----][----]
{y [bbbb][----][----][----]}
43012{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.

STDArray StrideBytes
14032{w [bbbb][----]}
{x [bbbb][bbbb]}
{y [bbbb][----]}
[----][----]
43024{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).

STDArray StrideBytes
14032{w [bbbb][----][----][----]}
{x [bbbb][bbbb][bbbb]}
{y [bbbb]}
43032{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.

STDArray StrideBytes
14048{w [bbbb][----][----][----]}
{x [bbbb][bbbb][bbbb][----]}
{y [bbbb][bbbb]}
[----][----]
43048{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.

STDArray StrideBytes
14064{w [bbbb][----][----][----]}
{x [bbbb][bbbb][----][----]
   [bbbb][bbbb][----][----]}
{y [bbbb][----][----][----]}
43032{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.

STDArray StrideBytes
14048{w [bbbb][----][----][----]}
{x a{[bbbb]}
   b{[bbbb]}
   c{[bbbb]}
     [----]
{y [bbbb][----][----][----]}
43020{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.

STDArray StrideBytes
14096{w [bbbb][----][----][----]}
{x {a [bbbb]}
   {b [bbbb]}
      [----][----]
   {c [bbbb][----][----][----]
      [bbbb][----][----][----]
      [bbbb][----][----][----]}}
{y [bbbb][----][----][----]}
43028{w [bbbb]}
{x a{[bbbb]}
   {b [bbbb]}
   {c [bbbb][bbbb][bbbb] }}
{y [bbbb]}