Законно ли повторное использование привязок для нескольких блоков хранения шейдеров?

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

layout(std430,binding=0) buffer FloatView { float floats[]; };
layout(std430,binding=0) buffer IntView { int ints[]; };

Является ли это законным GLSL? opengl.org говорит "нет":

Два блока не могут использовать один и тот же индекс.

Однако мне не удалось найти такое утверждение в основной спецификации GL 4.5. или Спецификация GLSL 4.50 (или описание расширения ARB_shader_storage_buffer_object), и мой драйвер NVIDIA компилирует такой код без ошибок или предупреждений.


person Nobody moving away from SE    schedule 14.01.2016    source источник


Ответы (1)


Спецификация OpenGL прямо запрещает это? Очевидно нет. Или, по крайней мере, если и есть, то я не вижу где.

Но это не значит, что он будет работать кроссплатформенно. Имея дело с OpenGL, всегда лучше идти по консервативному пути.

Если вам нужно «перебросить» память из одного представления в другое, вы должны просто использовать отдельные точки привязки. Это безопаснее.


Сейчас есть официальное слово по этому поводу. Я отправил сообщение об ошибке, и они его прочитали и решил некоторые вещи. В частности, был сделан вывод:

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

Короче, не делай этого. Надеемся, что спецификация GLSL будет разъяснена в этом отношении.


Это было «исправлено» в версии 7 GLSL 4.5:

Использование одного и того же номера binding для более чем одного юниформ-блока или для более чем одного буферного блока является ошибкой времени компиляции или компоновки.

Я говорю «исправлено», потому что вы все еще можете выполнять алиасинг вручную через glUniform/ShaderStorageBlockBinding. И спецификация не говорит, как именно это будет работать.

person Nicol Bolas    schedule 14.01.2016
comment
Что ж, меня интересует сохранение точек привязки для реализаций с низким лимитом. Например, можно использовать один буфер/привязку в качестве структуры массивов с динамическим размером, предлагая в нее разные представления и получая доступ только к неперекрывающимся частям с каждым представлением. - person Nobody moving away from SE; 14.01.2016
comment
@Nobody: Хронос доложил; смотрите дополнение к моему сообщению. - person Nicol Bolas; 29.01.2016
comment
Я не могу много сказать против официального слова. Однако, насколько я понимаю, уже есть проблема с алиасингом. В конце концов, для этого и нужен restrict, не так ли? - person Nobody moving away from SE; 01.02.2016
comment
@Nobody: регулярное использование псевдонимов похоже на наличие двух переменных-указателей, которые указывают на одно и то же место в памяти (или на перекрывающиеся места). Это нормально. То, о чем вы говорите, это наличие двух переменных-указателей, где сами переменные являются разными именами для одной и той же переменной. - person Nicol Bolas; 01.02.2016
comment
Я знаю об этом, но я не понимаю, почему они хотят запретить использование псевдонимов таким образом, когда они уже разрешают его другим способом. Единственная проблема, которую я вижу, - это объявить оба restricted, но было бы тривиально обнаружить такие ошибки, и это полностью ошибка разработчиков (это то же самое, что использовать ограничение, а затем использовать тот же буфер). Моя позиция такова: я не вижу никаких недостатков в разрешении этого, так зачем запрещать это. (Очевидно, что могут быть технические ограничения, о которых я не знаю, поэтому мой вопрос сводится к следующему: какие ограничения препятствуют этому?) - person Nobody moving away from SE; 04.02.2016
comment
@Nobody: Я знаю об этом, но я не понимаю, почему они хотят запретить псевдонимы таким образом, когда они уже разрешают его другим способом. Я мог бы так же легко задать обратный вопрос: почему они должны разрешить это? Единственное, что это позволяет вам делать, это обращаться к одной и той же памяти разными способами, не сжигая больше точек привязки. Это не совсем полезная функция. Если кто-то дважды ссылается на одну и ту же точку привязки, вероятность того, что он совершил ошибку, гораздо выше, что он хотел использовать две разные единицы измерения и допустил опечатку. - person Nicol Bolas; 04.02.2016