Vulkan : Gaps in descriptor sets.

QuadBit
3 min readFeb 19, 2021

--

Descriptor sets

My code design predefines/categorises descriptor sets based on the frequency of usage. Hence I came accross the scenario of tackling the gaps in descriptor sets for a given shader module.

Some insight into the design.
Set 0 : Camera
Set 1 : Lights
Set 2 : Textures
Set 3 : Object surface
Set 4 : Transformation

Using the above mentioned configuration, such a drawgraph can be created. In case of a shader module/material which doesn’t accomodate all the sets, it will require some hack to materialise the material :).

Link for the working setup snippets, without any gaps.

As an example, the below mentioned shader uses 2 uniform sets.

layout(set = 0, binding = 0) uniform UniformBufferObject {
mat4 viewMatrix;
mat4 projMatrix;
} ubo;

layout(set = 2, binding = 0) uniform TransformBufferObject {
mat4 modelMatrix;
} transform;

The above modification (set =1, index missing) will cause the validation to trigger pipeline layout compatibility errors as shown below.

Shader uses descriptor slot 2.0 (expected `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT`) but not declared in pipeline layout

Validation Error: vkCmdDraw(): VkPipeline 0x6b0ed800000000fd[] defined with VkPipelineLayout 0x5a58f900000000fc[] is not compatible for maximum set statically used 2 with bound descriptor sets, last bound with VkPipelineLayout

UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotBound(ERROR / SPEC): msgNum: -840888189 — Validation Error: [ UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotBound ] Object 0: handle = 0x2816754f928, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0xcde11083 | VkPipeline 0x6b0ed800000000fd[] uses set #2 but that set is not bound.

Let’s see the changes required to handle it.

First a dummy empty descriptor set layout is required to convince the pipeline layout creation that the layout matches the uniform declarations in the shader.

Please note that the order of the set layouts matter. To represent the set with value equal to 1, a DescriptorSetLayoutCreateInfo with binding count of 0 is used. Creating the pipeline layout using the above descriptor set layout will remove the above mentioned error related to the pipeline layout creation but validation will still complain with new errors mentioned below.

Shader uses descriptor slot 2.0 (expected `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT`) but not declared in pipeline layout

Validation Error: vkCmdDraw(): VkPipeline 0x6b0ed800000000fd[] defined with VkPipelineLayout 0x5a58f900000000fc[] is not compatible for maximum set statically used 2 with bound descriptor sets, last bound with VkPipelineLayout 0x5a58f900000000fc[]

Validation Error: VkPipeline 0x6b0ed800000000fd[] uses set #2 but that set is not bound.

The validation compains that it has issues with descriptor set at #2. So vulkan is actually expecting a total of 3 sets including the gap at #1. This one was a bit tricky to figure out. A dummy descriptor set needs to be created and bound at rendering time.

The dummy descriptorSet needs to be placed at the correct location within descriptorSet collection while rendering

With these adjustments rendering goes back to its normal state, without any errors. A single dummy set and setLayout can be created and reused for the entire application.

A possible scenario :

A question can be raised why not avoid gaps and create pipeline layouts accordingly. The idea will not scale up efficiently, especially if drawgraph edge creation need to be automated. If gaps are avoided automation might get compromised a bit.

Really good blog on shader reflection system using Spir-Cross, saved some of my time by using his system and making it compatible with my parser/interpreter system.

--

--

QuadBit
QuadBit

Written by QuadBit

Graphics programmer, trying to get a grip on Vulkan. Just trying :) https://github.com/quad-bit

No responses yet