Added ManuallyTestLinearAllocator which allows me to manually inspect VmaStats, VmaPoolStats and stats string of custom pool. Fixed bug in VmaBlockMetadata_Linear::PrintDetailedMap.
diff --git a/src/Tests.cpp b/src/Tests.cpp
index 552f3cc..a2415a2 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -1704,6 +1704,120 @@
     vmaDestroyPool(g_hAllocator, pool);

 }

 

+static void ManuallyTestLinearAllocator()

+{

+    VmaStats origStats;

+    vmaCalculateStats(g_hAllocator, &origStats);

+

+    wprintf(L"Manually test linear allocator\n");

+

+    RandomNumberGenerator rand{645332};

+

+    VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };

+    sampleBufCreateInfo.size = 1024; // Whatever.

+    sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;

+

+    VmaAllocationCreateInfo sampleAllocCreateInfo = {};

+    sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;

+

+    VmaPoolCreateInfo poolCreateInfo = {};

+    VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &poolCreateInfo.memoryTypeIndex);

+    assert(res == VK_SUCCESS);

+

+    poolCreateInfo.blockSize = 10 * 1024;

+    poolCreateInfo.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;

+    poolCreateInfo.minBlockCount = poolCreateInfo.maxBlockCount = 1;

+

+    VmaPool pool = nullptr;

+    res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool);

+    assert(res == VK_SUCCESS);

+

+    VkBufferCreateInfo bufCreateInfo = sampleBufCreateInfo;

+

+    VmaAllocationCreateInfo allocCreateInfo = {};

+    allocCreateInfo.pool = pool;

+

+    std::vector<BufferInfo> bufInfo;

+    VmaAllocationInfo allocInfo;

+    BufferInfo newBufInfo;

+

+    // Test double stack.

+    {

+        /*

+        Lower: Buffer 32 B, Buffer 1024 B, Buffer 32 B

+        Upper: Buffer 16 B, Buffer 1024 B, Buffer 128 B

+

+        Totally:

+        1 block allocated

+        10240 Vulkan bytes

+        6 new allocations

+        2256 bytes in allocations

+        */

+

+        bufCreateInfo.size = 32;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        bufCreateInfo.size = 1024;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        bufCreateInfo.size = 32;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+

+        bufCreateInfo.size = 128;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        bufCreateInfo.size = 1024;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        bufCreateInfo.size = 16;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        VmaStats currStats;

+        vmaCalculateStats(g_hAllocator, &currStats);

+        VmaPoolStats poolStats;

+        vmaGetPoolStats(g_hAllocator, pool, &poolStats);

+

+        char* statsStr = nullptr;

+        vmaBuildStatsString(g_hAllocator, &statsStr, VK_TRUE);

+

+        // PUT BREAKPOINT HERE TO CHECK.

+        // Inspect: currStats versus origStats, poolStats, statsStr.

+        int I = 0;

+

+        vmaFreeStatsString(g_hAllocator, statsStr);

+

+        // Destroy the buffers in reverse order.

+        while(!bufInfo.empty())

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+    }

+

+    vmaDestroyPool(g_hAllocator, pool);

+}

+

 static void TestPool_SameSize()

 {

     const VkDeviceSize BUF_SIZE = 1024 * 1024;

@@ -3429,6 +3543,7 @@
 

     // TEMP tests

 TestLinearAllocator();

+ManuallyTestLinearAllocator();

 return;

 

     // # Simple tests

diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h
index 4b499d0..810b889 100644
--- a/src/vk_mem_alloc.h
+++ b/src/vk_mem_alloc.h
@@ -7914,7 +7914,7 @@
             

                 // 3. Prepare for next iteration.

                 lastOffset = suballoc.offset + suballoc.size;

-                ++nextAlloc2ndIndex;

+                --nextAlloc2ndIndex;

             }

             // We are at the end.

             else