Improved VmaPoolAllocator to use larger and larger block sizes instead of constant size.
diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h
index 9c262ec..5ae0c29 100644
--- a/src/vk_mem_alloc.h
+++ b/src/vk_mem_alloc.h
@@ -4209,7 +4209,7 @@
{
VMA_CLASS_NO_COPY(VmaPoolAllocator)
public:
- VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, size_t itemsPerBlock);
+ VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity);
~VmaPoolAllocator();
void Clear();
T* Alloc();
@@ -4225,23 +4225,24 @@
struct ItemBlock
{
Item* pItems;
+ uint32_t Capacity;
uint32_t FirstFreeIndex;
};
const VkAllocationCallbacks* m_pAllocationCallbacks;
- size_t m_ItemsPerBlock;
+ const uint32_t m_FirstBlockCapacity;
VmaVector< ItemBlock, VmaStlAllocator<ItemBlock> > m_ItemBlocks;
ItemBlock& CreateNewBlock();
};
template<typename T>
-VmaPoolAllocator<T>::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, size_t itemsPerBlock) :
+VmaPoolAllocator<T>::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity) :
m_pAllocationCallbacks(pAllocationCallbacks),
- m_ItemsPerBlock(itemsPerBlock),
+ m_FirstBlockCapacity(firstBlockCapacity),
m_ItemBlocks(VmaStlAllocator<ItemBlock>(pAllocationCallbacks))
{
- VMA_ASSERT(itemsPerBlock > 0);
+ VMA_ASSERT(m_FirstBlockCapacity > 1);
}
template<typename T>
@@ -4254,7 +4255,7 @@
void VmaPoolAllocator<T>::Clear()
{
for(size_t i = m_ItemBlocks.size(); i--; )
- vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemsPerBlock);
+ vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemBlocks[i].Capacity);
m_ItemBlocks.clear();
}
@@ -4284,7 +4285,7 @@
void VmaPoolAllocator<T>::Free(T* ptr)
{
// Search all memory blocks to find ptr.
- for(size_t i = 0; i < m_ItemBlocks.size(); ++i)
+ for(size_t i = m_ItemBlocks.size(); i--; )
{
ItemBlock& block = m_ItemBlocks[i];
@@ -4293,7 +4294,7 @@
memcpy(&pItemPtr, &ptr, sizeof(pItemPtr));
// Check if pItemPtr is in address range of this block.
- if((pItemPtr >= block.pItems) && (pItemPtr < block.pItems + m_ItemsPerBlock))
+ if((pItemPtr >= block.pItems) && (pItemPtr < block.pItems + block.Capacity))
{
const uint32_t index = static_cast<uint32_t>(pItemPtr - block.pItems);
pItemPtr->NextFreeIndex = block.FirstFreeIndex;
@@ -4307,15 +4308,20 @@
template<typename T>
typename VmaPoolAllocator<T>::ItemBlock& VmaPoolAllocator<T>::CreateNewBlock()
{
- ItemBlock newBlock = {
- vma_new_array(m_pAllocationCallbacks, Item, m_ItemsPerBlock), 0 };
+ const uint32_t newBlockCapacity = m_ItemBlocks.empty() ?
+ m_FirstBlockCapacity : m_ItemBlocks.back().Capacity * 3 / 2;
+
+ const ItemBlock newBlock = {
+ vma_new_array(m_pAllocationCallbacks, Item, newBlockCapacity),
+ newBlockCapacity,
+ 0 };
m_ItemBlocks.push_back(newBlock);
// Setup singly-linked list of all free items in this block.
- for(uint32_t i = 0; i < m_ItemsPerBlock - 1; ++i)
+ for(uint32_t i = 0; i < newBlockCapacity - 1; ++i)
newBlock.pItems[i].NextFreeIndex = i + 1;
- newBlock.pItems[m_ItemsPerBlock - 1].NextFreeIndex = UINT32_MAX;
+ newBlock.pItems[newBlockCapacity - 1].NextFreeIndex = UINT32_MAX;
return m_ItemBlocks.back();
}