# 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\ | [bbbb][bbbb] |
| vec3\ | [bbbb][bbbb][bbbb][----] |
| vec4\ | [bbbb][bbbb][bbbb][bbbb] |
| vec2\  | [bb] |
| vec3\  | [bbb-] |
| vec4\  | [bbbb] |
| vec2\ | [bbbb] |
| vec3\ | [bbbb][bb--] |
| vec4\ | [bbbb][bbbb] |
| vec2\ | [bbbb][bbbb] |
| vec3\ | [bbbb][bbbb][bbbb][----] |
| vec4\ | [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\[] | [bbbb][bbbb][----][----] |
| vec3\[] | [bbbb][bbbb][bbbb][----] |
| vec4\[] | [bbbb][bbbb][bbbb][bbbb] |
| vec2\[]  | [bb--][----][----][----] |
| vec2\[] | [bbbb][----][----][----] |
| vec2\[] | [bbbb][bbbb][----][----] |
| vec3\[]  | [bbb-][----][----][----] |
| vec3\[] | [bbbb][bb--][----][----] |
| vec3\[] | [bbbb][bbbb][bbbb][----] |
| vec4\[]  | [bbbb][----][----][----] |
| vec4\[] | [bbbb][bbbb][----][----] |
| vec4\[] | [bbbb][bbbb][bbbb][bbbb] |

### STD430
| Name | Bytes |
|------|-------|
| vec2\[] | [bbbb][bbbb] |
| vec3\[] | [bbbb][bbbb][bbbb][----] |
| vec4\[] | [bbbb][bbbb][bbbb][bbbb] |
| vec2\[]  | [bb] |
| vec2\[] | [bbbb] |
| vec2\[] | [bbbb][bbbb] |
| vec3\[]  | [bbb-] |
| vec3\[] | [bbbb][bb--] |
| vec3\[] | [bbbb][bbbb][bbbb][----] |
| vec4\[]  | [bbbb] |
| vec4\[] | [bbbb][bbbb] |
| vec4\[] | [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\  | [bb--][----][----][----]
[bb--][----][----][----]
| | mat2x2\ | [bbbb][----][----][----]
[bbbb][----][----][----]
| | mat2x2\ | [bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
| | mat2x3\ | [bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
| | mat2x4\ | [bbbb][bbbb][bbbb][bbbb]
[bbbb][bbbb][bbbb][bbbb]
| | mat3x2\ | [bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
| | mat4x2\ | [bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
| | mat4x3\ | [bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
| ### STD430 | Name | Bytes | |------|-------| | mat2x2\ | [bbbb]
[bbbb]
| | mat2x2\ | [bbbb][bbbb]
[bbbb][bbbb]
| | mat2x3\ | [bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
| | mat2x4\ | [bbbb][bbbb][bbbb][bbbb]
[bbbb][bbbb][bbbb][bbbb]
| | mat2x2\ | [bb]
[bb]
| | mat3x2\ | [bbbb][bbbb]
[bbbb][bbbb]
[bbbb][bbbb]
| | mat3x3\ | [bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
| | mat4x2\ | [bbbb][bbbb][bbbb][bbbb]
[bbbb][bbbb][bbbb][bbbb]
| | mat4x3\ | [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\[] | [bb--][----][----][----]
[bb--][----][----][----]
| | mat2x2\[] | [bbbb][----][----][----]
[bbbb][----][----][----]
| | mat2x2\[] | [bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
| | mat2x3\[] | [bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
| | mat2x4\[] | [bbbb][bbbb][bbbb][bbbb]
[bbbb][bbbb][bbbb][bbbb]
| | mat3x2\[] | [bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
| | mat4x2\[] | [bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
[bbbb][bbbb][----][----]
| | mat4x3\[] | [bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
| ### STD430 | Name | Bytes | |------|-------| | mat2x2\[] | [bbbb]
[bbbb]
| | mat2x2\[] | [bbbb][bbbb]
[bbbb][bbbb]
| | mat2x3\[] | [bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
| | mat2x4\[] | [bbbb][bbbb][bbbb][bbbb]
[bbbb][bbbb][bbbb][bbbb]
| | mat2x2\[] | [bb]
[bb]
| | mat3x2\[] | [bbbb][bbbb][bbbb][bbbb]
[bbbb][bbbb]
| | mat3x3\[] | [bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
[bbbb][bbbb][bbbb][----]
| | mat4x2\[] | [bbbb][bbbb][bbbb][bbbb]
[bbbb][bbbb][bbbb][bbbb]
| | mat4x3\[] | [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 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 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 x; vec2 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 x; float y; } ``` In STD140 the `mat2x2` 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]}
|