From 144a91ea9797674db8f4d2ecd5c5eeeaf574979e Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 18 Feb 2016 17:32:51 +0100 Subject: [PATCH] Correctly handle sparsely-defined descriptor set layouts (Refs #176) --- renderdoc/driver/vulkan/vk_info.cpp | 30 ++++++++++++++++++++--------- renderdoc/driver/vulkan/vk_info.h | 7 ++++++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index 00ca20ec9..eaca156d7 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -29,29 +29,41 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo { dynamicCount = 0; + // descriptor set layouts can be sparse, such that only three bindings exist + // but they are at 0, 5 and 10. + // We assume here that while the layouts may be sparse that's mostly to allow + // multiple layouts to co-exist nicely, and that we can allocate our bindings + // array to cover the whole size, and leave some elements unused. + + // will be at least this size. bindings.resize(pCreateInfo->bindingCount); for(uint32_t i=0; i < pCreateInfo->bindingCount; i++) { - bindings[i].descriptorCount = pCreateInfo->pBindings[i].descriptorCount; - bindings[i].descriptorType = pCreateInfo->pBindings[i].descriptorType; - bindings[i].stageFlags = pCreateInfo->pBindings[i].stageFlags; + uint32_t b = pCreateInfo->pBindings[i].binding; + // expand to fit the binding + if(b >= bindings.size()) + bindings.resize(b+1); - if(bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || - bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) + bindings[b].descriptorCount = pCreateInfo->pBindings[i].descriptorCount; + bindings[b].descriptorType = pCreateInfo->pBindings[i].descriptorType; + bindings[b].stageFlags = pCreateInfo->pBindings[i].stageFlags; + + if(bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || + bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) dynamicCount++; if(pCreateInfo->pBindings[i].pImmutableSamplers) { - bindings[i].immutableSampler = new ResourceId[bindings[i].descriptorCount]; + bindings[b].immutableSampler = new ResourceId[bindings[i].descriptorCount]; - for(uint32_t s=0; s < bindings[i].descriptorCount; s++) + for(uint32_t s=0; s < bindings[b].descriptorCount; s++) { // during writing, the create info contains the *wrapped* objects. // on replay, we have the wrapper map so we can look it up if(resourceMan->IsWriting()) - bindings[i].immutableSampler[s] = GetResID(pCreateInfo->pBindings[i].pImmutableSamplers[s]); + bindings[b].immutableSampler[s] = GetResID(pCreateInfo->pBindings[i].pImmutableSamplers[s]); else - bindings[i].immutableSampler[s] = resourceMan->GetNonDispWrapper(pCreateInfo->pBindings[i].pImmutableSamplers[s])->id; + bindings[b].immutableSampler[s] = resourceMan->GetNonDispWrapper(pCreateInfo->pBindings[i].pImmutableSamplers[s])->id; } } } diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index 3c23278fb..e5f1bc982 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -39,7 +39,12 @@ struct DescSetLayout struct Binding { - Binding() : immutableSampler(NULL) {} + // set reasonable defaults in the constructor as with sparse descriptor set layouts + // some elements could be untouched. We set stageFlags to 0 so the UI ignores these + // elements + Binding() + : descriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), descriptorCount(1) + , stageFlags(0), immutableSampler(NULL) {} ~Binding() { SAFE_DELETE_ARRAY(immutableSampler); } VkDescriptorType descriptorType;