1
votes

In a compute shader I have a struct for a particle:

struct Particle {
    float delta;
    float start_posx;
    float start_posy;
    float start_posz;
    float restart;
    uint max_textures;
    float max_lifetime;
};

Now I want to use this struct in an SSBO:

layout (std430, binding = 12) buffer particleBlock {
    Particle particles[];
};

I am assuming my particles in the ssbo are tightly packed, because all struct members are size of 4. If I set alignment to 16:

layout (std430, binding = 12) buffer particleBlock {
    layout(align = 16) Particle particles[];
};

will particles[1] be at offset 32? I'm not sure how this align works for arrays and this doesn't seem to work for me.

1

1 Answers

2
votes

The single array elements can't be aligned by an align qualifier. Only the start of the array can be aligned.

GLSL - The OpenGL Shading Language 4.6; 4.4.5. Uniform and Shader Storage Block Layout Qualifiers; page 85 :

The align qualifier makes the start of each block member have a minimum byte alignment. It does not affect the internal layout within each member, which will still follow the std140 or std430 rules.
...
When align is applied to an array, it affects only the start of the array, not the array’s internal stride.

If you would use the std140 qualifier, an array of the struct Particle would have a stride of 32, because the stride is rounded up to a multiple of the base alignment of a vec4, which is 16.

Note, a major difference between the std140 and std430 standard is, that the stride of array elements is not rounded up to a multiple of 16 bytes, in case of std430.

If the struct Particle should have a size of 32 bytes, then you can add a dummy member at the end:

struct Particle {
    float delta;        //  0
    float start_posx;   //  4
    float start_posy;   //  8
    float start_posz;   // 12
    float restart;      // 16
    uint  max_textures; // 20
    float max_lifetime; // 24
    float dummy;        // 28: dummy member for the alignment
};