Как установить выравнивание массива в SSBO - PullRequest
0 голосов
/ 14 сентября 2018

В вычислительном шейдере у меня есть структура для частицы:

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

Теперь я хочу использовать эту структуру в SSBO:

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

Я предполагаю, что мои частицы в ssbo плотно упакованы, потому что все элементы структуры имеют размер 4. Если я установлю выравнивание на 16:

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

будут ли частицы [1] со смещением 32? Я не уверен, как это выравнивание работает для массивов, и это, похоже, не работает для меня.

1 Ответ

0 голосов
/ 14 сентября 2018

Элементы одного массива не могут быть выровнены квалификатором align. Выровнять можно только начало массива.

GLSL - Язык затенения OpenGL 4.6; 4.4.5. Классификаторы макетов блоков унифицированного и шейдерного хранилища; страница 85 :

Спецификатор выравнивания заставляет начало каждого элемента блока иметь минимальное байтовое выравнивание. Это не влияет на внутреннюю разметку внутри каждого члена, которая все равно будет следовать правилам std140 или std430.
...
Когда выравнивание применяется к массиву, оно влияет только на начало массива, а не на внутренний шаг массива.

Если вы используете квалификатор std140 , массив структуры Particle будет иметь шаг 32, потому что шаг округляется до кратности базового выравнивания vec4 , что составляет 16.

Обратите внимание, что основное различие между стандартами std140 и std340 заключается в том, что шаг элементов массива не округляется до кратных 16 байт, в случае std340.

Если структура Particle должна иметь размер 32 байта, тогда вы можете добавить фиктивный элемент в конце:

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
};
...