mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
synced 2024-09-20 22:52:16 +00:00
Added TestDefragmentationGpu. Not passing - apparently there is some bug...
This commit is contained in:
parent
76c5bcabfd
commit
ff0f7b8254
@ -57,6 +57,11 @@ inline T ceil_div(T x, T y)
|
|||||||
{
|
{
|
||||||
return (x+y-1) / y;
|
return (x+y-1) / y;
|
||||||
}
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline T round_div(T x, T y)
|
||||||
|
{
|
||||||
|
return (x+y/(T)2) / y;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline T align_up(T val, T align)
|
static inline T align_up(T val, T align)
|
||||||
|
156
src/Tests.cpp
156
src/Tests.cpp
@ -649,17 +649,47 @@ static void SaveAllocatorStatsToFile(const wchar_t* filePath)
|
|||||||
|
|
||||||
struct AllocInfo
|
struct AllocInfo
|
||||||
{
|
{
|
||||||
VmaAllocation m_Allocation;
|
VmaAllocation m_Allocation = VK_NULL_HANDLE;
|
||||||
VkBuffer m_Buffer;
|
VkBuffer m_Buffer = VK_NULL_HANDLE;
|
||||||
VkImage m_Image;
|
VkImage m_Image = VK_NULL_HANDLE;
|
||||||
uint32_t m_StartValue;
|
uint32_t m_StartValue = 0;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
VkBufferCreateInfo m_BufferInfo;
|
VkBufferCreateInfo m_BufferInfo;
|
||||||
VkImageCreateInfo m_ImageInfo;
|
VkImageCreateInfo m_ImageInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void CreateBuffer(
|
||||||
|
const VkBufferCreateInfo& bufCreateInfo,
|
||||||
|
const VmaAllocationCreateInfo& allocCreateInfo);
|
||||||
|
void Destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void AllocInfo::CreateBuffer(
|
||||||
|
const VkBufferCreateInfo& bufCreateInfo,
|
||||||
|
const VmaAllocationCreateInfo& allocCreateInfo)
|
||||||
|
{
|
||||||
|
m_BufferInfo = bufCreateInfo;
|
||||||
|
VkResult res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &m_Buffer, &m_Allocation, nullptr);
|
||||||
|
TEST(res == VK_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AllocInfo::Destroy()
|
||||||
|
{
|
||||||
|
if(m_Image)
|
||||||
|
{
|
||||||
|
vkDestroyImage(g_hDevice, m_Image, nullptr);
|
||||||
|
}
|
||||||
|
if(m_Buffer)
|
||||||
|
{
|
||||||
|
vkDestroyBuffer(g_hDevice, m_Buffer, nullptr);
|
||||||
|
}
|
||||||
|
if(m_Allocation)
|
||||||
|
{
|
||||||
|
vmaFreeMemory(g_hAllocator, m_Allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class StagingBufferCollection
|
class StagingBufferCollection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -997,7 +1027,7 @@ static void CreateBuffer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CreateAllocation(AllocInfo& outAllocation, VmaAllocator allocator)
|
static void CreateAllocation(AllocInfo& outAllocation)
|
||||||
{
|
{
|
||||||
outAllocation.m_Allocation = nullptr;
|
outAllocation.m_Allocation = nullptr;
|
||||||
outAllocation.m_Buffer = nullptr;
|
outAllocation.m_Buffer = nullptr;
|
||||||
@ -1021,7 +1051,7 @@ static void CreateAllocation(AllocInfo& outAllocation, VmaAllocator allocator)
|
|||||||
bufferInfo.size = bufferSize;
|
bufferInfo.size = bufferSize;
|
||||||
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
|
||||||
VkResult res = vmaCreateBuffer(allocator, &bufferInfo, &vmaMemReq, &outAllocation.m_Buffer, &outAllocation.m_Allocation, &allocInfo);
|
VkResult res = vmaCreateBuffer(g_hAllocator, &bufferInfo, &vmaMemReq, &outAllocation.m_Buffer, &outAllocation.m_Allocation, &allocInfo);
|
||||||
outAllocation.m_BufferInfo = bufferInfo;
|
outAllocation.m_BufferInfo = bufferInfo;
|
||||||
TEST(res == VK_SUCCESS);
|
TEST(res == VK_SUCCESS);
|
||||||
}
|
}
|
||||||
@ -1047,7 +1077,7 @@ static void CreateAllocation(AllocInfo& outAllocation, VmaAllocator allocator)
|
|||||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
||||||
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
|
||||||
VkResult res = vmaCreateImage(allocator, &imageInfo, &vmaMemReq, &outAllocation.m_Image, &outAllocation.m_Allocation, &allocInfo);
|
VkResult res = vmaCreateImage(g_hAllocator, &imageInfo, &vmaMemReq, &outAllocation.m_Image, &outAllocation.m_Allocation, &allocInfo);
|
||||||
outAllocation.m_ImageInfo = imageInfo;
|
outAllocation.m_ImageInfo = imageInfo;
|
||||||
TEST(res == VK_SUCCESS);
|
TEST(res == VK_SUCCESS);
|
||||||
}
|
}
|
||||||
@ -1055,7 +1085,7 @@ static void CreateAllocation(AllocInfo& outAllocation, VmaAllocator allocator)
|
|||||||
uint32_t* data = (uint32_t*)allocInfo.pMappedData;
|
uint32_t* data = (uint32_t*)allocInfo.pMappedData;
|
||||||
if(allocInfo.pMappedData == nullptr)
|
if(allocInfo.pMappedData == nullptr)
|
||||||
{
|
{
|
||||||
VkResult res = vmaMapMemory(allocator, outAllocation.m_Allocation, (void**)&data);
|
VkResult res = vmaMapMemory(g_hAllocator, outAllocation.m_Allocation, (void**)&data);
|
||||||
TEST(res == VK_SUCCESS);
|
TEST(res == VK_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1065,7 +1095,7 @@ static void CreateAllocation(AllocInfo& outAllocation, VmaAllocator allocator)
|
|||||||
data[i] = value++;
|
data[i] = value++;
|
||||||
|
|
||||||
if(allocInfo.pMappedData == nullptr)
|
if(allocInfo.pMappedData == nullptr)
|
||||||
vmaUnmapMemory(allocator, outAllocation.m_Allocation);
|
vmaUnmapMemory(g_hAllocator, outAllocation.m_Allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DestroyAllocation(const AllocInfo& allocation)
|
static void DestroyAllocation(const AllocInfo& allocation)
|
||||||
@ -1339,7 +1369,7 @@ void TestDefragmentationFull()
|
|||||||
for(size_t i = 0; i < 400; ++i)
|
for(size_t i = 0; i < 400; ++i)
|
||||||
{
|
{
|
||||||
AllocInfo allocation;
|
AllocInfo allocation;
|
||||||
CreateAllocation(allocation, g_hAllocator);
|
CreateAllocation(allocation);
|
||||||
allocations.push_back(allocation);
|
allocations.push_back(allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1415,6 +1445,106 @@ void TestDefragmentationFull()
|
|||||||
DestroyAllAllocations(allocations);
|
DestroyAllAllocations(allocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void TestDefragmentationGpu()
|
||||||
|
{
|
||||||
|
wprintf(L"Test defragmentation GPU\n");
|
||||||
|
|
||||||
|
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 totalSize = 3ull * 256 * 1024 * 1024;
|
||||||
|
const size_t bufCount = (size_t)(totalSize / bufSize);
|
||||||
|
const size_t percentToLeave = 20;
|
||||||
|
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;
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo allocCreateInfo = {};
|
||||||
|
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
||||||
|
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT;
|
||||||
|
allocCreateInfo.pUserData = "TestDefragmentationGpu";
|
||||||
|
|
||||||
|
// Create all intended buffers.
|
||||||
|
for(size_t i = 0; i < bufCount; ++i)
|
||||||
|
{
|
||||||
|
AllocInfo alloc;
|
||||||
|
alloc.CreateBuffer(bufCreateInfo, allocCreateInfo);
|
||||||
|
alloc.m_StartValue = rand.Generate();
|
||||||
|
allocations.push_back(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy some percentage of them.
|
||||||
|
{
|
||||||
|
const size_t buffersToDestroy = round_div<size_t>(bufCount * (100 - percentToLeave), 100);
|
||||||
|
for(size_t i = 0; i < buffersToDestroy; ++i)
|
||||||
|
{
|
||||||
|
const size_t index = rand.Generate() % allocations.size();
|
||||||
|
allocations[index].Destroy();
|
||||||
|
allocations.erase(allocations.begin() + index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill them with meaningful data.
|
||||||
|
UploadGpuData(allocations.data(), allocations.size());
|
||||||
|
|
||||||
|
SaveAllocatorStatsToFile(L"GPU_defragmentation_A_before.json");
|
||||||
|
|
||||||
|
// Defragment using GPU only.
|
||||||
|
{
|
||||||
|
const size_t allocCount = allocations.size();
|
||||||
|
std::vector<VmaAllocation> allocationPtrs(allocCount);
|
||||||
|
std::vector<VkBool32> allocationChanged(allocCount);
|
||||||
|
for(size_t i = 0; i < allocCount; ++i)
|
||||||
|
{
|
||||||
|
allocationPtrs[i] = allocations[i].m_Allocation;
|
||||||
|
allocationChanged[i] = VK_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeginSingleTimeCommands();
|
||||||
|
|
||||||
|
VmaDefragmentationInfo2 defragInfo = {};
|
||||||
|
defragInfo.allocationCount = (uint32_t)allocCount;
|
||||||
|
defragInfo.pAllocations = allocationPtrs.data();
|
||||||
|
defragInfo.maxGpuBytesToMove = 0;//VK_WHOLE_SIZE;
|
||||||
|
defragInfo.maxGpuAllocationsToMove = UINT32_MAX;
|
||||||
|
defragInfo.commandBuffer = g_hTemporaryCommandBuffer;
|
||||||
|
|
||||||
|
VmaDefragmentationStats stats = {};
|
||||||
|
VmaDefragmentationContext ctx = VK_NULL_HANDLE;
|
||||||
|
VkResult res = vmaDefragmentationBegin(g_hAllocator, &defragInfo, &stats, &ctx);
|
||||||
|
TEST(res >= VK_SUCCESS);
|
||||||
|
|
||||||
|
EndSingleTimeCommands();
|
||||||
|
|
||||||
|
vmaDefragmentationEnd(g_hAllocator, ctx);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < allocCount; ++i)
|
||||||
|
{
|
||||||
|
if(allocationChanged[i])
|
||||||
|
{
|
||||||
|
RecreateAllocationResource(allocations[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TEST(stats.allocationsMoved > 0 && stats.bytesMoved > 0);
|
||||||
|
//TEST(stats.deviceMemoryBlocksFreed > 0 && stats.bytesFreed > 0);
|
||||||
|
//TEST(stats.allocationsLost == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidateGpuData(allocations.data(), allocations.size());
|
||||||
|
|
||||||
|
SaveAllocatorStatsToFile(L"GPU_defragmentation_B_after.json");
|
||||||
|
|
||||||
|
// Destroy all remaining buffers.
|
||||||
|
for(size_t i = allocations.size(); i--; )
|
||||||
|
{
|
||||||
|
allocations[i].Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void TestUserData()
|
static void TestUserData()
|
||||||
{
|
{
|
||||||
VkResult res;
|
VkResult res;
|
||||||
@ -4555,8 +4685,9 @@ void Test()
|
|||||||
// ########################################
|
// ########################################
|
||||||
// ########################################
|
// ########################################
|
||||||
|
|
||||||
//TestDefragmentationSimple();
|
TestDefragmentationGpu();
|
||||||
//TestDefragmentationFull();
|
TestDefragmentationSimple();
|
||||||
|
TestDefragmentationFull();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4591,6 +4722,7 @@ void Test()
|
|||||||
|
|
||||||
TestDefragmentationSimple();
|
TestDefragmentationSimple();
|
||||||
TestDefragmentationFull();
|
TestDefragmentationFull();
|
||||||
|
TestDefragmentationGpu();
|
||||||
|
|
||||||
// # Detailed tests
|
// # Detailed tests
|
||||||
FILE* file;
|
FILE* file;
|
||||||
|
Loading…
Reference in New Issue
Block a user