Open NBickford-NV opened 1 week ago
I grabbed the repro case and can see the assert! I am currently slight backlogged, but will hopefully have time next week to look at this
Thank you Spencer! Much appreciated.
the reproduce case was easy to spot this and have tests ready (just need to fix it now)
The issue is around the fact we use vvl::DescriptorSetLayoutDef::hash()
to create a DescriptorSetLayout hash as we don't want thousands of duplicates
the pImmutableSamplers
are the issue as it is a pointer to an array of VkSampler
handles (which might be different, but identically defined which is considered the same)
need to rework things to account for this
ok, so the hash_utils::Dictionary
logic is too dense for me to figure out, going to get some help on it, until then, leaving these tests here for me to copy and paste later
TEST_F(PositiveDescriptors, DuplicateLayoutSameSampler) {
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8497");
RETURN_IF_SKIP(Init());
vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo());
OneOffDescriptorSet ds_0(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &sampler.handle()}});
const vkt::PipelineLayout pipeline_layout_0(*m_device, {&ds_0.layout_});
OneOffDescriptorSet ds_1(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &sampler.handle()}});
m_commandBuffer->begin();
vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout_0.handle(), 0, 1,
&ds_1.set_, 0, nullptr);
m_commandBuffer->end();
}
TEST_F(PositiveDescriptors, DuplicateLayoutDuplicateSampler) {
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8497");
RETURN_IF_SKIP(Init());
vkt::Sampler sampler_0(*m_device, SafeSaneSamplerCreateInfo());
vkt::Sampler sampler_1(*m_device, SafeSaneSamplerCreateInfo());
OneOffDescriptorSet ds_0(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &sampler_0.handle()}});
const vkt::PipelineLayout pipeline_layout_0(*m_device, {&ds_0.layout_});
OneOffDescriptorSet ds_1(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &sampler_1.handle()}});
m_commandBuffer->begin();
vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout_0.handle(), 0, 1,
&ds_1.set_, 0, nullptr);
m_commandBuffer->end();
}
TEST_F(PositiveDescriptors, DuplicateLayoutSameSamplerArray) {
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8497");
RETURN_IF_SKIP(Init());
vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo());
VkSampler sampler_array[3] = {sampler.handle(), sampler.handle(), sampler.handle()};
OneOffDescriptorSet ds_0(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3, VK_SHADER_STAGE_COMPUTE_BIT, sampler_array}});
const vkt::PipelineLayout pipeline_layout_0(*m_device, {&ds_0.layout_});
OneOffDescriptorSet ds_1(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3, VK_SHADER_STAGE_COMPUTE_BIT, sampler_array}});
m_commandBuffer->begin();
vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout_0.handle(), 0, 1,
&ds_1.set_, 0, nullptr);
m_commandBuffer->end();
}
TEST_F(PositiveDescriptors, DuplicateLayoutDuplicateSamplerArray) {
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8497");
RETURN_IF_SKIP(Init());
vkt::Sampler sampler_0(*m_device, SafeSaneSamplerCreateInfo());
vkt::Sampler sampler_1(*m_device, SafeSaneSamplerCreateInfo());
VkSampler sampler_array_0[3] = {sampler_0.handle(), sampler_0.handle(), sampler_0.handle()};
VkSampler sampler_array_1[3] = {sampler_1.handle(), sampler_1.handle(), sampler_1.handle()};
OneOffDescriptorSet ds_0(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3, VK_SHADER_STAGE_COMPUTE_BIT, sampler_array_0}});
const vkt::PipelineLayout pipeline_layout_0(*m_device, {&ds_0.layout_});
OneOffDescriptorSet ds_1(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3, VK_SHADER_STAGE_COMPUTE_BIT, sampler_array_1}});
m_commandBuffer->begin();
vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout_0.handle(), 0, 1,
&ds_1.set_, 0, nullptr);
m_commandBuffer->end();
}
TEST_F(NegativeDescriptors, DuplicateLayoutDifferentSampler) {
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8497");
RETURN_IF_SKIP(Init());
auto sampler_ci = SafeSaneSamplerCreateInfo();
vkt::Sampler sampler_0(*m_device, sampler_ci);
sampler_ci.maxLod = 8.0;
vkt::Sampler sampler_1(*m_device, sampler_ci);
OneOffDescriptorSet ds_0(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &sampler_0.handle()}});
const vkt::PipelineLayout pipeline_layout_0(*m_device, {&ds_0.layout_});
OneOffDescriptorSet ds_1(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &sampler_1.handle()}});
m_commandBuffer->begin();
vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout_0.handle(), 0, 1,
&ds_1.set_, 0, nullptr);
m_commandBuffer->end();
}
TEST_F(NegativeDescriptors, DuplicateLayoutDifferentSamplerArray) {
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8497");
RETURN_IF_SKIP(Init());
auto sampler_ci = SafeSaneSamplerCreateInfo();
vkt::Sampler sampler_0(*m_device, sampler_ci);
sampler_ci.maxLod = 8.0;
vkt::Sampler sampler_1(*m_device, sampler_ci);
VkSampler sampler_array_0[3] = {sampler_0.handle(), sampler_0.handle(), sampler_0.handle()};
VkSampler sampler_array_1[3] = {sampler_0.handle(), sampler_1.handle(), sampler_0.handle()};
OneOffDescriptorSet ds_0(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3, VK_SHADER_STAGE_COMPUTE_BIT, sampler_array_0}});
const vkt::PipelineLayout pipeline_layout_0(*m_device, {&ds_0.layout_});
OneOffDescriptorSet ds_1(m_device,
{{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3, VK_SHADER_STAGE_COMPUTE_BIT, sampler_array_1}});
m_commandBuffer->begin();
vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout_0.handle(), 0, 1,
&ds_1.set_, 0, nullptr);
m_commandBuffer->end();
}
Environment:
Describe the Issue
Hi Vulkan Validation Layers team!
I managed to find a way to reach this assertion error at the end of
CoreChecks::VerifySetLayoutCompatibility()
in cc_descriptor.cpp:This can happen if an app:
vkCmdBindDescriptorSets()
with a pipeline layout from the first group and a descriptor set from the second:I've attached a .zip archive for a repro case and build instructions in the Additional context section. This can happen in real-world code; I ran into it while fixing a separate validation layer issue in the nvpro-samples vk_compute_mipmaps sample.
Expected behavior
The DescriptorSetLayout::IsCompatible() check should return
true
if the detailed check passes. I think this should returntrue
, since it satisfies the identically defined as case of https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358 (although there's an additional edge case there; I'll create a follow-up issue for it).Valid Usage ID None
Additional context
Here's source code for a sample that reproduces this assertion error: vk-validation-pipeline-repro.zip
To build it, run
It uses the nvpro_core Vulkan helper library; to make things more convenient, I've copied the source code of main.cpp below.
Source code for the repro case, omitting nvpro_core's context_vk, error_vk, and resourceallocator_vk helpers
```cpp #includeThanks!