Render to UAV buffer into a volume texture?

I’m dealing with something new, writing to a UAV buffer into a volume texture’s data:

This is a usage of the GPU I am totally unfamiliar with. Can you point me in the right direction to get started? Thanks!

UAVs are Direct3D/HLSL terminology for GPU functionality. I don’t have specific knowledge of how HLSL maps these sorts of things into something Vulkan recognizes, but since the page you cited says:

Note that the data is written to a 3D texture which is bound as a UAV buffer

then you’re looking at writing to what the Vulkan API (and SPIR-V) refers to as a “storage image”. Specifically a 3D storage image. So you have to create a 3D image, bind it to the appropriate storage image descriptor, and access it from within your shader.

1 Like

Okay, I added an option to create storage textures, and I already have a set of storage buffers in use in my descriptor set…but how to connect those two things so I can write to the texture?

I’m not sure how to answer your question. Do you want to write to a buffer or to an image? These are two largely unrelated processes.

Okay, for descriptor sets you have several options:
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER

Which is the correct one, to write into a storage texture? What should the image’s VkImageLayout be set to? How does a shader actually write into the texture?

The Vulkan API is really not trying to hide things from you. It generally names things what they mean. So if you’re trying to write to an image, you should probably pick the option that doesn’t have the word “buffer” in it.

This is also why in Vulkan, we talk about images. An image can be used as a texture, but there are other uses of images too (though admittedly, the nomenclature in the standard isn’t 100% consistent).

The standard has a nice section on image layouts, wherein it describes what operations are permitted by each layout. Of course, none of the mention storage image usage specifically, but by process of elimination, you will find the one layout that accepts this usage… because it accepts all usages.

By calling imageStore. That’s an OpenGL page, but the GLSL equivalent is virtually identical for Vulkan.

1 Like

I know you are trying to teach a man to fish, and I am doing the best I can. :grinning_face_with_smiling_eyes:

I am binding a storage texture’s imageview to the descriptor set, using descriptor type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE.

The imageview is created with all the texture’s miplevels. (VkImageViewCreateInfo.subresourceRange.levelCount equals the number of mipmaps.)

However, the imageStore GLSL command does not specify an image LOD, it just uses a coord (presumably uvec2?). Unlike Vulkan, OpenGL uses a command glBindImageTexture, which specifies a single LOD level.

Is it possible in Vulkan to bind an imageview with miplevels to one descriptor slot, and write to the different LOD levels somehow? There is an AMD extension “VK_AMD_shader_image_load_store_lod” but this is getting into something called "OpImageWrite* which I am not sure accessible in GLSL or some internal SPIR-V thing?:
https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_AMD_shader_image_load_store_lod.html

It looks like it is not possible otherwise.

That’s a good question. While the answer is obvious (it uses mipmap 0 of the image view), tracking down where this gets said is less so. Since SPIR-V’s OpWriteImage uses integer texel coordinates, you can find this in the section titled: “Integer Texel Coordinate Operations”.

So while the API lets you bind a mipmapped view, it’s only going to let you write to the base level of that view. If you need to write to other mipmap levels, they must be bound to other image variables as separate image views.

Yep. It would be nice if that AMD extension was standard. But I’ve basically got it working now. Thank you.