Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory allocation with std430 qualifier

Tags:

opengl

glsl

I'm using the compute shader bound with a SSAO. And I use the following structure in the compute shader:

struct Particle                 
{                       
    vec4 pAnds;                     
    vec3 velocity;                  
    float lifespan;             
    float age;                  
};

layout (std430, binding = 0) buffer members_in
{
    Particle particle[];
} input_data;

yet it seems that the memory block allocated for each of these data structure is not equal to (4 + 3 + 1 + 1) * 4. And I also tried another one:

struct Particle                 
{                       
    vec4 pAnds;                     
    vec3 velocity;                  
    float lifespan;             
};

This time it worked fine. I was wondering how the memory is allocated with std430 qualifier. How to make my first data structure work just as the second one?

updated: I changed it to the following form:

struct Particle
{                           
    float px, py, pz, s;
    float vx, vy, vz;
    float lifespan;
    float age;
};

This time it worked fine, but I still have no idea why there's problem using vec4 / vec3.

like image 501
Oscar Avatar asked Apr 09 '15 06:04

Oscar


1 Answers

From the std430 Layout Rules:

Structure alignment is the same as the alignment for the biggest structure member, where three-component vectors are not rounded up to the size of four-component vectors. Each structure will start on this alignment, and its size will be the space needed by its members, according to the previous rules, rounded up to a multiple of the structure alignment.

The alignments for vec4 is four times the size of float.

Source: OpenGL Programming Guide, 8th Edition


First example:

struct Particle {
    vec4 pAnds;      // 4 * 4 bytes
    vec3 velocity;   // 3 * 4 bytes
    float lifespan;  // 1 * 4 bytes
    float age;       // 1 * 4 bytes
};

The biggest member of the structure is vec4 pAnds and it has 16 byte alignment. Therefore the structure's alignment is also 16 bytes, meaning, that inside an array each structure has to start at a position multiple of 16. In order to satisfy that, a 12 byte padding will be appended to the end of each structure.


Second example:

struct Particle {
    vec4 pAnds;      // 4 * 4 bytes
    vec3 velocity;   // 3 * 4 bytes
    float lifespan;  // 1 * 4 bytes
};

The structure has an alignment of 16 bytes and the size of the structure nicely fits into 2 times the alignment of the structure.


Third example:

struct Particle {
    float px, py, pz, s;
    float vx, vy, vz;
    float lifespan;
    float age;
};

The structure doesn't have any elements bigger than one size of float, therefore the alignment of the structure is only 4 bytes.


The workaround could be inserting an array of floats as an explicit padding or trying to pack your data tightly into a size multiple of the structure's alignment.

like image 127
aethe Avatar answered Nov 14 '22 17:11

aethe