Defer memory frees onto a thread

This commit is contained in:
baldurk
2023-04-13 11:31:53 +01:00
parent 6d765b1cc6
commit f413d4d084
3 changed files with 34 additions and 6 deletions
+1
View File
@@ -583,6 +583,7 @@ private:
// all 'base' allocations. The offset is used to indicate the current offset, and the size is the
// total size, thus the free space can be determined with size - offset.
rdcarray<MemoryAllocation> m_MemoryBlocks[arraydim<MemoryScope>()];
Threading::ThreadHandle m_MemoryFreeThread = 0;
// Per memory scope, the size of the next allocation. This allows us to balance number of memory
// allocation objects with size by incrementally allocating larger blocks.
+19 -6
View File
@@ -408,15 +408,28 @@ void WrappedVulkan::FreeAllMemory(MemoryScope scope)
if(allocList.empty())
return;
VkDevice d = GetDev();
for(MemoryAllocation alloc : allocList)
// freeing a lot of memory can take a while on some implementations. Since this only needs to
// externally synchronise the memory we do it on a thread and synchronise if we need to free again
// or on device shutdown
if(m_MemoryFreeThread)
{
ObjDisp(d)->FreeMemory(Unwrap(d), Unwrap(alloc.mem), NULL);
GetResourceManager()->ReleaseWrappedResource(alloc.mem);
Threading::JoinThread(m_MemoryFreeThread);
Threading::CloseThread(m_MemoryFreeThread);
m_MemoryFreeThread = 0;
}
allocList.clear();
VkDevice d = GetDev();
rdcarray<MemoryAllocation> allocs;
allocs.swap(allocList);
m_MemoryFreeThread = Threading::CreateThread([this, d, allocs]() {
for(const MemoryAllocation &alloc : allocs)
{
ObjDisp(d)->FreeMemory(Unwrap(d), Unwrap(alloc.mem), NULL);
GetResourceManager()->ReleaseWrappedResource(alloc.mem);
}
});
}
void WrappedVulkan::FreeMemoryAllocation(MemoryAllocation alloc)
@@ -955,6 +955,13 @@ void WrappedVulkan::Shutdown()
FreeAllMemory(MemoryScope::InitialContents);
if(m_MemoryFreeThread)
{
Threading::JoinThread(m_MemoryFreeThread);
Threading::CloseThread(m_MemoryFreeThread);
m_MemoryFreeThread = 0;
}
// we do more in Shutdown than the equivalent vkDestroyInstance since on replay there's
// no explicit vkDestroyDevice, we destroy the device here then the instance
@@ -4237,6 +4244,13 @@ void WrappedVulkan::vkDestroyDevice(VkDevice device, const VkAllocationCallbacks
if(device == VK_NULL_HANDLE)
return;
if(m_MemoryFreeThread)
{
Threading::JoinThread(m_MemoryFreeThread);
Threading::CloseThread(m_MemoryFreeThread);
m_MemoryFreeThread = 0;
}
// flush out any pending commands/semaphores
SubmitCmds();
SubmitSemaphores();