Load/Store to specific mip level in vulkan compute shader

1.3k Views Asked by At

As the title suggests, I want to read and write to a specific pixel of a certain mip level in a compute shader. I know on the Vulkan side, that I can specify how much mip levels I want to address in an ImageView, but I'm not sure how this works in glsl. Can I use a single image3D with a single ImageView:

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

or do I need one image2D per mip level and thus multiple ImageViews?

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

Since both imageLoad/Store have an overload taking an ivec3 I assume I can specify the mip level as the z coordinate in the first case.

1

There are 1 best solutions below

0
Nicol Bolas On

You cannot treat a mipmap pyramid as a single bound descriptor.

You can however bind each mipmap in a pyramid to an arrayed descriptor:

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

This descriptor would be arrayed, meaning that VkDescriptorSetLayoutBinding::descriptorCount for binding 0 of this set would be 3 in this example. You also would have to bind each mipmap of the image to a different array index in the descriptor, so descriptorCount and pImageInfo for that descriptor would need to provide multiple images for the vkUpdateDescriptorSet call. And the number of array elements needs to be stated in the shader, so it can't dynamically change (though you can leave some of them unspecified in the descriptor if your shader doesn't access them).

Also, you have to follow your implementation's rules for indexing an array of opaque types. Most desktop implementations allow these to be dynamically uniform expressions (and you need to activate the shaderStorageImageArrayDynamicIndexing feature), so you can use uniform variables rather than a constant expression. But the expressions cannot be arbitrary; they must resolve to the same value within a single draw call.

Also, using an array of images doesn't bypass the limits on the number of images a shader can use. However, most desktop hardware is pretty generous with these limits.