mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 17:40:39 +00:00
When updating descriptor bind refs, cache resource references
* This means we don't have to iterate the whole bindrefs array every time we want to propagate references in the background, but we can submit them in batch.
This commit is contained in:
@@ -609,6 +609,7 @@ public:
|
||||
void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType, Compose comp);
|
||||
|
||||
inline void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType);
|
||||
void MarkBackgroundFrameReferenced(const rdcarray<rdcpair<ResourceId, FrameRefType>> &refs);
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Replay-side methods
|
||||
@@ -809,6 +810,41 @@ ResourceManager<Configuration>::~ResourceManager()
|
||||
RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this);
|
||||
}
|
||||
|
||||
template <typename Configuration>
|
||||
void ResourceManager<Configuration>::MarkBackgroundFrameReferenced(
|
||||
const rdcarray<rdcpair<ResourceId, FrameRefType>> &refs)
|
||||
{
|
||||
SCOPED_LOCK(m_Lock);
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
if(refs.size() <= m_ResourceRefTimes.size())
|
||||
{
|
||||
for(const rdcpair<ResourceId, FrameRefType> &ref : refs)
|
||||
{
|
||||
UpdateLastPartialUseTime(ref.first, ref.second);
|
||||
UpdateLastWriteTime(ref.first, ref.second);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(const ResourceRefTimes &res : m_ResourceRefTimes)
|
||||
{
|
||||
const rdcpair<ResourceId, FrameRefType> *it = std::lower_bound(
|
||||
refs.begin(), refs.end(), make_rdcpair(res.id, eFrameRef_None),
|
||||
[](const rdcpair<ResourceId, FrameRefType> &a,
|
||||
const rdcpair<ResourceId, FrameRefType> &b) { return a.first < b.first; });
|
||||
|
||||
if(it != refs.end() && it->first == res.id)
|
||||
{
|
||||
UpdateLastPartialUseTime(it->first, it->second);
|
||||
UpdateLastWriteTime(it->first, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Configuration>
|
||||
template <typename Compose>
|
||||
void ResourceManager<Configuration>::MarkResourceFrameReferenced(ResourceId id,
|
||||
|
||||
@@ -1098,37 +1098,76 @@ void DescriptorSetSlot::RemoveBindRefs(VulkanResourceManager *rm, VkResourceReco
|
||||
imageInfo.sampler = ResourceId();
|
||||
}
|
||||
|
||||
void DescriptorSetSlot::AddBindRefs(VulkanResourceManager *rm, VkResourceRecord *record,
|
||||
FrameRefType ref)
|
||||
void DescriptorSetSlot::AddBindRefs(std::set<ResourceId> &ids, VulkanResourceManager *rm,
|
||||
VkResourceRecord *record, FrameRefType ref)
|
||||
{
|
||||
SCOPED_LOCK(record->descInfo->refLock);
|
||||
|
||||
if(texelBufferView != ResourceId())
|
||||
{
|
||||
VkResourceRecord *bufView = rm->GetResourceRecord(texelBufferView);
|
||||
record->AddBindFrameRef(bufView->GetResourceID(), eFrameRef_Read,
|
||||
record->AddBindFrameRef(ids, bufView->GetResourceID(), eFrameRef_Read,
|
||||
bufView->resInfo && bufView->resInfo->IsSparse());
|
||||
if(bufView->baseResource != ResourceId())
|
||||
record->AddBindFrameRef(bufView->baseResource, eFrameRef_Read);
|
||||
record->AddBindFrameRef(ids, bufView->baseResource, eFrameRef_Read);
|
||||
if(bufView->baseResourceMem != ResourceId())
|
||||
record->AddMemFrameRef(bufView->baseResourceMem, bufView->memOffset, bufView->memSize, ref);
|
||||
record->AddMemFrameRef(ids, bufView->baseResourceMem, bufView->memOffset, bufView->memSize,
|
||||
ref);
|
||||
}
|
||||
if(imageInfo.imageView != ResourceId())
|
||||
{
|
||||
VkResourceRecord *view = rm->GetResourceRecord(imageInfo.imageView);
|
||||
record->AddImgFrameRef(view, ref);
|
||||
record->AddImgFrameRef(ids, view, ref);
|
||||
}
|
||||
if(imageInfo.sampler != ResourceId())
|
||||
{
|
||||
record->AddBindFrameRef(imageInfo.sampler, eFrameRef_Read);
|
||||
record->AddBindFrameRef(ids, imageInfo.sampler, eFrameRef_Read);
|
||||
}
|
||||
if(bufferInfo.buffer != ResourceId())
|
||||
{
|
||||
VkResourceRecord *buf = rm->GetResourceRecord(bufferInfo.buffer);
|
||||
record->AddBindFrameRef(bufferInfo.buffer, eFrameRef_Read,
|
||||
record->AddBindFrameRef(ids, bufferInfo.buffer, eFrameRef_Read,
|
||||
buf->resInfo && buf->resInfo->IsSparse());
|
||||
if(buf->baseResource != ResourceId())
|
||||
record->AddMemFrameRef(buf->baseResource, buf->memOffset, buf->memSize, ref);
|
||||
record->AddMemFrameRef(ids, buf->baseResource, buf->memOffset, buf->memSize, ref);
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorSetData::UpdateBackgroundRefCache(VulkanResourceManager *resourceManager,
|
||||
const std::set<ResourceId> &ids)
|
||||
{
|
||||
SCOPED_LOCK(refLock);
|
||||
|
||||
rdcpair<ResourceId, FrameRefType> *cacheit = backgroundFrameRefs.begin();
|
||||
for(auto refit = ids.begin(); refit != ids.end(); ++refit)
|
||||
{
|
||||
ResourceId id = *refit;
|
||||
FrameRefType refType = bindFrameRefs[id].second;
|
||||
|
||||
// find the Id we're looking for in the remainder of the cache. This won't skip over any one
|
||||
// that we care about because we're iterating in ascending Id order
|
||||
cacheit = std::lower_bound(
|
||||
cacheit, backgroundFrameRefs.end(), make_rdcpair(id, eFrameRef_None),
|
||||
[](const rdcpair<ResourceId, FrameRefType> &a, const rdcpair<ResourceId, FrameRefType> &b) {
|
||||
return a.first < b.first;
|
||||
});
|
||||
|
||||
// if we didn't find a match, insert the desired entry here
|
||||
if(cacheit == backgroundFrameRefs.end() || cacheit->first != id)
|
||||
{
|
||||
// calculate the index
|
||||
size_t idx = cacheit - backgroundFrameRefs.begin();
|
||||
// insert the entry
|
||||
backgroundFrameRefs.insert(idx, {id, refType});
|
||||
// re-initialise our iterator to point here, as the above insert might have invalidated it due
|
||||
// to a resize
|
||||
cacheit = backgroundFrameRefs.begin() + idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
// update the frameref
|
||||
cacheit->second = refType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -431,7 +431,8 @@ struct DescriptorSetSlotImageInfo
|
||||
struct DescriptorSetSlot
|
||||
{
|
||||
void RemoveBindRefs(VulkanResourceManager *rm, VkResourceRecord *record);
|
||||
void AddBindRefs(VulkanResourceManager *rm, VkResourceRecord *record, FrameRefType ref);
|
||||
void AddBindRefs(std::set<ResourceId> &ids, VulkanResourceManager *rm, VkResourceRecord *record,
|
||||
FrameRefType ref);
|
||||
|
||||
// VkDescriptorBufferInfo
|
||||
DescriptorSetSlotBufferInfo bufferInfo;
|
||||
|
||||
@@ -1063,9 +1063,14 @@ struct DescriptorSetData
|
||||
// the refcount has the high-bit set if this resource has sparse
|
||||
// mapping information
|
||||
static const uint32_t SPARSE_REF_BIT = 0x80000000;
|
||||
std::map<ResourceId, rdcpair<uint32_t, FrameRefType> > bindFrameRefs;
|
||||
std::map<ResourceId, rdcpair<uint32_t, FrameRefType>> bindFrameRefs;
|
||||
std::map<ResourceId, MemRefs> bindMemRefs;
|
||||
std::map<ResourceId, ImageState> bindImageStates;
|
||||
|
||||
void UpdateBackgroundRefCache(VulkanResourceManager *resourceManager,
|
||||
const std::set<ResourceId> &ids);
|
||||
|
||||
rdcarray<rdcpair<ResourceId, FrameRefType>> backgroundFrameRefs;
|
||||
};
|
||||
|
||||
struct PipelineLayoutData
|
||||
@@ -1818,7 +1823,7 @@ struct ImgRefs
|
||||
}
|
||||
InitReqType SubresourceRangeMaxInitReq(VkImageSubresourceRange range, InitPolicy policy,
|
||||
bool initialized) const;
|
||||
rdcarray<rdcpair<VkImageSubresourceRange, InitReqType> > SubresourceRangeInitReqs(
|
||||
rdcarray<rdcpair<VkImageSubresourceRange, InitReqType>> SubresourceRangeInitReqs(
|
||||
VkImageSubresourceRange range, InitPolicy policy, bool initialized) const;
|
||||
void Split(bool splitAspects, bool splitLevels, bool splitLayers);
|
||||
template <typename Compose>
|
||||
@@ -2116,13 +2121,15 @@ public:
|
||||
cmdInfo->memFrameRefs.swap(bakedCommands->cmdInfo->memFrameRefs);
|
||||
}
|
||||
|
||||
void AddBindFrameRef(ResourceId id, FrameRefType ref, bool hasSparse = false)
|
||||
void AddBindFrameRef(std::set<ResourceId> &ids, ResourceId id, FrameRefType ref,
|
||||
bool hasSparse = false)
|
||||
{
|
||||
if(id == ResourceId())
|
||||
{
|
||||
RDCERR("Unexpected NULL resource ID being added as a bind frame ref");
|
||||
return;
|
||||
}
|
||||
ids.insert(id);
|
||||
rdcpair<uint32_t, FrameRefType> &p = descInfo->bindFrameRefs[id];
|
||||
if((p.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0)
|
||||
{
|
||||
@@ -2138,12 +2145,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void AddImgFrameRef(VkResourceRecord *view, FrameRefType refType)
|
||||
void AddImgFrameRef(std::set<ResourceId> &ids, VkResourceRecord *view, FrameRefType refType)
|
||||
{
|
||||
AddBindFrameRef(view->GetResourceID(), eFrameRef_Read,
|
||||
AddBindFrameRef(ids, view->GetResourceID(), eFrameRef_Read,
|
||||
view->resInfo && view->resInfo->IsSparse());
|
||||
if(view->baseResourceMem != ResourceId())
|
||||
AddBindFrameRef(view->baseResourceMem, eFrameRef_Read, false);
|
||||
AddBindFrameRef(ids, view->baseResourceMem, eFrameRef_Read, false);
|
||||
|
||||
rdcpair<uint32_t, FrameRefType> &p = descInfo->bindFrameRefs[view->baseResource];
|
||||
if((p.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0)
|
||||
@@ -2167,13 +2174,15 @@ public:
|
||||
p.second = ComposeFrameRefsDisjoint(p.second, maxRef);
|
||||
}
|
||||
|
||||
void AddMemFrameRef(ResourceId mem, VkDeviceSize offset, VkDeviceSize size, FrameRefType refType)
|
||||
void AddMemFrameRef(std::set<ResourceId> &ids, ResourceId mem, VkDeviceSize offset,
|
||||
VkDeviceSize size, FrameRefType refType)
|
||||
{
|
||||
if(mem == ResourceId())
|
||||
{
|
||||
RDCERR("Unexpected NULL resource ID being added as a bind frame ref");
|
||||
return;
|
||||
}
|
||||
ids.insert(mem);
|
||||
rdcpair<uint32_t, FrameRefType> &p = descInfo->bindFrameRefs[mem];
|
||||
if((p.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0)
|
||||
{
|
||||
|
||||
@@ -1054,6 +1054,8 @@ 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;
|
||||
|
||||
for(uint32_t i = 0; i < writeCount; i++)
|
||||
{
|
||||
const VkWriteDescriptorSet &descWrite = pDescriptorWrites[i];
|
||||
@@ -1089,6 +1091,8 @@ 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
|
||||
@@ -1154,8 +1158,10 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount,
|
||||
bind.bufferInfo.SetFrom(descWrite.pBufferInfo[d]);
|
||||
}
|
||||
|
||||
bind.AddBindRefs(GetResourceManager(), record, ref);
|
||||
bind.AddBindRefs(ids, GetResourceManager(), record, ref);
|
||||
}
|
||||
|
||||
record->descInfo->UpdateBackgroundRefCache(GetResourceManager(), ids);
|
||||
}
|
||||
|
||||
// this is almost identical to the above loop, except that instead of sourcing the descriptors
|
||||
@@ -1192,6 +1198,8 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount,
|
||||
uint32_t curSrcIdx = pDescriptorCopies[i].srcArrayElement;
|
||||
uint32_t curDstIdx = pDescriptorCopies[i].dstArrayElement;
|
||||
|
||||
ids.clear();
|
||||
|
||||
for(uint32_t d = 0; d < pDescriptorCopies[i].descriptorCount; d++, curSrcIdx++, curDstIdx++)
|
||||
{
|
||||
if(srclayoutBinding->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
|
||||
@@ -1230,8 +1238,10 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount,
|
||||
|
||||
bind.RemoveBindRefs(GetResourceManager(), dstrecord);
|
||||
bind = (*srcbinding)[curSrcIdx];
|
||||
bind.AddBindRefs(GetResourceManager(), dstrecord, ref);
|
||||
bind.AddBindRefs(ids, GetResourceManager(), dstrecord, ref);
|
||||
}
|
||||
|
||||
dstrecord->descInfo->UpdateBackgroundRefCache(GetResourceManager(), ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1475,9 +1485,12 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate(
|
||||
// need to track descriptor set contents whether capframing or idle
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
std::set<ResourceId> ids;
|
||||
|
||||
for(const VkDescriptorUpdateTemplateEntry &entry : tempInfo->updates)
|
||||
{
|
||||
VkResourceRecord *record = GetRecord(descriptorSet);
|
||||
|
||||
RDCASSERT(record->descInfo && record->descInfo->layout);
|
||||
const DescSetLayout &layout = *record->descInfo->layout;
|
||||
|
||||
@@ -1493,6 +1506,8 @@ 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
|
||||
@@ -1559,8 +1574,10 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate(
|
||||
bind.bufferInfo.SetFrom(*(const VkDescriptorBufferInfo *)src);
|
||||
}
|
||||
|
||||
bind.AddBindRefs(GetResourceManager(), record, ref);
|
||||
bind.AddBindRefs(ids, GetResourceManager(), record, ref);
|
||||
}
|
||||
|
||||
record->descInfo->UpdateBackgroundRefCache(GetResourceManager(), ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1007,19 +1007,8 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount,
|
||||
|
||||
SCOPED_LOCK(setrecord->descInfo->refLock);
|
||||
|
||||
for(auto refit = setrecord->descInfo->bindFrameRefs.begin();
|
||||
refit != setrecord->descInfo->bindFrameRefs.end(); ++refit)
|
||||
{
|
||||
GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second);
|
||||
|
||||
if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT)
|
||||
{
|
||||
VkResourceRecord *sparserecord =
|
||||
GetResourceManager()->GetResourceRecord(refit->first);
|
||||
|
||||
GetResourceManager()->MarkSparseMapReferenced(sparserecord->resInfo);
|
||||
}
|
||||
}
|
||||
GetResourceManager()->MarkBackgroundFrameReferenced(
|
||||
setrecord->descInfo->backgroundFrameRefs);
|
||||
}
|
||||
|
||||
record->bakedCommands->AddResourceReferences(GetResourceManager());
|
||||
|
||||
Reference in New Issue
Block a user