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