使用 std430 限定符的内存分配

Memory allocation with std430 qualifier

我正在使用与 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 会出现问题。

来自 std430 布局规则:

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.

vec4 的对齐是 float 大小的四倍。

来源: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;
};

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


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