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();

 }