Written test for various defragmentation algorithms, in TestDefragmentationGpu.
diff --git a/src/Tests.cpp b/src/Tests.cpp
index ff6aa3a..509432f 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -1445,34 +1445,61 @@
DestroyAllAllocations(allocations);
}
-static void TestDefragmentationGpu()
+static void TestDefragmentationGpu(uint32_t flags)
{
- wprintf(L"Test defragmentation GPU\n");
+ const wchar_t* flagsName = L"0";
+ switch(flags)
+ {
+ case VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT:
+ flagsName = L"FAST";
+ break;
+ case VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT:
+ flagsName = L"OPTIMAL";
+ break;
+ }
+
+ wprintf(L"Test defragmentation GPU (%s)\n", flagsName);
g_MemoryAliasingWarningEnabled = false;
std::vector<AllocInfo> allocations;
// Create that many allocations to surely fill 3 new blocks of 256 MB.
- const VkDeviceSize bufSize = 10ull * 1024 * 1024;
+ const VkDeviceSize bufSizeMin = 5ull * 1024 * 1024;
+ const VkDeviceSize bufSizeMax = 10ull * 1024 * 1024;
const VkDeviceSize totalSize = 3ull * 256 * 1024 * 1024;
- const size_t bufCount = (size_t)(totalSize / bufSize);
- const size_t percentToLeave = 20;
+ const size_t bufCount = (size_t)(totalSize / bufSizeMin);
+ const size_t percentToLeave = 30;
+ const size_t percentNonMovable = 3;
RandomNumberGenerator rand = { 234522 };
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
- bufCreateInfo.size = bufSize;
- bufCreateInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
- VK_BUFFER_USAGE_TRANSFER_DST_BIT |
- VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
- allocCreateInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT;
- allocCreateInfo.pUserData = "TestDefragmentationGpu";
+ allocCreateInfo.flags = 0;
// Create all intended buffers.
for(size_t i = 0; i < bufCount; ++i)
{
+ bufCreateInfo.size = align_up(rand.Generate() % (bufSizeMax - bufSizeMin) + bufSizeMin, 32ull);
+
+ if(rand.Generate() % 100 < percentNonMovable)
+ {
+ bufCreateInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT |
+ VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ allocCreateInfo.pUserData = (void*)(uintptr_t)2;
+ }
+ else
+ {
+ // Different usage just to see different color in output from VmaDumpVis.
+ bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT |
+ VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ // And in JSON dump.
+ allocCreateInfo.pUserData = (void*)(uintptr_t)1;
+ }
+
AllocInfo alloc;
alloc.CreateBuffer(bufCreateInfo, allocCreateInfo);
alloc.m_StartValue = rand.Generate();
@@ -1493,24 +1520,37 @@
// Fill them with meaningful data.
UploadGpuData(allocations.data(), allocations.size());
- SaveAllocatorStatsToFile(L"GPU_defragmentation_A_before.json");
+ wchar_t fileName[MAX_PATH];
+ swprintf_s(fileName, L"GPU_defragmentation_%s_A_before.json", flagsName);
+ SaveAllocatorStatsToFile(fileName);
// Defragment using GPU only.
{
const size_t allocCount = allocations.size();
- std::vector<VmaAllocation> allocationPtrs(allocCount);
- std::vector<VkBool32> allocationChanged(allocCount);
+ std::vector<VmaAllocation> allocationPtrs;
+ std::vector<VkBool32> allocationChanged;
+ std::vector<size_t> allocationOriginalIndex;
+
for(size_t i = 0; i < allocCount; ++i)
{
- allocationPtrs[i] = allocations[i].m_Allocation;
+ VmaAllocationInfo allocInfo = {};
+ vmaGetAllocationInfo(g_hAllocator, allocations[i].m_Allocation, &allocInfo);
+ if((uintptr_t)allocInfo.pUserData == 1) // Movable
+ {
+ allocationPtrs.push_back(allocations[i].m_Allocation);
+ allocationChanged.push_back(VK_FALSE);
+ allocationOriginalIndex.push_back(i);
+ }
}
- memset(allocationChanged.data(), 0, allocCount * sizeof(VkBool32));
+
+ const size_t movableAllocCount = allocationPtrs.size();
BeginSingleTimeCommands();
VmaDefragmentationInfo2 defragInfo = {};
- defragInfo.allocationCount = (uint32_t)allocCount;
+ defragInfo.flags = flags;
+ defragInfo.allocationCount = (uint32_t)movableAllocCount;
defragInfo.pAllocations = allocationPtrs.data();
defragInfo.pAllocationsChanged = allocationChanged.data();
defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE;
@@ -1526,11 +1566,12 @@
vmaDefragmentationEnd(g_hAllocator, ctx);
- for(size_t i = 0; i < allocCount; ++i)
+ for(size_t i = 0; i < movableAllocCount; ++i)
{
if(allocationChanged[i])
{
- RecreateAllocationResource(allocations[i]);
+ const size_t origAllocIndex = allocationOriginalIndex[i];
+ RecreateAllocationResource(allocations[origAllocIndex]);
}
}
@@ -1541,7 +1582,8 @@
ValidateGpuData(allocations.data(), allocations.size());
- SaveAllocatorStatsToFile(L"GPU_defragmentation_B_after.json");
+ swprintf_s(fileName, L"GPU_defragmentation_%s_B_after.json", flagsName);
+ SaveAllocatorStatsToFile(fileName);
// Destroy all remaining buffers.
for(size_t i = allocations.size(); i--; )
@@ -4897,7 +4939,9 @@
// ########################################
// ########################################
- TestDefragmentationGpu();
+ TestDefragmentationGpu(0);
+ TestDefragmentationGpu(VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT);
+ TestDefragmentationGpu(VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT);
TestDefragmentationSimple();
TestDefragmentationFull();
return;
@@ -4935,7 +4979,9 @@
TestDefragmentationSimple();
TestDefragmentationFull();
- TestDefragmentationGpu();
+ TestDefragmentationGpu(0);
+ TestDefragmentationGpu(VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT);
+ TestDefragmentationGpu(VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT);
// # Detailed tests
FILE* file;