From 9cf30b190e69ec98944ee02b6aec715c356d1e63 Mon Sep 17 00:00:00 2001 From: William Pearson Date: Wed, 8 Nov 2023 11:05:35 -0700 Subject: [PATCH] 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 --- .../vulkan/wrappers/vk_descriptor_funcs.cpp | 5 +++ util/test/demos/vk/vk_parameter_zoo.cpp | 36 ++++++++++--------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index 514d1a812..742e62cc4 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -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); } diff --git a/util/test/demos/vk/vk_parameter_zoo.cpp b/util/test/demos/vk/vk_parameter_zoo.cpp index 82d714b59..a298dcb99 100644 --- a/util/test/demos/vk/vk_parameter_zoo.cpp +++ b/util/test/demos/vk/vk_parameter_zoo.cpp @@ -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);