使用std430限定符分配内存

时间:2015-04-09 06:23:54

标签: opengl glsl

我使用与SSAO绑定的计算着色器。我在计算着色器中使用以下结构:

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

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

但似乎为每个数据结构分配的内存块不等于(4 + 3 + 1 + 1)* 4.我还尝试了另一个:

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

这次它运作良好。我想知道如何使用std430限定符分配内存。如何使我的第一个数据结构像第二个一样工作?

更新: 我把它改成了以下形式:

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

这一次它工作正常,但我仍然不知道为什么使用vec4 / vec3存在问题。

1 个答案:

答案 0 :(得分:5)

来自std430布局规则:

  

结构对齐与最大结构成员的对齐相同,其中三分量向量不会四舍五入到四分量向量的大小。每个结构都将从此对齐开始,其大小将是其成员所需的空间,根据之前的规则,四舍五入到结构对齐的倍数。

vec4的对齐是浮点数的四倍。

来源:OpenGL编程指南,第8版


第一个例子:

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

结构中最大的成员是vec4 pAnds,它有16字节对齐。因此,结构的对齐也是16个字节,这意味着,在数组内部,每个结构必须从16的位置开始。为了满足这一要求,将在每个结构的末尾附加12字节填充。


第二个例子:

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

该结构的对齐为16个字节,结构的大小恰好适合结构对齐的2倍。


第三个例子:

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

该结构没有任何大于float大小的元素,因此结构的对齐只有4个字节。


解决方法可能是将一个浮点数组插入显式填充或尝试将数据紧密地打包到结构对齐的大小倍数中。