diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index 8b8c3218c..c89667458 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -1057,7 +1057,7 @@ void DescriptorSetSlotImageInfo::SetFrom(const VkDescriptorImageInfo &imInfo, bo imageLayout = imInfo.imageLayout; } -void DescriptorSetSlot::RemoveBindRefs(std::set &ids, VulkanResourceManager *rm, +void DescriptorSetSlot::RemoveBindRefs(rdcarray &ids, VulkanResourceManager *rm, VkResourceRecord *record) { SCOPED_SPINLOCK(record->descInfo->refLock); @@ -1105,7 +1105,7 @@ void DescriptorSetSlot::RemoveBindRefs(std::set &ids, VulkanResource imageInfo.sampler = ResourceId(); } -void DescriptorSetSlot::AddBindRefs(std::set &ids, VkResourceRecord *bufView, +void DescriptorSetSlot::AddBindRefs(rdcarray &ids, VkResourceRecord *bufView, VkResourceRecord *imgView, VkResourceRecord *buffer, VkResourceRecord *descSetRecord, FrameRefType ref) { @@ -1139,7 +1139,7 @@ void DescriptorSetSlot::AddBindRefs(std::set &ids, VkResourceRecord } } -void DescriptorSetSlot::AddBindRefs(std::set &ids, VulkanResourceManager *rm, +void DescriptorSetSlot::AddBindRefs(rdcarray &ids, VulkanResourceManager *rm, VkResourceRecord *descSetRecord, FrameRefType ref) { VkResourceRecord *bufView = NULL, *imgView = NULL, *buffer = NULL; @@ -1154,11 +1154,17 @@ void DescriptorSetSlot::AddBindRefs(std::set &ids, VulkanResourceMan AddBindRefs(ids, bufView, imgView, buffer, descSetRecord, ref); } -void DescriptorSetData::UpdateBackgroundRefCache(VulkanResourceManager *resourceManager, - const std::set &ids) +void DescriptorSetData::UpdateBackgroundRefCache(const rdcarray &ids) { SCOPED_SPINLOCK(refLock); + if(backgroundFrameRefs.empty()) + { + for(auto refit = bindFrameRefs.begin(); refit != bindFrameRefs.end(); ++refit) + backgroundFrameRefs.push_back(make_rdcpair(refit->first, refit->second.second)); + return; + } + rdcpair *cacheit = backgroundFrameRefs.begin(); for(auto refit = ids.begin(); refit != ids.end(); ++refit) { diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index dd9feaf3d..29412a883 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -430,10 +430,10 @@ struct DescriptorSetSlotImageInfo struct DescriptorSetSlot { - void RemoveBindRefs(std::set &ids, VulkanResourceManager *rm, VkResourceRecord *record); - void AddBindRefs(std::set &ids, VulkanResourceManager *rm, VkResourceRecord *record, + void RemoveBindRefs(rdcarray &ids, VulkanResourceManager *rm, VkResourceRecord *record); + void AddBindRefs(rdcarray &ids, VulkanResourceManager *rm, VkResourceRecord *record, FrameRefType ref); - void AddBindRefs(std::set &ids, VkResourceRecord *bufView, VkResourceRecord *imgView, + void AddBindRefs(rdcarray &ids, VkResourceRecord *bufView, VkResourceRecord *imgView, VkResourceRecord *buffer, VkResourceRecord *descSetRecord, FrameRefType ref); // VkDescriptorBufferInfo diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 2341718d3..97eba44ca 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -1067,8 +1067,7 @@ struct DescriptorSetData std::map bindMemRefs; std::map bindImageStates; - void UpdateBackgroundRefCache(VulkanResourceManager *resourceManager, - const std::set &ids); + void UpdateBackgroundRefCache(const rdcarray &ids); rdcarray> backgroundFrameRefs; }; @@ -2124,7 +2123,7 @@ public: cmdInfo->memFrameRefs.swap(bakedCommands->cmdInfo->memFrameRefs); } - void AddBindFrameRef(std::set &ids, ResourceId id, FrameRefType ref, + void AddBindFrameRef(rdcarray &ids, ResourceId id, FrameRefType ref, bool hasSparse = false) { if(id == ResourceId()) @@ -2132,7 +2131,8 @@ public: RDCERR("Unexpected NULL resource ID being added as a bind frame ref"); return; } - ids.insert(id); + if(!ids.contains(id)) + ids.push_back(id); rdcpair &p = descInfo->bindFrameRefs[id]; if((p.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0) { @@ -2148,9 +2148,10 @@ public: } } - void AddImgFrameRef(std::set &ids, VkResourceRecord *view, FrameRefType refType) + void AddImgFrameRef(rdcarray &ids, VkResourceRecord *view, FrameRefType refType) { - ids.insert(view->baseResource); + if(!ids.contains(view->baseResource)) + ids.push_back(view->baseResource); AddBindFrameRef(ids, view->GetResourceID(), eFrameRef_Read, view->resInfo && view->resInfo->IsSparse()); if(view->baseResourceMem != ResourceId()) @@ -2178,7 +2179,7 @@ public: p.second = ComposeFrameRefsDisjoint(p.second, maxRef); } - void AddMemFrameRef(std::set &ids, ResourceId mem, VkDeviceSize offset, + void AddMemFrameRef(rdcarray &ids, ResourceId mem, VkDeviceSize offset, VkDeviceSize size, FrameRefType refType) { if(mem == ResourceId()) @@ -2186,7 +2187,8 @@ public: RDCERR("Unexpected NULL resource ID being added as a bind frame ref"); return; } - ids.insert(mem); + if(!ids.contains(mem)) + ids.push_back(mem); rdcpair &p = descInfo->bindFrameRefs[mem]; if((p.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0) { @@ -2203,7 +2205,7 @@ public: p.second = ComposeFrameRefsDisjoint(p.second, maxRef); } - void RemoveBindFrameRef(std::set &ids, ResourceId id) + void RemoveBindFrameRef(rdcarray &ids, ResourceId id) { // ignore any NULL IDs - probably an object that was // deleted since it was bound. @@ -2223,7 +2225,8 @@ public: if((it->second.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0) { - ids.insert(id); + if(!ids.contains(id)) + ids.push_back(id); descInfo->bindFrameRefs.erase(it); } } diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index cdc0038fc..6551e1d76 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -1146,7 +1146,10 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, // need to track descriptor set contents whether capframing or idle if(IsCaptureMode(m_State)) { - std::set ids; + rdcarray ids; + VkResourceRecord *setrecord = NULL; + + ids.reserve(128); for(uint32_t i = 0; i < writeCount; i++) { @@ -1156,6 +1159,17 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, RDCASSERT(record->descInfo && record->descInfo->layout); const DescSetLayout &layout = *record->descInfo->layout; + if(setrecord && setrecord != record) + { + std::sort(ids.begin(), ids.end()); + + setrecord->descInfo->UpdateBackgroundRefCache(ids); + + ids.clear(); + } + + setrecord = record; + RDCASSERT(descWrite.dstBinding < record->descInfo->data.binds.size()); DescriptorSetSlot **binding = &record->descInfo->data.binds[descWrite.dstBinding]; @@ -1183,8 +1197,6 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, // start at the dstArrayElement uint32_t curIdx = descWrite.dstArrayElement; - ids.clear(); - for(uint32_t d = 0; d < descWrite.descriptorCount; d++, curIdx++) { // roll over onto the next binding, on the assumption that it is the same @@ -1261,10 +1273,16 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, bind.AddBindRefs(ids, bufView, imgView, buffer, record, ref); } - - record->descInfo->UpdateBackgroundRefCache(GetResourceManager(), ids); } + if(setrecord) + { + std::sort(ids.begin(), ids.end()); + + setrecord->descInfo->UpdateBackgroundRefCache(ids); + } + setrecord = NULL; + // this is almost identical to the above loop, except that instead of sourcing the descriptors // from the writedescriptor struct, we source it from our stored bindings on the source // descrpitor set @@ -1344,7 +1362,9 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, bind.AddBindRefs(ids, GetResourceManager(), dstrecord, ref); } - dstrecord->descInfo->UpdateBackgroundRefCache(GetResourceManager(), ids); + std::sort(ids.begin(), ids.end()); + + dstrecord->descInfo->UpdateBackgroundRefCache(ids); } } } @@ -1588,12 +1608,26 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate( // need to track descriptor set contents whether capframing or idle if(IsCaptureMode(m_State)) { - std::set ids; + rdcarray ids; + VkResourceRecord *setrecord = NULL; + + ids.reserve(128); for(const VkDescriptorUpdateTemplateEntry &entry : tempInfo->updates) { VkResourceRecord *record = GetRecord(descriptorSet); + if(setrecord && setrecord != record) + { + std::sort(ids.begin(), ids.end()); + + setrecord->descInfo->UpdateBackgroundRefCache(ids); + + ids.clear(); + } + + setrecord = record; + RDCASSERT(record->descInfo && record->descInfo->layout); const DescSetLayout &layout = *record->descInfo->layout; @@ -1609,8 +1643,6 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate( // start at the dstArrayElement uint32_t curIdx = entry.dstArrayElement; - ids.clear(); - for(uint32_t d = 0; d < entry.descriptorCount; d++, curIdx++) { // roll over onto the next binding, on the assumption that it is the same @@ -1681,8 +1713,13 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate( bind.AddBindRefs(ids, GetResourceManager(), record, ref); } + } - record->descInfo->UpdateBackgroundRefCache(GetResourceManager(), ids); + if(setrecord) + { + std::sort(ids.begin(), ids.end()); + + setrecord->descInfo->UpdateBackgroundRefCache(ids); } } }