Выделение буфера в OpenGL для вычислений

Я пытаюсь использовать буфер в вычислительном шейдере, как это:

layout (binding = 1, std430) writeonly buffer bl1
{
    uint data[gl_WorkGroupSize.x * gl_NumWorkGroups.x * gl_NumWorkGroups.y];
};

но я получаю следующую ошибку (из-за использования gl_NumWorkGroups для размера):

Array size must be a constant integer expression

Как я могу обойти это?

1 ответ

Решение

Прекратите вводить длину вообще:

layout (binding = 1, std430) writeonly buffer bl1
{
    uint data[];
};

Эта особенность уникальна для SSBO. И у вас может быть только один массив без размера в SSBO, и он должен быть последним членом в блоке интерфейса. Размер data будет вычисляться на основе размера диапазона объекта буфера, который вы привязываете к этой точке привязки. Таким образом, если вы связываете 32 КБ буферного пространства, вы получите 8 КБ элементов (размер uint 4 байта).

Во время выполнения ваш шейдер может использовать gl_WorkGroupSize.x * gl_NumWorkGroups.x * gl_NumWorkGroups.y рассчитать длину data, В качестве альтернативы просто используйте data.length() чтобы получить длину буфера, который дал вам пользователь. В качестве альтернативы... вам не нужно явно знать длину, в зависимости от того, как вы ее используете.

Пока ваш код привязки буфера OpenGL использует буфер с достаточным объемом памяти для подсчета отправлений и размера рабочей группы, все в порядке.

Другие вопросы по тегам