New Vulkan samples for using descriptor heaps

New way of passing data to shaders

In Vulkan, data has historically been passed to shaders using descriptors. Managing them can become quite complicated. There are ways to avoid that, such as using buffer device address (obviously for buffers only) or descriptor indexing (aka “bindless”). But until recently, there was no unified way to avoid the complexity around descriptors.

This changed a few months ago when VK_EXT_descriptor_heap was introduced. That extension completely overhauls Vulkan’s existing descriptor API, letting you handle descriptors as raw memory. If you’ve used descriptor heaps in DX12, this will feel familiar, though there are slight differences to accommodate the wider range of device and platform support in Vulkan.

To ease the adoption, the extension offers two ways of accessing heaps from the shader side:

Set and binding mappings using VkDescriptorSetAndBindingMappingEXT.

This lets you reuse existing shaders without having to adjust the interface by mapping heaps to shader inputs:

VkDescriptorSetAndBindingMappingEXT{
	.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_AND_BINDING_MAPPING_EXT,
	.descriptorSet = 0,
	.firstBinding = 0,
	.bindingCount = 1,
	.resourceMask = VK_SPIRV_RESOURCE_TYPE_UNIFORM_BUFFER_BIT_EXT,
	.source = VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_CONSTANT_OFFSET_EXT,
	.sourceData = {
		.constantOffset = {
			.heapArrayStride = static_cast<uint32_t>(bufferDescriptorSize)
		}
	}
}
layout (set = 0, binding = 0) uniform UBO {
	mat4 projection;
	mat4 view;
	mat4 model;
} ubo;

The second way is using untyped pointers, which gives you more direct control over how to access heaps from shaders, but may require some manual offset calculations. It also has certain limitations depending on the shading language you use:

layout(descriptor_heap) buffer ModelData {
	vec4 pos;
	vec4 color;
} modelData[];

void main() 
{
	...
	vec3 localPos = inPos * 0.25f + modelData[nonuniformEXT(gl_InstanceIndex)].pos.xyz;
	outColor = modelData[nonuniformEXT(gl_InstanceIndex)].color.rgb;
}

C++ Samples

To help you get started with descriptor heaps in Vulkan, I have added two new examples to my repository of C++ Vulkan samples:

Further reading