GLSL: как правильно связать тысячи буферов?

Мне пришла в голову идея, требующая привязки тысяч буферов (атомарных счетчиков и шейдерных хранилищ) к одной GLSL-программе. Сначала я проверил, будет ли это иметь смысл в ограничениях openGL, и это кажется возможным по двум причинам:

  1. На моем ноутбуке GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS и GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS составляют около 32 КБ. Таким образом, openGL позволяет мне связывать тысячи буферов за один проход.
  2. openGL 4.4 предлагает:

    void BindBuffersBase (перечисление target, uint first, sizei count, const uint *buffers);

В коде C это кажется простым, но я понятия не имею, как делать свои шейдеры. При привязке индексированных буферов мы должны использовать:

layout (std430, binding = 0) buffer Objects
{
  Object objects[];
};

При привязке пары буферов все в порядке. Но в моем случае:

  1. Я не знаю заранее, сколько буферов будет привязано
  2. Даже если бы я знал, должен ли я написать несколько строк кода для КАЖДОГО буфера и определить в привязке макета 0, 1, 2, ..., n?

Тогда возникает вопрос: есть ли способ сделать так, чтобы шейдер не знал о номере буфера, который будет к нему привязан? Предполагая, что они ВСЕ содержат данные одного типа.

Ответ :

Спасибо Андону М. Коулману за быстрые и четкие ответы.

Во-первых, я ошибался, полагая, что мое оборудование поддерживает тысячи привязок. Ошибки новичка, я взял заданное значение вместо значения времени выполнения.

На моей машине:

  1. GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 96
  2. GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 8
  3. GL_MAX_UNIFORM_BUFFER_BINDINGS = 84

Это далеко не то, на чем я основывал свой вопрос.

Однако есть способ определить несколько буферов в шейдере:

A
{
  B b[];
}
layout (std430, binding = 0) buffer A a[32];

Количество максимальных привязок должно быть известно заранее, но эти буферы будут занимать привязки от 0 до 31.


person agrum    schedule 15.05.2014    source источник
comment
Вы действительно запрашивали эти значения во время выполнения, а не использовали значение константы, верно? Большинство новых расширений имеют константы в этом диапазоне. Также у вас есть индекс массива не в том месте, он должен идти после конца блока.   -  person Andon M. Coleman    schedule 15.05.2014
comment
Абсолютно нет, хорошая догадка от вас. Я только что видел пост, где кто-то сказал, что его лимит равен 96, поэтому я проверил во время выполнения, чтобы быть уверенным. 8 для атомных и 96 для хранения. Что убивает прямо здесь и сейчас сделку.   -  person agrum    schedule 15.05.2014
comment
Если я все еще помещу индекс массива в конец блока, будет ли он охватывать привязку 0 к n ?   -  person agrum    schedule 15.05.2014
comment
Можно, если присвоить имя вида } foo [32];... Этому массиву из 32 блоков будут присвоены привязки в последовательном порядке: 0 - 31   -  person Andon M. Coleman    schedule 15.05.2014
comment
Спасибо, сэр. Я сейчас напишу ответ.   -  person agrum    schedule 15.05.2014
comment
Любопытно, для чего вы собираетесь использовать тысячи этих буферов?   -  person Steven Lu    schedule 15.05.2014
comment
Один проход SPH в неограниченном трехмерном пространстве. Но теперь это будет многократный проход, по одному на куб. С текущими ограничениями это все еще может работать, мне нужно 7 атомарных и 34 буфера хранения, привязанных к проходу. Просто если в кубе всего несколько частиц, он все равно будет использовать один вызов glDispatchCompute().   -  person agrum    schedule 15.05.2014
comment
Или я только что узнал, что атомарные операции можно выполнять с буферными и общими переменными. Так что мне даже не нужны атомарные буферы.   -  person agrum    schedule 16.05.2014


Ответы (1)


Спасибо Andon M. Coleman за быстрые и четкие ответы.

Во-первых, я ошибался, полагая, что мое оборудование поддерживает тысячи привязок. Ошибки новичка, я взял заданное значение вместо значения времени выполнения.

На моей машине:

  1. GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 96
  2. GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 8
  3. GL_MAX_UNIFORM_BUFFER_BINDINGS = 84

Это далеко не то, на чем я основывал свой вопрос.

Однако есть способ определить несколько буферов в шейдере:

A
{
  B b[];
}
layout (std430, binding = 0) buffer A a[32];

Количество максимальных привязок должно быть известно заранее, но эти буферы будут занимать привязки от 0 до 31.

person agrum    schedule 15.05.2014