From 812e601a88ffbd7829052280f902e23cd66b989c Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 23 Sep 2019 16:48:04 +0100 Subject: [PATCH] Ignore sampler updates when descset has immutable samplers. Closes #1528 --- .../vulkan/wrappers/vk_descriptor_funcs.cpp | 31 ++++++++++++++- util/test/demos/vk/vk_parameter_zoo.cpp | 39 ++++++++++++++++--- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index 6127f24f8..24b8fb3bb 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -835,6 +835,31 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, for(uint32_t i = 0; i < writeCount; i++) { unwrappedWrites[i] = pDescriptorWrites[i]; + + bool hasImmutable = false; + + if(IsCaptureMode(m_State)) + { + VkResourceRecord *record = GetRecord(unwrappedWrites[i].dstSet); + RDCASSERT(record->descInfo && record->descInfo->layout); + const DescSetLayout &layout = *record->descInfo->layout; + + RDCASSERT(unwrappedWrites[i].dstBinding < record->descInfo->descBindings.size()); + const DescSetLayout::Binding *layoutBinding = &layout.bindings[unwrappedWrites[i].dstBinding]; + + hasImmutable = layoutBinding->immutableSampler != NULL; + } + else + { + const DescSetLayout &layout = + m_CreationInfo + .m_DescSetLayout[m_DescriptorSetState[GetResID(unwrappedWrites[i].dstSet)].layout]; + + const DescSetLayout::Binding *layoutBinding = &layout.bindings[unwrappedWrites[i].dstBinding]; + + hasImmutable = layoutBinding->immutableSampler != NULL; + } + unwrappedWrites[i].dstSet = Unwrap(unwrappedWrites[i].dstSet); VkDescriptorBufferInfo *bufInfos = nextDescriptors; @@ -863,7 +888,8 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, { bool hasSampler = (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) && + !hasImmutable; bool hasImage = (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || @@ -1050,6 +1076,9 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, bind.imageInfo.imageView = VK_NULL_HANDLE; else if(descWrite.descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) bind.imageInfo.sampler = VK_NULL_HANDLE; + + if(layoutBinding->immutableSampler) + bind.imageInfo.sampler = VK_NULL_HANDLE; } else { diff --git a/util/test/demos/vk/vk_parameter_zoo.cpp b/util/test/demos/vk/vk_parameter_zoo.cpp index 7ec9f2a8a..02fefe141 100644 --- a/util/test/demos/vk/vk_parameter_zoo.cpp +++ b/util/test/demos/vk/vk_parameter_zoo.cpp @@ -103,6 +103,17 @@ void main() {10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_SHADER_STAGE_VERTEX_BIT}, })); + VkSampler invalidSampler = (VkSampler)0x1234; + VkSampler validSampler = VK_NULL_HANDLE; + VkSamplerCreateInfo sampInfo = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; + sampInfo.magFilter = VK_FILTER_LINEAR; + sampInfo.minFilter = VK_FILTER_LINEAR; + vkCreateSampler(device, &sampInfo, NULL, &validSampler); + + VkDescriptorSetLayout immutsetlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({ + {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, &validSampler}, + })); + VkDescriptorSetLayout pushlayout = VK_NULL_HANDLE; VkPipelineLayout layout; @@ -123,6 +134,9 @@ void main() layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout})); } + VkPipelineLayout immutlayout = + createPipelineLayout(vkh::PipelineLayoutCreateInfo({immutsetlayout})); + vkh::GraphicsPipelineCreateInfo pipeCreateInfo; pipeCreateInfo.layout = layout; @@ -141,6 +155,10 @@ void main() VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo); + pipeCreateInfo.layout = immutlayout; + + VkPipeline immutpipe = createGraphicsPipeline(pipeCreateInfo); + { // invalid handle - should not be used because the flag for derived pipelines is not used pipeCreateInfo.basePipelineHandle = (VkPipeline)0x1234; @@ -203,12 +221,7 @@ void main() VkDescriptorSet descset = allocateDescriptorSet(setlayout); - VkSampler invalidSampler = (VkSampler)0x1234; - VkSampler validSampler = VK_NULL_HANDLE; - VkSamplerCreateInfo sampInfo = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; - sampInfo.magFilter = VK_FILTER_LINEAR; - sampInfo.minFilter = VK_FILTER_LINEAR; - vkCreateSampler(device, &sampInfo, NULL, &validSampler); + VkDescriptorSet immutdescset = allocateDescriptorSet(immutsetlayout); AllocatedBuffer buf(allocator, vkh::BufferCreateInfo(1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | @@ -273,6 +286,11 @@ void main() vkh::WriteDescriptorSet(descset, 7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, validBufInfos), vkh::WriteDescriptorSet(descset, 8, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, validBufInfos), vkh::WriteDescriptorSet(descset, 9, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, validBufInfos), + + vkh::WriteDescriptorSet(immutdescset, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + validCombinedImgs), + vkh::WriteDescriptorSet(immutdescset, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + validSoloImgs), }; // do a first update @@ -319,6 +337,9 @@ void main() writes[9].pTexelBufferView = &invalidBufView; writes[9].pImageInfo = &invalidImgInfo; + writes[10].pTexelBufferView = &invalidBufView; + writes[10].pBufferInfo = &invalidBufInfo; + vkh::updateDescriptorSets(device, writes); // finally set invalid pointers too @@ -470,6 +491,12 @@ void main() vkCmdPushDescriptorSetWithTemplateKHR(cmd, pushtempl, layout, 1, &pushdata); vkCmdDraw(cmd, 3, 1, 0, 0); + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, immutpipe); + vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, immutlayout, 0, + {immutdescset}, {}); + + vkCmdDraw(cmd, 3, 1, 0, 0); + vkCmdEndRenderPass(cmd); FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);