Written test for various defragmentation algorithms, in TestDefragmentationGpu.

This commit is contained in:
Adam Sawicki 2018-11-16 17:04:14 +01:00
parent 5249980132
commit c6ede15fab

View file

@ -1445,34 +1445,61 @@ void TestDefragmentationFull()
DestroyAllAllocations(allocations); 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; g_MemoryAliasingWarningEnabled = false;
std::vector<AllocInfo> allocations; std::vector<AllocInfo> allocations;
// Create that many allocations to surely fill 3 new blocks of 256 MB. // 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 VkDeviceSize totalSize = 3ull * 256 * 1024 * 1024;
const size_t bufCount = (size_t)(totalSize / bufSize); const size_t bufCount = (size_t)(totalSize / bufSizeMin);
const size_t percentToLeave = 20; const size_t percentToLeave = 30;
const size_t percentNonMovable = 3;
RandomNumberGenerator rand = { 234522 }; RandomNumberGenerator rand = { 234522 };
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; 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 = {}; VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT; allocCreateInfo.flags = 0;
allocCreateInfo.pUserData = "TestDefragmentationGpu";
// Create all intended buffers. // Create all intended buffers.
for(size_t i = 0; i < bufCount; ++i) 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; AllocInfo alloc;
alloc.CreateBuffer(bufCreateInfo, allocCreateInfo); alloc.CreateBuffer(bufCreateInfo, allocCreateInfo);
alloc.m_StartValue = rand.Generate(); alloc.m_StartValue = rand.Generate();
@ -1493,24 +1520,37 @@ static void TestDefragmentationGpu()
// Fill them with meaningful data. // Fill them with meaningful data.
UploadGpuData(allocations.data(), allocations.size()); 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. // Defragment using GPU only.
{ {
const size_t allocCount = allocations.size(); const size_t allocCount = allocations.size();
std::vector<VmaAllocation> allocationPtrs(allocCount); std::vector<VmaAllocation> allocationPtrs;
std::vector<VkBool32> allocationChanged(allocCount); std::vector<VkBool32> allocationChanged;
std::vector<size_t> allocationOriginalIndex;
for(size_t i = 0; i < allocCount; ++i) 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(); BeginSingleTimeCommands();
VmaDefragmentationInfo2 defragInfo = {}; VmaDefragmentationInfo2 defragInfo = {};
defragInfo.allocationCount = (uint32_t)allocCount; defragInfo.flags = flags;
defragInfo.allocationCount = (uint32_t)movableAllocCount;
defragInfo.pAllocations = allocationPtrs.data(); defragInfo.pAllocations = allocationPtrs.data();
defragInfo.pAllocationsChanged = allocationChanged.data(); defragInfo.pAllocationsChanged = allocationChanged.data();
defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE; defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE;
@ -1526,11 +1566,12 @@ static void TestDefragmentationGpu()
vmaDefragmentationEnd(g_hAllocator, ctx); vmaDefragmentationEnd(g_hAllocator, ctx);
for(size_t i = 0; i < allocCount; ++i) for(size_t i = 0; i < movableAllocCount; ++i)
{ {
if(allocationChanged[i]) if(allocationChanged[i])
{ {
RecreateAllocationResource(allocations[i]); const size_t origAllocIndex = allocationOriginalIndex[i];
RecreateAllocationResource(allocations[origAllocIndex]);
} }
} }
@ -1541,7 +1582,8 @@ static void TestDefragmentationGpu()
ValidateGpuData(allocations.data(), allocations.size()); 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. // Destroy all remaining buffers.
for(size_t i = allocations.size(); i--; ) for(size_t i = allocations.size(); i--; )
@ -4897,7 +4939,9 @@ void Test()
// ######################################## // ########################################
// ######################################## // ########################################
TestDefragmentationGpu(); TestDefragmentationGpu(0);
TestDefragmentationGpu(VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT);
TestDefragmentationGpu(VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT);
TestDefragmentationSimple(); TestDefragmentationSimple();
TestDefragmentationFull(); TestDefragmentationFull();
return; return;
@ -4935,7 +4979,9 @@ void Test()
TestDefragmentationSimple(); TestDefragmentationSimple();
TestDefragmentationFull(); TestDefragmentationFull();
TestDefragmentationGpu(); TestDefragmentationGpu(0);
TestDefragmentationGpu(VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT);
TestDefragmentationGpu(VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT);
// # Detailed tests // # Detailed tests
FILE* file; FILE* file;