diff --git a/src/Tests.cpp b/src/Tests.cpp index a79b9a8..c65d1a4 100644 --- a/src/Tests.cpp +++ b/src/Tests.cpp @@ -1733,7 +1733,7 @@ static void TestLinearAllocator() } // Allocate number of buffers until pool is full again. - // This way we make sure ring buffers wraps around. + // This way we make sure ring buffers wraps around, front in in the middle. res = VK_SUCCESS; for(size_t i = 0; res == VK_SUCCESS; ++i) { @@ -1786,6 +1786,35 @@ static void TestLinearAllocator() break; } + // Delete buffers that are lost. + for(size_t i = bufInfo.size(); i--; ) + { + vmaGetAllocationInfo(g_hAllocator, bufInfo[i].Allocation, &allocInfo); + if(allocInfo.deviceMemory == VK_NULL_HANDLE) + { + vmaDestroyBuffer(g_hAllocator, bufInfo[i].Buffer, bufInfo[i].Allocation); + bufInfo.erase(bufInfo.begin() + i); + } + } + + // Test vmaMakePoolAllocationsLost + { + vmaSetCurrentFrameIndex(g_hAllocator, ++g_FrameIndex); + + size_t lostAllocCount = SIZE_MAX; + vmaMakePoolAllocationsLost(g_hAllocator, pool, &lostAllocCount); + assert(lostAllocCount > 0); + + size_t realLostAllocCount = 0; + for(size_t i = 0; i < bufInfo.size(); ++i) + { + vmaGetAllocationInfo(g_hAllocator, bufInfo[i].Allocation, &allocInfo); + if(allocInfo.deviceMemory == VK_NULL_HANDLE) + ++realLostAllocCount; + } + assert(realLostAllocCount == lostAllocCount); + } + // Destroy all the buffers in forward order. for(size_t i = 0; i < bufInfo.size(); ++i) vmaDestroyBuffer(g_hAllocator, bufInfo[i].Buffer, bufInfo[i].Allocation); diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h index 84b3adc..acec2a1 100644 --- a/src/vk_mem_alloc.h +++ b/src/vk_mem_alloc.h @@ -8504,8 +8504,44 @@ bool VmaBlockMetadata_Linear::MakeRequestedAllocationsLost( uint32_t VmaBlockMetadata_Linear::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) { - VMA_ASSERT(0 && "TODO"); - return 0; + uint32_t lostAllocationCount = 0; + + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + for(size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i) + { + VmaSuballocation& suballoc = suballocations1st[i]; + if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE && + suballoc.hAllocation->CanBecomeLost() && + suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) + { + suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + suballoc.hAllocation = VK_NULL_HANDLE; + ++m_1stNullItemsMiddleCount; + ++lostAllocationCount; + } + } + + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + for(size_t i = 0, count = suballocations2nd.size(); i < count; ++i) + { + VmaSuballocation& suballoc = suballocations2nd[i]; + if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE && + suballoc.hAllocation->CanBecomeLost() && + suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) + { + suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + suballoc.hAllocation = VK_NULL_HANDLE; + ++m_2ndNullItemsCount; + ++lostAllocationCount; + } + } + + if(lostAllocationCount) + { + CleanupAfterFree(); + } + + return lostAllocationCount; } VkResult VmaBlockMetadata_Linear::CheckCorruption(const void* pBlockData)