Fix crash when descriptor update template uses unreferenced layout

It is possible for the VkDescriptorUpdateTemplateCreateInfo to have its
descriptorSetLayout or pipelineLayout be the only reference to the
corresponding object, as vkCmdPushDescriptorSetWithTemplateKHR and
vkUpdateDescriptorSetWithTemplate only require that the actual layout
matches/is compatible with the one used by the template. Before, there
was no dependency from the update template to the layout, so if it was
the sole use of a layout, the layout would not be saved in the capture,
resulting in a crash during playback.

This change also modifies the vk_parameter_zoo to test this case. With
those modifications, the change to vk_descriptor_funcs is required to
prevent the crash. Note that on my machine, I needed to comment out
other parts of vk_parameter_zoo, or else it would crash (even when
not run under renderdoc) due to driver issues.

For reference:

https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdPushDescriptorSetWithTemplateKHR.html#VUID-vkCmdPushDescriptorSetWithTemplateKHR-layout-07993
https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkUpdateDescriptorSetWithTemplate.html#VUID-vkUpdateDescriptorSetWithTemplate-pData-01685
https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDescriptorUpdateTemplateCreateInfoKHR.html#_members
This commit is contained in:
William Pearson
2023-11-08 11:05:35 -07:00
committed by Baldur Karlsson
parent 0ff1c66ca7
commit 9cf30b190e
2 changed files with 25 additions and 16 deletions
@@ -1480,6 +1480,11 @@ VkResult WrappedVulkan::vkCreateDescriptorUpdateTemplate(
VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pDescriptorUpdateTemplate);
record->AddChunk(chunk);
if(unwrapped.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR)
record->AddParent(GetRecord(pCreateInfo->pipelineLayout));
else if(unwrapped.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET)
record->AddParent(GetRecord(pCreateInfo->descriptorSetLayout));
record->descTemplateInfo = new DescUpdateTemplate();
record->descTemplateInfo->Init(GetResourceManager(), m_CreationInfo, pCreateInfo);
}
+20 -16
View File
@@ -471,19 +471,21 @@ void main()
{10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_SHADER_STAGE_VERTEX_BIT},
}));
VkDescriptorSetLayout refsetlayout =
createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
{0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_VERTEX_BIT},
{3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_VERTEX_BIT},
{4, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{5, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{6, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{8, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT},
{9, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT},
}));
VkDescriptorSetLayoutCreateInfo refsetlayoutcreateinfo = vkh::DescriptorSetLayoutCreateInfo({
{0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_VERTEX_BIT},
{3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_VERTEX_BIT},
{4, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{5, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{6, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
{8, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT},
{9, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT},
});
VkDescriptorSetLayout refsetlayout = createDescriptorSetLayout(&refsetlayoutcreateinfo);
VkDescriptorSetLayout refsetlayout_copy = createDescriptorSetLayout(&refsetlayoutcreateinfo);
VkSampler invalidSampler = (VkSampler)0x1234;
VkSampler validSampler = createSampler(vkh::SamplerCreateInfo(VK_FILTER_LINEAR));
@@ -497,7 +499,7 @@ void main()
{99, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_VERTEX_BIT, &invalidSampler},
}));
VkPipelineLayout layout, reflayout;
VkPipelineLayout layout, layout_copy, reflayout;
if(KHR_push_descriptor)
{
@@ -510,6 +512,7 @@ void main()
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout, pushlayout}));
layout_copy = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout, pushlayout}));
VkDescriptorSetLayout refpushlayout =
createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo(
@@ -535,6 +538,7 @@ void main()
else
{
layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout}));
layout_copy = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout}));
if(KHR_descriptor_update_template)
reflayout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({refsetlayout, refsetlayout}));
@@ -1127,7 +1131,7 @@ void main()
sizeof(data)},
};
createInfo.descriptorSetLayout = refsetlayout;
createInfo.descriptorSetLayout = refsetlayout_copy;
createInfo.descriptorUpdateEntryCount = (uint32_t)entries.size();
createInfo.pDescriptorUpdateEntries = entries.data();
@@ -1156,7 +1160,7 @@ void main()
createInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR;
createInfo.descriptorSetLayout = (VkDescriptorSetLayout)0x1234;
createInfo.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
createInfo.pipelineLayout = layout;
createInfo.pipelineLayout = layout_copy;
createInfo.set = 1;
vkCreateDescriptorUpdateTemplateKHR(device, &createInfo, NULL, &pushtempl);