Константа специализации, используемая для размера массива - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь использовать константу специализации SPIR-V , чтобы определить размер массива в едином блоке.

#version 460 core

layout(constant_id = 0) const uint count = 0;

layout(binding = 0) uniform Uniform
{
    vec4 foo[count];
    uint bar[count];
};

void main() {}

При объявлении count = 0 в шейдере компиляция завершается с:

array size must be a positive integer

При count = 1 и специализации 5 код компилируется, но связывание не выполняется во время выполнения с жалобами на алиасинг:

error: different uniforms (named Uniform.foo[4] and Uniform.bar[3]) sharing the same offset within a uniform block (named Uniform) between shaders
error: different uniforms (named Uniform.foo[3] and Uniform.bar[2]) sharing the same offset within a uniform block (named Uniform) between shaders
error: different uniforms (named Uniform.foo[2] and Uniform.bar[1]) sharing the same offset within a uniform block (named Uniform) between shaders
error: different uniforms (named Uniform.foo[1] and Uniform.bar[0]) sharing the same offset within a uniform block (named Uniform) between shaders

Кажется, что расположение унифицированного блока (смещение каждого элемента) не изменяется во время специализации, поэтому foo и bar перекрываются.

Явные смещения тоже не работают и приводят к тем же ошибкам ссылки:

layout(binding = 0, std140) uniform Uniform
{
    layout(offset = 0) vec4 foo[count];
    layout(offset = count) uint bar[count];
};

Это предполагаемое поведение? Упускать из виду? Можно ли использовать константу специализации для определения размера массива?

1 Ответ

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

Это странная причуда ARB_spir_v. От спецификация расширения :

Массивы внутри блока могут иметь размер с константой специализации, но блок будет иметь статическую компоновку. Изменение специализированного размера не приведет к изменению структуры блока. При отсутствии явных смещений макет будет основан на размере массива по умолчанию.

Поскольку размер по умолчанию равен 0, структура в блоке будет размещена так, как если бы массивы были нулевого размера.

По сути, вы можете использовать константы специализации, чтобы сделать массивы короче, чем по умолчанию, но не длиннее . И даже если вы сделаете их короче, они по-прежнему будут занимать то же пространство, что и по умолчанию.

Таким образом, на самом деле использование констант специализации в длинах массива блоков - это просто сокращенный способ объявления массива со значением по умолчанию в качестве его длины, а затем замены того места, где вы будете использовать name.length(), на константу / выражение специализации. Это чисто синтаксический сахар.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...