mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-28 21:01:04 +00:00
Add hackish but better handling of device memory initial states
* Device memory is always treated as dirty from creation. This means we will always prepare_initialstate for all memory. * We no longer force initial states for all memory. * Instead we iterate over all frame ref'd objects, and then ref their memory records - for framebuffers and view objects, we frame ref their parents so that they can in turn frame ref their memory record. * In future this should be built up at creation time and just iterated whenever we want to ref any of these objects (all the way down to mem)
This commit is contained in:
@@ -198,6 +198,8 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res)
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCASSERT(res != NULL);
|
||||
|
||||
if(type == eResDescriptorSet)
|
||||
{
|
||||
uint32_t numElems;
|
||||
@@ -205,8 +207,6 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res)
|
||||
|
||||
m_pSerialiser->SerialiseComplexArray("Bindings", bindings, numElems);
|
||||
|
||||
RDCASSERT(res != NULL);
|
||||
|
||||
const VulkanCreationInfo::DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[ m_DescriptorSetInfo[id].layout ];
|
||||
|
||||
uint32_t numBinds = (uint32_t)layout.bindings.size();
|
||||
@@ -353,7 +353,7 @@ void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool
|
||||
}
|
||||
else if(type == eResDeviceMemory)
|
||||
{
|
||||
RDCERR("Unexpected attempt to create initial state for memory");
|
||||
// ignore, it was probably dirty but not referenced in the frame
|
||||
}
|
||||
else if(type == eResFramebuffer)
|
||||
{
|
||||
|
||||
@@ -438,20 +438,56 @@ void VulkanResourceManager::ApplyTransitions(vector< pair<ResourceId, ImageRegio
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanResourceManager::Hack_PropagateReferencesToMemory()
|
||||
{
|
||||
// very nasty - prevents us re-processing the same entries when we loop
|
||||
// around to recursively propagate references.
|
||||
std::set<ResourceId> processed;
|
||||
|
||||
// VKTODOMED this is hack, should be done earlier, but for now it works.
|
||||
// iterate through every referenced resource and make sure its memory is referenced
|
||||
// too.
|
||||
for(auto it = m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it)
|
||||
{
|
||||
ResourceId id = it->first;
|
||||
|
||||
if(processed.find(id) != processed.end()) continue;
|
||||
processed.insert(id);
|
||||
|
||||
VkResourceRecord *record = GetResourceRecord(id);
|
||||
|
||||
if(record && record->GetMemoryRecord())
|
||||
{
|
||||
RDCLOG("Propagating reference from %llu to %llu", record->GetResourceID(), record->GetMemoryRecord()->GetResourceID());
|
||||
// mark it as read-before-write so that we ensure there are initial states serialised for it.
|
||||
MarkResourceFrameReferenced(record->GetMemoryRecord()->GetResourceID(), eFrameRef_ReadBeforeWrite);
|
||||
}
|
||||
else if(record && HasCurrentResource(id))
|
||||
{
|
||||
// also extra hack - framebuffers and views and things need to mark their
|
||||
// parents referenced so that we can eventually come to the image or buffer
|
||||
// with a memory record.
|
||||
WrappedVkRes *res = GetCurrentResource(id);
|
||||
|
||||
if(WrappedVkBufferView::IsAlloc(res) ||
|
||||
WrappedVkImageView::IsAlloc(res) ||
|
||||
WrappedVkAttachmentView::IsAlloc(res) ||
|
||||
WrappedVkFramebuffer::IsAlloc(res))
|
||||
{
|
||||
record->MarkParentsReferenced(this, eFrameRef_Read);
|
||||
|
||||
RDCLOG("Propagating references to parents from %llu", record->GetResourceID());
|
||||
|
||||
// reset to start so we can do this recursively - nasty I know.
|
||||
it = m_FrameReferencedResources.begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool VulkanResourceManager::Force_InitialState(WrappedVkRes *res)
|
||||
{
|
||||
// VKTODOMED don't want to be forcing device memory initial state, need to
|
||||
// know which objects have dirtied their bound memory.
|
||||
if(!WrappedVkDeviceMemory::IsAlloc(res))
|
||||
return false;
|
||||
|
||||
WrappedVkDeviceMemory *devmem = (WrappedVkDeviceMemory *)res;
|
||||
|
||||
// debug-only resources we don't want initial states for
|
||||
if(devmem->record == NULL)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VulkanResourceManager::Need_InitialStateChunk(WrappedVkRes *res)
|
||||
|
||||
@@ -83,6 +83,8 @@ class VulkanResourceManager : public ResourceManager<WrappedVkRes*, TypedRealHan
|
||||
{
|
||||
return realtype( (uint64_t) ((typename UnwrapHelper<realtype>::ParentType *)ResourceManager::GetCurrentResource(id)) );
|
||||
}
|
||||
|
||||
void Hack_PropagateReferencesToMemory();
|
||||
|
||||
// handling memory & image transitions
|
||||
void RecordTransitions(vector< pair<ResourceId, ImageRegionState> > &trans, map<ResourceId, ImgState> &states,
|
||||
|
||||
@@ -88,6 +88,10 @@ VkResult WrappedVulkan::vkAllocMemory(
|
||||
RDCASSERT(record);
|
||||
|
||||
record->AddChunk(chunk);
|
||||
|
||||
// VKTODOMED always treat memory as dirty for now, so its initial state
|
||||
// is guaranteed to be prepared
|
||||
GetResourceManager()->MarkDirtyResource(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -882,6 +882,8 @@ VkResult WrappedVulkan::vkQueuePresentWSI(
|
||||
m_pFileSerialiser->Insert(scope.Get(true));
|
||||
}
|
||||
|
||||
GetResourceManager()->Hack_PropagateReferencesToMemory();
|
||||
|
||||
RDCDEBUG("Inserting Resource Serialisers");
|
||||
|
||||
GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser);
|
||||
|
||||
Reference in New Issue
Block a user