mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
synced 2024-11-05 04:10:06 +00:00
Fixed vmaGetPoolStats for dedicated allocations
Added new tests: TestPoolsAndAllocationParameters.
This commit is contained in:
parent
6fe7212e73
commit
cbad11e039
@ -5709,6 +5709,7 @@ public:
|
||||
void Init(bool useMutex) { m_UseMutex = useMutex; }
|
||||
|
||||
void AddStats(VmaStats* stats, uint32_t memTypeIndex, uint32_t memHeapIndex);
|
||||
void AddPoolStats(VmaPoolStats* stats);
|
||||
#if VMA_STATS_STRING_ENABLED
|
||||
// Writes JSON array with the list of allocations.
|
||||
void BuildStatsString(VmaJsonWriter& json);
|
||||
@ -5750,6 +5751,20 @@ void VmaDedicatedAllocationList::AddStats(VmaStats* stats, uint32_t memTypeIndex
|
||||
}
|
||||
}
|
||||
|
||||
void VmaDedicatedAllocationList::AddPoolStats(VmaPoolStats* stats)
|
||||
{
|
||||
VmaMutexLockRead(m_Mutex, m_UseMutex);
|
||||
|
||||
const size_t allocCount = m_AllocationList.GetCount();
|
||||
stats->allocationCount += allocCount;
|
||||
stats->blockCount += allocCount;
|
||||
|
||||
for(auto* item = m_AllocationList.Front(); item != nullptr; item = DedicatedAllocationLinkedList::GetNext(item))
|
||||
{
|
||||
stats->size += item->GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
#if VMA_STATS_STRING_ENABLED
|
||||
void VmaDedicatedAllocationList::BuildStatsString(VmaJsonWriter& json)
|
||||
{
|
||||
@ -9898,7 +9913,7 @@ public:
|
||||
void* const GetAllocationNextPtr() const { return m_pMemoryAllocateNext; }
|
||||
|
||||
VkResult CreateMinBlocks();
|
||||
void GetPoolStats(VmaPoolStats* pStats);
|
||||
void AddPoolStats(VmaPoolStats* pStats);
|
||||
bool IsEmpty();
|
||||
bool IsCorruptionDetectionEnabled() const;
|
||||
|
||||
@ -11782,18 +11797,12 @@ VkResult VmaBlockVector::CreateMinBlocks()
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void VmaBlockVector::GetPoolStats(VmaPoolStats* pStats)
|
||||
void VmaBlockVector::AddPoolStats(VmaPoolStats* pStats)
|
||||
{
|
||||
VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex);
|
||||
|
||||
const size_t blockCount = m_Blocks.size();
|
||||
|
||||
pStats->size = 0;
|
||||
pStats->unusedSize = 0;
|
||||
pStats->allocationCount = 0;
|
||||
pStats->unusedRangeCount = 0;
|
||||
pStats->unusedRangeSizeMax = 0;
|
||||
pStats->blockCount = blockCount;
|
||||
pStats->blockCount += blockCount;
|
||||
|
||||
for (uint32_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
|
||||
{
|
||||
@ -16397,7 +16406,15 @@ void VmaAllocator_T::DestroyPool(VmaPool pool)
|
||||
|
||||
void VmaAllocator_T::GetPoolStats(VmaPool pool, VmaPoolStats* pPoolStats)
|
||||
{
|
||||
pool->m_BlockVector.GetPoolStats(pPoolStats);
|
||||
pPoolStats->size = 0;
|
||||
pPoolStats->unusedSize = 0;
|
||||
pPoolStats->allocationCount = 0;
|
||||
pPoolStats->unusedRangeCount = 0;
|
||||
pPoolStats->unusedRangeSizeMax = 0;
|
||||
pPoolStats->blockCount = 0;
|
||||
|
||||
pool->m_BlockVector.AddPoolStats(pPoolStats);
|
||||
pool->m_DedicatedAllocations.AddPoolStats(pPoolStats);
|
||||
}
|
||||
|
||||
void VmaAllocator_T::SetCurrentFrameIndex(uint32_t frameIndex)
|
||||
|
131
src/Tests.cpp
131
src/Tests.cpp
@ -3128,6 +3128,134 @@ static void TestPool_MinAllocationAlignment()
|
||||
vmaDestroyPool(g_hAllocator, pool);
|
||||
}
|
||||
|
||||
static void TestPoolsAndAllocationParameters()
|
||||
{
|
||||
wprintf(L"Test pools and allocation parameters\n");
|
||||
|
||||
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
bufCreateInfo.size = 1 * MEGABYTE;
|
||||
bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
|
||||
VmaAllocationCreateInfo allocCreateInfo = {};
|
||||
|
||||
uint32_t memTypeIndex = UINT32_MAX;
|
||||
VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &memTypeIndex);
|
||||
TEST(res == VK_SUCCESS);
|
||||
|
||||
VmaPool pool1 = nullptr, pool2 = nullptr;
|
||||
std::vector<BufferInfo> bufs;
|
||||
|
||||
uint32_t totalNewAllocCount = 0, totalNewBlockCount = 0;
|
||||
VmaStats statsBeg, statsEnd;
|
||||
vmaCalculateStats(g_hAllocator, &statsBeg);
|
||||
|
||||
// poolTypeI:
|
||||
// 0 = default pool
|
||||
// 1 = custom pool, default (flexible) block size and block count
|
||||
// 2 = custom pool, fixed block size and limited block count
|
||||
for(size_t poolTypeI = 0; poolTypeI < 3; ++poolTypeI)
|
||||
{
|
||||
if(poolTypeI == 0)
|
||||
{
|
||||
allocCreateInfo.pool = nullptr;
|
||||
}
|
||||
else if(poolTypeI == 1)
|
||||
{
|
||||
VmaPoolCreateInfo poolCreateInfo = {};
|
||||
poolCreateInfo.memoryTypeIndex = memTypeIndex;
|
||||
res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool1);
|
||||
TEST(res == VK_SUCCESS);
|
||||
allocCreateInfo.pool = pool1;
|
||||
}
|
||||
else if(poolTypeI == 2)
|
||||
{
|
||||
VmaPoolCreateInfo poolCreateInfo = {};
|
||||
poolCreateInfo.memoryTypeIndex = memTypeIndex;
|
||||
poolCreateInfo.maxBlockCount = 1;
|
||||
poolCreateInfo.blockSize = 2 * MEGABYTE + MEGABYTE / 2; // 2.5 MB
|
||||
res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool2);
|
||||
TEST(res == VK_SUCCESS);
|
||||
allocCreateInfo.pool = pool2;
|
||||
}
|
||||
|
||||
uint32_t poolAllocCount = 0, poolBlockCount = 0;
|
||||
BufferInfo bufInfo = {};
|
||||
VmaAllocationInfo allocInfo[4] = {};
|
||||
|
||||
// Default parameters
|
||||
allocCreateInfo.flags = 0;
|
||||
res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &bufInfo.Buffer, &bufInfo.Allocation, &allocInfo[0]);
|
||||
TEST(res == VK_SUCCESS && bufInfo.Allocation && bufInfo.Buffer);
|
||||
bufs.push_back(std::move(bufInfo));
|
||||
++poolAllocCount;
|
||||
|
||||
// DEDICATED. Should not try pool2 as it asserts on invalid call.
|
||||
if(poolTypeI != 2)
|
||||
{
|
||||
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
|
||||
res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &bufInfo.Buffer, &bufInfo.Allocation, &allocInfo[1]);
|
||||
TEST(res == VK_SUCCESS && bufInfo.Allocation && bufInfo.Buffer);
|
||||
TEST(allocInfo[1].offset == 0); // Dedicated
|
||||
TEST(allocInfo[1].deviceMemory != allocInfo[0].deviceMemory); // Dedicated
|
||||
bufs.push_back(std::move(bufInfo));
|
||||
++poolAllocCount;
|
||||
}
|
||||
|
||||
// NEVER_ALLOCATE #1
|
||||
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT;
|
||||
res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &bufInfo.Buffer, &bufInfo.Allocation, &allocInfo[2]);
|
||||
TEST(res == VK_SUCCESS && bufInfo.Allocation && bufInfo.Buffer);
|
||||
TEST(allocInfo[2].deviceMemory == allocInfo[0].deviceMemory); // Same memory block as default one.
|
||||
TEST(allocInfo[2].offset != allocInfo[0].offset);
|
||||
bufs.push_back(std::move(bufInfo));
|
||||
++poolAllocCount;
|
||||
|
||||
// NEVER_ALLOCATE #2. Should fail in pool2 as it has no space.
|
||||
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT;
|
||||
res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &bufInfo.Buffer, &bufInfo.Allocation, &allocInfo[3]);
|
||||
if(poolTypeI == 2)
|
||||
TEST(res < 0);
|
||||
else
|
||||
{
|
||||
TEST(res == VK_SUCCESS && bufInfo.Allocation && bufInfo.Buffer);
|
||||
bufs.push_back(std::move(bufInfo));
|
||||
++poolAllocCount;
|
||||
}
|
||||
|
||||
// Pool stats
|
||||
switch(poolTypeI)
|
||||
{
|
||||
case 0: poolBlockCount = 1; break; // At least 1 added for dedicated allocation.
|
||||
case 1: poolBlockCount = 2; break; // 1 for custom pool block and 1 for dedicated allocation.
|
||||
case 2: poolBlockCount = 1; break; // Only custom pool, no dedicated allocation.
|
||||
}
|
||||
|
||||
if(poolTypeI > 0)
|
||||
{
|
||||
VmaPoolStats poolStats = {};
|
||||
vmaGetPoolStats(g_hAllocator, poolTypeI == 2 ? pool2 : pool1, &poolStats);
|
||||
TEST(poolStats.allocationCount == poolAllocCount);
|
||||
const VkDeviceSize usedSize = poolStats.size - poolStats.unusedSize;
|
||||
TEST(usedSize == poolAllocCount * MEGABYTE);
|
||||
TEST(poolStats.blockCount == poolBlockCount);
|
||||
}
|
||||
|
||||
totalNewAllocCount += poolAllocCount;
|
||||
totalNewBlockCount += poolBlockCount;
|
||||
}
|
||||
|
||||
vmaCalculateStats(g_hAllocator, &statsEnd);
|
||||
TEST(statsEnd.total.allocationCount == statsBeg.total.allocationCount + totalNewAllocCount);
|
||||
TEST(statsEnd.total.blockCount >= statsBeg.total.blockCount + totalNewBlockCount);
|
||||
TEST(statsEnd.total.usedBytes == statsBeg.total.usedBytes + totalNewAllocCount * MEGABYTE);
|
||||
|
||||
for(auto& bufInfo : bufs)
|
||||
vmaDestroyBuffer(g_hAllocator, bufInfo.Buffer, bufInfo.Allocation);
|
||||
|
||||
vmaDestroyPool(g_hAllocator, pool2);
|
||||
vmaDestroyPool(g_hAllocator, pool1);
|
||||
}
|
||||
|
||||
void TestHeapSizeLimit()
|
||||
{
|
||||
const VkDeviceSize HEAP_SIZE_LIMIT = 100ull * 1024 * 1024; // 100 MB
|
||||
@ -6929,8 +7057,6 @@ void Test()
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Temporarily insert custom tests here:
|
||||
TestVirtualBlocks();
|
||||
TestVirtualBlocksAlgorithms();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6947,6 +7073,7 @@ void Test()
|
||||
TestPool_SameSize();
|
||||
TestPool_MinBlockCount();
|
||||
TestPool_MinAllocationAlignment();
|
||||
TestPoolsAndAllocationParameters();
|
||||
TestHeapSizeLimit();
|
||||
#endif
|
||||
#if VMA_DEBUG_INITIALIZE_ALLOCATIONS
|
||||
|
Loading…
Reference in New Issue
Block a user