KhronosGroup / KhronosGroup/Vulkan-ValidationLayers
Trying to understand the rules for set incompatibility when immutable samplers are involved
@spencer-lunarg is already working on this.
Since May 13, 2025.
- Dominant language
- C++
- Stars
- 1k
- Forks
- 505
- Avg merge
- 11h 25m
- Merged PRs (30d)
- 229
Description
A recent change in our renderer backend to add immutable samplers has led to this seemingly unrelated error appearing during each frame.
VUID-vkCmdDrawIndexed-None-08600 vkCmdDrawIndexed(): VkPipeline 0x20be00000020be[RID:21891448307752] uses set 2 but that set is not bound. (Need to use a command like vkCmdBindDescriptorSets to bind the set).
VUID-vkCmdDrawIndexed-None-08600 vkCmdDrawIndexed(): VkPipeline 0x20be00000020be[RID:21891448307752] uses set 1 but that set is not bound. (Need to use a command like vkCmdBindDescriptorSets to bind the set).
- The pipeline in question uses three descriptor sets. The engine does not detect any need to rebind sets 1 and 2 unless the pipeline layouts are different, but seemingly it doesn't agree with the internal rules that the VVL has about it.
- It doesn't complain about set #0, nor is set #0 being bound again during the render pass. The engine always rebinds all sets above a specific set if it needs to.
- The immutable sampler in question is always a singular handle that's been created only once in the lifetime of the application.
- The immutable sampler is not the only descriptor in the set, but it is the only immutable sampler to appear in it.
- The immutable sampler is the first descriptor in the set.
- The immutable sampler is skipped from being updated with vkUpdateDescriptorSets, as the sampler is passed directly when creating the pipeline layout with VkDescriptorSetLayoutBinding.
- One possible thing I suspected here was if the VkSampler * being different despite pointing to the same sampler could be the cause of a false positive, but fixing this to a static value in memory did not change the behavior.
- The problem goes away if sets 1 and 2 are forcefully bound before every draw.
- I've not determined which particular event triggers the sets being "unbound".
- All the pipelines in the render pass use pipelines use the same exact immutable sampler.
- I can confirm the error goes away as well if a dynamic sampler is used instead.
- It's worth clarifying I don't see any rendering errors caused by this. Two descriptor sets not being bound at all would definitely cause something pretty visible to happen, but it's not happening in any of the hardware I've tested (NVIDIA, AMD, Qualcomm, etc).
I've dug around the codebase of the validation layers for a while but haven't been able to turn much up. There's seemingly lots of rules that determine whether a pipeline layout is compatible or not, and the application seems to be able to get past these conditions only by introducing an immutable sampler into the mix. Without it, everything works as expected and there's no validation error claiming that the sets were not rebound as necessary.
Can I ask for a clarification on what are the exact rules of why a descriptor set would become "unbound" between pipeline changes or draws at the presence of an immutable sampler? Most of what I found seems to indicate that at least the numerical value of the VkSampler handle is involved in the hash computation.
I've not been able to build a minimal reproduction yet as I'm not entirely sure what series of events triggers the set being "unbound" so far. Suggestions on what to debug further are welcome.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.