3

I have trouble with differences between layout std140 and std430.

this is my code of struct in .Cpp

struct Particle {
    glm::vec3 position = glm::vec3(0);
    float density = 1;
};


for (int z = 0; z < d; ++z) {
    for (int y = 0; y < d; ++y) {
        for (int x = 0; x < d; ++x) {
            int index = z * d * d + y * d + x;
            if (index >= num) break;

            // dam break
            m_InitParticles[index].position = glm::vec3(x, y, z) * distance;
            m_InitParticles[index].position += glm::vec3(getJitter(), getJitter(), getJitter());
            m_InitParticles[index].density = index;
        }
    }
}

And compute shader code

struct Particle {
    vec3 position;
    float density;
};
layout(std140, binding = 0) restrict buffer Particles{
    Particle particles[];
};

it seems that I get correct data std430 data in renderdoc by

pack#(std430) 
struct Particle {
    vec3 position;
    float t;
}

And when I use pack#(std140), the struct seems to have a 8N space std140 in renderdoc.

pack#(std430) 
struct Particle {
    vec3 position;
    float t;
}

With std140, glGetActiveUniformsiv returns offset 0 and 12.

Why struct vec + float takes up extra space in std140?

mq s
  • 41
  • 4

1 Answers1

3

The official OpenGL wiki has got you covered:

The rules for std140 layout are covered quite well in the OpenGL specification (OpenGL 4.5, Section 7.6.2.2, page 137). Among the most important is the fact that arrays of types are not necessarily tightly packed. An array of floats in such a block will not be the equivalent to an array of floats in C/C++. The array stride (the bytes between array elements) is always rounded up to the size of a vec4 (ie: 16-bytes). So arrays will only match their C/C++ definitions if the type is a multiple of 16 bytes

Warning: Implementations sometimes get the std140 layout wrong for vec3 components. You are advised to manually pad your structures/arrays out and avoid using vec3 at all.

LJᛃ
  • 7,655
  • 2
  • 24
  • 35