Batch updates to background ref cache

* If the background cache is empty also (for a descriptor set that has never
  been written before) we can duplicate it straight from bindFrameRefs).
This commit is contained in:
baldurk
2020-08-18 16:36:42 +01:00
parent 0859aaa163
commit 8a350f28c8
4 changed files with 74 additions and 28 deletions
+11 -5
View File
@@ -1057,7 +1057,7 @@ void DescriptorSetSlotImageInfo::SetFrom(const VkDescriptorImageInfo &imInfo, bo
imageLayout = imInfo.imageLayout;
}
void DescriptorSetSlot::RemoveBindRefs(std::set<ResourceId> &ids, VulkanResourceManager *rm,
void DescriptorSetSlot::RemoveBindRefs(rdcarray<ResourceId> &ids, VulkanResourceManager *rm,
VkResourceRecord *record)
{
SCOPED_SPINLOCK(record->descInfo->refLock);
@@ -1105,7 +1105,7 @@ void DescriptorSetSlot::RemoveBindRefs(std::set<ResourceId> &ids, VulkanResource
imageInfo.sampler = ResourceId();
}
void DescriptorSetSlot::AddBindRefs(std::set<ResourceId> &ids, VkResourceRecord *bufView,
void DescriptorSetSlot::AddBindRefs(rdcarray<ResourceId> &ids, VkResourceRecord *bufView,
VkResourceRecord *imgView, VkResourceRecord *buffer,
VkResourceRecord *descSetRecord, FrameRefType ref)
{
@@ -1139,7 +1139,7 @@ void DescriptorSetSlot::AddBindRefs(std::set<ResourceId> &ids, VkResourceRecord
}
}
void DescriptorSetSlot::AddBindRefs(std::set<ResourceId> &ids, VulkanResourceManager *rm,
void DescriptorSetSlot::AddBindRefs(rdcarray<ResourceId> &ids, VulkanResourceManager *rm,
VkResourceRecord *descSetRecord, FrameRefType ref)
{
VkResourceRecord *bufView = NULL, *imgView = NULL, *buffer = NULL;
@@ -1154,11 +1154,17 @@ void DescriptorSetSlot::AddBindRefs(std::set<ResourceId> &ids, VulkanResourceMan
AddBindRefs(ids, bufView, imgView, buffer, descSetRecord, ref);
}
void DescriptorSetData::UpdateBackgroundRefCache(VulkanResourceManager *resourceManager,
const std::set<ResourceId> &ids)
void DescriptorSetData::UpdateBackgroundRefCache(const rdcarray<ResourceId> &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<ResourceId, FrameRefType> *cacheit = backgroundFrameRefs.begin();
for(auto refit = ids.begin(); refit != ids.end(); ++refit)
{
+3 -3
View File
@@ -430,10 +430,10 @@ struct DescriptorSetSlotImageInfo
struct DescriptorSetSlot
{
void RemoveBindRefs(std::set<ResourceId> &ids, VulkanResourceManager *rm, VkResourceRecord *record);
void AddBindRefs(std::set<ResourceId> &ids, VulkanResourceManager *rm, VkResourceRecord *record,
void RemoveBindRefs(rdcarray<ResourceId> &ids, VulkanResourceManager *rm, VkResourceRecord *record);
void AddBindRefs(rdcarray<ResourceId> &ids, VulkanResourceManager *rm, VkResourceRecord *record,
FrameRefType ref);
void AddBindRefs(std::set<ResourceId> &ids, VkResourceRecord *bufView, VkResourceRecord *imgView,
void AddBindRefs(rdcarray<ResourceId> &ids, VkResourceRecord *bufView, VkResourceRecord *imgView,
VkResourceRecord *buffer, VkResourceRecord *descSetRecord, FrameRefType ref);
// VkDescriptorBufferInfo
+13 -10
View File
@@ -1067,8 +1067,7 @@ struct DescriptorSetData
std::map<ResourceId, MemRefs> bindMemRefs;
std::map<ResourceId, ImageState> bindImageStates;
void UpdateBackgroundRefCache(VulkanResourceManager *resourceManager,
const std::set<ResourceId> &ids);
void UpdateBackgroundRefCache(const rdcarray<ResourceId> &ids);
rdcarray<rdcpair<ResourceId, FrameRefType>> backgroundFrameRefs;
};
@@ -2124,7 +2123,7 @@ public:
cmdInfo->memFrameRefs.swap(bakedCommands->cmdInfo->memFrameRefs);
}
void AddBindFrameRef(std::set<ResourceId> &ids, ResourceId id, FrameRefType ref,
void AddBindFrameRef(rdcarray<ResourceId> &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<uint32_t, FrameRefType> &p = descInfo->bindFrameRefs[id];
if((p.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0)
{
@@ -2148,9 +2148,10 @@ public:
}
}
void AddImgFrameRef(std::set<ResourceId> &ids, VkResourceRecord *view, FrameRefType refType)
void AddImgFrameRef(rdcarray<ResourceId> &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<ResourceId> &ids, ResourceId mem, VkDeviceSize offset,
void AddMemFrameRef(rdcarray<ResourceId> &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<uint32_t, FrameRefType> &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<ResourceId> &ids, ResourceId id)
void RemoveBindFrameRef(rdcarray<ResourceId> &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);
}
}
@@ -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<ResourceId> ids;
rdcarray<ResourceId> 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<ResourceId> ids;
rdcarray<ResourceId> 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);
}
}
}