Загрузка / сохранение на определенном уровне MIP в вычисляющем шейдере vulkan

Как следует из названия, я хочу читать и записывать в определенный пиксель определенного уровня MIP в вычислительном шейдере. На стороне Vulkan я знаю, что могу указать, сколько уровней mip я хочу адресовать в ImageView, но я не уверен, как это работает в glsl. Могу ли я использовать один image3D с одним ImageView:

layout(binding = 0, rgb8) uniform image3D img;

или мне нужен один image2D для каждого уровня MIP и, следовательно, несколько ImageViews?

layout(binding = 0, rgb8) uniform image2d mipLvl0;
layout(binding = 1, rgb8) uniform image2d mipLvl1;
layout(binding = 2, rgb8) uniform image2d mipLvl2;

Поскольку оба imageLoad / Store имеют перегрузку, принимающую ivec3, я предполагаю, что в первом случае я могу указать уровень mip как координату z.


person Bass Guru    schedule 29.06.2021    source источник
comment
mip-уровни и 3D или массивы - это разные вещи.   -  person krOoze    schedule 29.06.2021
comment
Может, я плохо подобрал слова. Я хотел спросить, есть ли возможность получить доступ к уровням MIP в вычислительном шейдере, таком как 3D-изображение?   -  person Bass Guru    schedule 29.06.2021
comment
@BassGuru: Что ты имеешь в виду, говоря, как [sic] 3D изображение? Трехмерные изображения имеют одинаковые размеры для всех двухмерных глубинных срезов. Двухмерные MIP-карты становятся меньше с каждым уровнем MIP-карты. Поскольку вы получаете доступ к ним по размеру пикселей, вы не можете не знать, к какому уровню MIP-карты вы обращаетесь.   -  person Nicol Bolas    schedule 29.06.2021
comment
Но вы можете получить размер изображения, например, imageSize и вычисляют размер, затем уменьшая его вдвое или передавая его косвенно, выпуская vkCmdDispatch для каждого уровня, регулируя количество групп и передавая уровень с помощью константы push.   -  person Bass Guru    schedule 29.06.2021
comment
@BassGuru: Я не уверен, что вы здесь пытаетесь донести. Уровни MIP-карты объекта изображения представляют собой отдельные изображения. Все глубины уровня MIP-карты объекта 3D-изображения являются частью одного и того же изображения. То, что вы хотите, невозможно так, как вы этого хотите, и на самом деле нет смысла делать это таким образом. Что вы пытаетесь сделать, чтобы вам это казалось нужным?   -  person Nicol Bolas    schedule 29.06.2021


Ответы (1)


Пирамиду MIP-карты нельзя рассматривать как дескриптор с одной привязкой.

Однако вы можете связать каждое MIP-карту в пирамиде с дескриптором массивом:

layout(binding = 0, rgb8) uniform image2d img[3];

Этот дескриптор будет массивом, что означает, что VkDescriptorSetLayoutBinding::descriptorCount для привязки 0 этого набора будет 3 в этом примере. Вам также нужно будет привязать каждый MIP-карту изображения к другому индексу массива в дескрипторе, поэтому descriptorCount и pImageInfo для этого дескриптора потребуется предоставить несколько изображений для вызова vkUpdateDescriptorSet. И количество элементов массива должно быть указано в шейдере, чтобы оно не могло динамически изменяться (хотя вы можете оставить некоторые из них неуказанными в дескрипторе, если ваш шейдер не имеет к ним доступа).

Кроме того, вы должны следовать правилам вашей реализации для индексации массива непрозрачных типов. Большинство настольных реализаций позволяют им быть динамически однородными выражениями (и вам необходимо активировать функцию shaderStorageImageArrayDynamicIndexing), поэтому вы можете использовать uniform переменные, а не постоянные выражения. Но выражения не могут быть произвольными; они должны разрешаться в одно и то же значение за один вызов отрисовки.

Кроме того, использование массива изображений не позволяет обойти ограничения на количество изображений, которые может использовать шейдер. Тем не менее, большинство настольных компьютеров довольно щедры с этими ограничениями.

person Nicol Bolas    schedule 29.06.2021