Optimization: custom pools are on an intrusive double linked list not sorted vector
Added struct VmaPoolListItemTraits.
diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h
index 426309c..0e2b837 100644
--- a/src/vk_mem_alloc.h
+++ b/src/vk_mem_alloc.h
@@ -6015,11 +6015,11 @@
Expected interface of ItemTypeTraits:
struct MyItemTypeTraits
{
-typedef MyItem ItemType;
-static ItemType* GetPrev(const ItemType* item) { return item->myPrevPtr; }
-static ItemType* GetNext(const ItemType* item) { return item->myNextPtr; }
-static ItemType*& AccessPrev(ItemType* item) { return item->myPrevPtr; }
-static ItemType*& AccessNext(ItemType* item) { return item->myNextPtr; }
+ typedef MyItem ItemType;
+ static ItemType* GetPrev(const ItemType* item) { return item->myPrevPtr; }
+ static ItemType* GetNext(const ItemType* item) { return item->myNextPtr; }
+ static ItemType*& AccessPrev(ItemType* item) { return item->myPrevPtr; }
+ static ItemType*& AccessNext(ItemType* item) { return item->myNextPtr; }
};
*/
template<typename ItemTypeTraits>
@@ -7268,14 +7268,6 @@
void* m_pMappedData;
};
-struct VmaPointerLess
-{
- bool operator()(const void* lhs, const void* rhs) const
- {
- return lhs < rhs;
- }
-};
-
struct VmaDefragmentationMove
{
size_t srcBlockIndex;
@@ -7479,6 +7471,18 @@
private:
uint32_t m_Id;
char* m_Name;
+ VmaPool_T* m_PrevPool = VMA_NULL;
+ VmaPool_T* m_NextPool = VMA_NULL;
+ friend struct VmaPoolListItemTraits;
+};
+
+struct VmaPoolListItemTraits
+{
+ typedef VmaPool_T ItemType;
+ static ItemType* GetPrev(const ItemType* item) { return item->m_PrevPool; }
+ static ItemType* GetNext(const ItemType* item) { return item->m_NextPool; }
+ static ItemType*& AccessPrev(ItemType* item) { return item->m_PrevPool; }
+ static ItemType*& AccessNext(ItemType* item) { return item->m_NextPool; }
};
/*
@@ -8343,8 +8347,9 @@
VMA_ATOMIC_UINT32 m_GpuDefragmentationMemoryTypeBits; // UINT32_MAX means uninitialized.
VMA_RW_MUTEX m_PoolsMutex;
- // Protected by m_PoolsMutex. Sorted by pointer value.
- VmaVector<VmaPool, VmaStlAllocator<VmaPool> > m_Pools;
+ typedef VmaIntrusiveLinkedList<VmaPoolListItemTraits> PoolList;
+ // Protected by m_PoolsMutex.
+ PoolList m_Pools;
uint32_t m_NextPoolId;
VmaVulkanFunctions m_VulkanFunctions;
@@ -12852,6 +12857,7 @@
VmaPool_T::~VmaPool_T()
{
+ VMA_ASSERT(m_PrevPool == VMA_NULL && m_NextPool == VMA_NULL);
}
void VmaPool_T::SetName(const char* pName)
@@ -15976,7 +15982,6 @@
m_PhysicalDevice(pCreateInfo->physicalDevice),
m_CurrentFrameIndex(0),
m_GpuDefragmentationMemoryTypeBits(UINT32_MAX),
- m_Pools(VmaStlAllocator<VmaPool>(GetAllocationCallbacks())),
m_NextPoolId(0),
m_GlobalMemoryTypeBits(UINT32_MAX)
#if VMA_RECORDING_ENABLED
@@ -16158,7 +16163,7 @@
}
#endif
- VMA_ASSERT(m_Pools.empty());
+ VMA_ASSERT(m_Pools.IsEmpty());
for(size_t memTypeIndex = GetMemoryTypeCount(); memTypeIndex--; )
{
@@ -17003,9 +17008,9 @@
// Process custom pools.
{
VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex);
- for(size_t poolIndex = 0, poolCount = m_Pools.size(); poolIndex < poolCount; ++poolIndex)
+ for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool))
{
- m_Pools[poolIndex]->m_BlockVector.AddStats(pStats);
+ pool->m_BlockVector.AddStats(pStats);
}
}
@@ -17300,7 +17305,7 @@
{
VmaMutexLockWrite lock(m_PoolsMutex, m_UseMutex);
(*pPool)->SetId(m_NextPoolId++);
- VmaVectorInsertSorted<VmaPointerLess>(m_Pools, *pPool);
+ m_Pools.PushBack(*pPool);
}
return VK_SUCCESS;
@@ -17311,8 +17316,7 @@
// Remove from m_Pools.
{
VmaMutexLockWrite lock(m_PoolsMutex, m_UseMutex);
- bool success = VmaVectorRemoveSorted<VmaPointerLess>(m_Pools, pool);
- VMA_ASSERT(success && "Pool not found in Allocator.");
+ m_Pools.Remove(pool);
}
vma_delete(this, pool);
@@ -17377,11 +17381,11 @@
// Process custom pools.
{
VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex);
- for(size_t poolIndex = 0, poolCount = m_Pools.size(); poolIndex < poolCount; ++poolIndex)
+ for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool))
{
- if(((1u << m_Pools[poolIndex]->m_BlockVector.GetMemoryTypeIndex()) & memoryTypeBits) != 0)
+ if(((1u << pool->m_BlockVector.GetMemoryTypeIndex()) & memoryTypeBits) != 0)
{
- VkResult localRes = m_Pools[poolIndex]->m_BlockVector.CheckCorruption();
+ VkResult localRes = pool->m_BlockVector.CheckCorruption();
switch(localRes)
{
case VK_ERROR_FEATURE_NOT_PRESENT:
@@ -18015,18 +18019,17 @@
// Custom pools
{
VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex);
- const size_t poolCount = m_Pools.size();
- if(poolCount > 0)
+ if(!m_Pools.IsEmpty())
{
json.WriteString("Pools");
json.BeginObject();
- for(size_t poolIndex = 0; poolIndex < poolCount; ++poolIndex)
+ for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool))
{
json.BeginString();
- json.ContinueString(m_Pools[poolIndex]->GetId());
+ json.ContinueString(pool->GetId());
json.EndString();
- m_Pools[poolIndex]->m_BlockVector.PrintDetailedMap(json);
+ pool->m_BlockVector.PrintDetailedMap(json);
}
json.EndObject();
}