New JSON dump format

Unified across VMA and D3D12MA.
Updated Python script for visualization - now called GpuMemDumpVis.py.

Also a fix for bug in EXTENSIVE defragmentation algorithm - see #232

Code by @medranSolus
This commit is contained in:
Adam Sawicki 2022-03-24 11:50:34 +01:00
parent 6fbb28e3a8
commit 3c6470cf45
22 changed files with 1205 additions and 712 deletions

View file

@ -5765,41 +5765,29 @@ static void VmaPrintDetailedStatistics(VmaJsonWriter& json, const VmaDetailedSta
json.WriteString("BlockCount");
json.WriteNumber(stat.statistics.blockCount);
json.WriteString("BlockBytes");
json.WriteNumber(stat.statistics.blockBytes);
json.WriteString("AllocationCount");
json.WriteNumber(stat.statistics.allocationCount);
json.WriteString("AllocationBytes");
json.WriteNumber(stat.statistics.allocationBytes);
json.WriteString("UnusedRangeCount");
json.WriteNumber(stat.unusedRangeCount);
json.WriteString("BlockBytes");
json.WriteNumber(stat.statistics.blockBytes);
json.WriteString("AllocationBytes");
json.WriteNumber(stat.statistics.allocationBytes);
if (stat.statistics.allocationCount > 1)
{
json.WriteString("AllocationSize");
json.BeginObject(true);
json.WriteString("Min");
json.WriteString("AllocationSizeMin");
json.WriteNumber(stat.allocationSizeMin);
json.WriteString("Max");
json.WriteString("AllocationSizeMax");
json.WriteNumber(stat.allocationSizeMax);
json.EndObject();
}
if (stat.unusedRangeCount > 1)
{
json.WriteString("UnusedRangeSize");
json.BeginObject(true);
json.WriteString("Min");
json.WriteString("UnusedRangeSizeMin");
json.WriteNumber(stat.unusedRangeSizeMin);
json.WriteString("Max");
json.WriteString("UnusedRangeSizeMax");
json.WriteNumber(stat.unusedRangeSizeMax);
json.EndObject();
}
json.EndObject();
}
#endif // _VMA_JSON_WRITER
@ -6348,8 +6336,7 @@ public:
virtual void AddStatistics(VmaStatistics& inoutStats) const = 0;
#if VMA_STATS_STRING_ENABLED
// mapRefCount == UINT32_MAX means unspecified.
virtual void PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const = 0;
virtual void PrintDetailedMap(class VmaJsonWriter& json) const = 0;
#endif
// Tries to find a place for suballocation with given parameters inside this block.
@ -6393,8 +6380,7 @@ protected:
void PrintDetailedMap_Begin(class VmaJsonWriter& json,
VkDeviceSize unusedBytes,
size_t allocationCount,
size_t unusedRangeCount,
uint32_t mapRefCount) const;
size_t unusedRangeCount) const;
void PrintDetailedMap_Allocation(class VmaJsonWriter& json,
VkDeviceSize offset, VkDeviceSize size, void* userData) const;
void PrintDetailedMap_UnusedRange(class VmaJsonWriter& json,
@ -6448,10 +6434,8 @@ void VmaBlockMetadata::DebugLogAllocation(VkDeviceSize offset, VkDeviceSize size
#if VMA_STATS_STRING_ENABLED
void VmaBlockMetadata::PrintDetailedMap_Begin(class VmaJsonWriter& json,
VkDeviceSize unusedBytes, size_t allocationCount, size_t unusedRangeCount, uint32_t mapRefCount) const
VkDeviceSize unusedBytes, size_t allocationCount, size_t unusedRangeCount) const
{
json.BeginObject();
json.WriteString("TotalBytes");
json.WriteNumber(GetSize());
@ -6459,16 +6443,10 @@ void VmaBlockMetadata::PrintDetailedMap_Begin(class VmaJsonWriter& json,
json.WriteNumber(unusedBytes);
json.WriteString("Allocations");
json.WriteNumber((uint64_t)allocationCount);
json.WriteNumber(allocationCount);
json.WriteString("UnusedRanges");
json.WriteNumber((uint64_t)unusedRangeCount);
if(mapRefCount != UINT32_MAX)
{
json.WriteString("MapRefCount");
json.WriteNumber(mapRefCount);
}
json.WriteNumber(unusedRangeCount);
json.WriteString("Suballocations");
json.BeginArray();
@ -6484,15 +6462,11 @@ void VmaBlockMetadata::PrintDetailedMap_Allocation(class VmaJsonWriter& json,
if (IsVirtual())
{
json.WriteString("Type");
json.WriteString("VirtualAllocation");
json.WriteString("Size");
json.WriteNumber(size);
if (userData != VMA_NULL)
if (userData)
{
json.WriteString("UserData");
json.WriteString("CustomData");
json.BeginString();
json.ContinueString_Pointer(userData);
json.EndString();
@ -6526,7 +6500,6 @@ void VmaBlockMetadata::PrintDetailedMap_UnusedRange(class VmaJsonWriter& json,
void VmaBlockMetadata::PrintDetailedMap_End(class VmaJsonWriter& json) const
{
json.EndArray();
json.EndObject();
}
#endif // VMA_STATS_STRING_ENABLED
#endif // _VMA_BLOCK_METADATA_FUNCTIONS
@ -7631,7 +7604,7 @@ public:
void AddStatistics(VmaStatistics& inoutStats) const override;
#if VMA_STATS_STRING_ENABLED
void PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const override;
void PrintDetailedMap(class VmaJsonWriter& json) const override;
#endif
bool CreateAllocationRequest(
@ -8218,7 +8191,7 @@ void VmaBlockMetadata_Linear::AddStatistics(VmaStatistics& inoutStats) const
}
#if VMA_STATS_STRING_ENABLED
void VmaBlockMetadata_Linear::PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const
void VmaBlockMetadata_Linear::PrintDetailedMap(class VmaJsonWriter& json) const
{
const VkDeviceSize size = GetSize();
const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
@ -8380,7 +8353,7 @@ void VmaBlockMetadata_Linear::PrintDetailedMap(class VmaJsonWriter& json, uint32
}
const VkDeviceSize unusedBytes = size - usedBytes;
PrintDetailedMap_Begin(json, unusedBytes, alloc1stCount + alloc2ndCount, unusedRangeCount, mapRefCount);
PrintDetailedMap_Begin(json, unusedBytes, alloc1stCount + alloc2ndCount, unusedRangeCount);
// SECOND PASS
lastOffset = 0;
@ -9988,7 +9961,7 @@ public:
void AddStatistics(VmaStatistics& inoutStats) const override;
#if VMA_STATS_STRING_ENABLED
void PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const override;
void PrintDetailedMap(class VmaJsonWriter& json) const override;
#endif
bool CreateAllocationRequest(
@ -10261,7 +10234,7 @@ void VmaBlockMetadata_TLSF::AddStatistics(VmaStatistics& inoutStats) const
}
#if VMA_STATS_STRING_ENABLED
void VmaBlockMetadata_TLSF::PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const
void VmaBlockMetadata_TLSF::PrintDetailedMap(class VmaJsonWriter& json) const
{
size_t blockCount = m_AllocCount + m_BlocksFreeCount;
VmaStlAllocator<Block*> allocator(GetAllocationCallbacks());
@ -10278,12 +10251,10 @@ void VmaBlockMetadata_TLSF::PrintDetailedMap(class VmaJsonWriter& json, uint32_t
VmaClearDetailedStatistics(stats);
AddDetailedStatistics(stats);
PrintDetailedMap_Begin(
json,
PrintDetailedMap_Begin(json,
stats.statistics.blockBytes - stats.statistics.allocationBytes,
stats.statistics.allocationCount,
stats.unusedRangeCount,
mapRefCount);
stats.unusedRangeCount);
for (; i < blockCount; ++i)
{
@ -11380,8 +11351,9 @@ void VmaVirtualBlock_T::BuildStatsString(bool detailedMap, VmaStringBuilder& sb)
if (detailedMap)
{
json.WriteString("Details");
m_Metadata->PrintDetailedMap(json,
UINT32_MAX); // mapRefCount
json.BeginObject();
m_Metadata->PrintDetailedMap(json);
json.EndObject();
}
json.EndObject();
@ -12280,10 +12252,12 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
json.WriteString("Size");
json.WriteNumber(m_Size);
json.WriteString("Usage");
json.WriteNumber(m_BufferImageUsage);
if (m_pUserData != VMA_NULL)
{
json.WriteString("UserData");
json.WriteString("CustomData");
json.BeginString();
json.ContinueString_Pointer(m_pUserData);
json.EndString();
@ -12293,12 +12267,6 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
json.WriteString("Name");
json.WriteString(m_pName);
}
if (m_BufferImageUsage != 0)
{
json.WriteString("Usage");
json.WriteNumber(m_BufferImageUsage);
}
}
#endif // VMA_STATS_STRING_ENABLED
@ -12951,50 +12919,7 @@ void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json)
{
VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex);
if (IsCustomPool())
{
const char* poolName = m_hParentPool->GetName();
if (poolName != VMA_NULL && poolName[0] != '\0')
{
json.WriteString("Name");
json.WriteString(poolName);
}
json.WriteString("MemoryTypeIndex");
json.WriteNumber(m_MemoryTypeIndex);
json.WriteString("BlockSize");
json.WriteNumber(m_PreferredBlockSize);
json.WriteString("BlockCount");
json.BeginObject(true);
if (m_MinBlockCount > 0)
{
json.WriteString("Min");
json.WriteNumber((uint64_t)m_MinBlockCount);
}
if (m_MaxBlockCount < SIZE_MAX)
{
json.WriteString("Max");
json.WriteNumber((uint64_t)m_MaxBlockCount);
}
json.WriteString("Cur");
json.WriteNumber((uint64_t)m_Blocks.size());
json.EndObject();
if (m_Algorithm != 0)
{
json.WriteString("Algorithm");
json.WriteString(VmaAlgorithmToStr(m_Algorithm));
}
}
else
{
json.WriteString("PreferredBlockSize");
json.WriteNumber(m_PreferredBlockSize);
}
json.WriteString("Blocks");
json.BeginObject();
for (size_t i = 0; i < m_Blocks.size(); ++i)
{
@ -13002,7 +12927,12 @@ void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json)
json.ContinueString(m_Blocks[i]->GetId());
json.EndString();
m_Blocks[i]->m_pMetadata->PrintDetailedMap(json, m_Blocks[i]->GetMapRefCount());
json.BeginObject();
json.WriteString("MapRefCount");
json.WriteNumber(m_Blocks[i]->GetMapRefCount());
m_Blocks[i]->m_pMetadata->PrintDetailedMap(json);
json.EndObject();
}
json.EndObject();
}
@ -13303,9 +13233,15 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo
StateExtensive& state = reinterpret_cast<StateExtensive*>(m_AlgorithmState)[vectorIndex];
if (state.firstFreeBlock != SIZE_MAX)
{
state.firstFreeBlock -= prevCount - currentCount;
if (state.firstFreeBlock != 0)
state.firstFreeBlock -= vector->GetBlock(state.firstFreeBlock - 1)->m_pMetadata->IsEmpty();
const size_t diff = prevCount - currentCount;
if (state.firstFreeBlock >= diff)
{
state.firstFreeBlock -= diff;
if (state.firstFreeBlock != 0)
state.firstFreeBlock -= vector->GetBlock(state.firstFreeBlock - 1)->m_pMetadata->IsEmpty();
}
else
state.firstFreeBlock = 0;
}
}
}
@ -13350,7 +13286,10 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo
{
if (i < state.firstFreeBlock - 1)
{
VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[--state.firstFreeBlock]);
if (state.firstFreeBlock > 1)
VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[--state.firstFreeBlock]);
else
--state.firstFreeBlock;
}
}
swapped = true;
@ -15968,89 +15907,90 @@ uint32_t VmaAllocator_T::GetGpuDefragmentationMemoryTypeBits()
#if VMA_STATS_STRING_ENABLED
void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json)
{
bool dedicatedAllocationsStarted = false;
for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
json.WriteString("DefaultPools");
json.BeginObject();
{
VmaDedicatedAllocationList& dedicatedAllocList = m_DedicatedAllocations[memTypeIndex];
if(!dedicatedAllocList.IsEmpty())
{
if(dedicatedAllocationsStarted == false)
{
dedicatedAllocationsStarted = true;
json.WriteString("DedicatedAllocations");
json.BeginObject();
}
json.BeginString("Type ");
json.ContinueString(memTypeIndex);
json.EndString();
dedicatedAllocList.BuildStatsString(json);
}
}
if(dedicatedAllocationsStarted)
{
json.EndObject();
}
{
bool allocationsStarted = false;
for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
for (uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
{
VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex];
if(pBlockVector != VMA_NULL)
VmaDedicatedAllocationList& dedicatedAllocList = m_DedicatedAllocations[memTypeIndex];
if (pBlockVector != VMA_NULL)
{
if (pBlockVector->IsEmpty() == false)
{
if (allocationsStarted == false)
{
allocationsStarted = true;
json.WriteString("DefaultPools");
json.BeginObject();
}
json.BeginString("Type ");
json.ContinueString(memTypeIndex);
json.EndString();
json.BeginObject();
pBlockVector->PrintDetailedMap(json);
json.EndObject();
}
}
}
if(allocationsStarted)
{
json.EndObject();
}
}
// Custom pools
{
VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex);
if(!m_Pools.IsEmpty())
{
json.WriteString("Pools");
json.BeginObject();
for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool))
{
json.BeginString();
json.ContinueString(pool->GetId());
json.BeginString("Type ");
json.ContinueString(memTypeIndex);
json.EndString();
json.BeginObject();
pool->m_BlockVector.PrintDetailedMap(json);
if (!pool->m_DedicatedAllocations.IsEmpty())
{
json.WriteString("PreferredBlockSize");
json.WriteNumber(pBlockVector->GetPreferredBlockSize());
json.WriteString("Blocks");
pBlockVector->PrintDetailedMap(json);
json.WriteString("DedicatedAllocations");
pool->m_DedicatedAllocations.BuildStatsString(json);
dedicatedAllocList.BuildStatsString(json);
}
json.EndObject();
}
json.EndObject();
}
}
json.EndObject();
json.WriteString("CustomPools");
json.BeginObject();
{
VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex);
if (!m_Pools.IsEmpty())
{
for (uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
{
bool displayType = true;
size_t index = 0;
for (VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool))
{
VmaBlockVector& blockVector = pool->m_BlockVector;
if (blockVector.GetMemoryTypeIndex() == memTypeIndex)
{
if (displayType)
{
json.BeginString("Type ");
json.ContinueString(memTypeIndex);
json.EndString();
json.BeginArray();
displayType = false;
}
json.BeginObject();
{
json.WriteString("Name");
json.BeginString();
json.ContinueString(index++);
if (pool->GetName())
{
json.WriteString(" - ");
json.WriteString(pool->GetName());
}
json.EndString();
json.WriteString("PreferredBlockSize");
json.WriteNumber(blockVector.GetPreferredBlockSize());
json.WriteString("Blocks");
blockVector.PrintDetailedMap(json);
json.WriteString("DedicatedAllocations");
pool->m_DedicatedAllocations.BuildStatsString(json);
}
json.EndObject();
}
}
if (!displayType)
json.EndArray();
}
}
}
json.EndObject();
}
#endif // VMA_STATS_STRING_ENABLED
#endif // _VMA_ALLOCATOR_T_FUNCTIONS
@ -16161,127 +16101,176 @@ VMA_CALL_PRE void VMA_CALL_POST vmaBuildStatsString(
VmaStringBuilder sb(allocator->GetAllocationCallbacks());
{
VmaJsonWriter json(allocator->GetAllocationCallbacks(), sb);
json.BeginObject();
VmaBudget budgets[VK_MAX_MEMORY_HEAPS];
allocator->GetHeapBudgets(budgets, 0, allocator->GetMemoryHeapCount());
VmaTotalStatistics stats;
allocator->CalculateStatistics(&stats);
json.WriteString("Total");
VmaPrintDetailedStatistics(json, stats.total);
for(uint32_t heapIndex = 0; heapIndex < allocator->GetMemoryHeapCount(); ++heapIndex)
VmaJsonWriter json(allocator->GetAllocationCallbacks(), sb);
json.BeginObject();
{
json.BeginString("Heap ");
json.ContinueString(heapIndex);
json.EndString();
json.BeginObject();
json.WriteString("Size");
json.WriteNumber(allocator->m_MemProps.memoryHeaps[heapIndex].size);
json.WriteString("Flags");
json.BeginArray(true);
if((allocator->m_MemProps.memoryHeaps[heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0)
{
json.WriteString("DEVICE_LOCAL");
}
json.EndArray();
json.WriteString("Budget");
json.WriteString("General");
json.BeginObject();
{
json.WriteString("BlockBytes");
json.WriteNumber(budgets[heapIndex].statistics.blockBytes);
json.WriteString("AllocationBytes");
json.WriteNumber(budgets[heapIndex].statistics.allocationBytes);
json.WriteString("BlockCount");
json.WriteNumber(budgets[heapIndex].statistics.blockCount);
json.WriteString("AllocationCount");
json.WriteNumber(budgets[heapIndex].statistics.allocationCount);
json.WriteString("Usage");
json.WriteNumber(budgets[heapIndex].usage);
json.WriteString("Budget");
json.WriteNumber(budgets[heapIndex].budget);
const VkPhysicalDeviceProperties& deviceProperties = allocator->m_PhysicalDeviceProperties;
const VkPhysicalDeviceMemoryProperties& memoryProperties = allocator->m_MemProps;
json.WriteString("API");
json.WriteString("Vulkan");
json.WriteString("apiVersion");
json.BeginString();
json.ContinueString(VK_API_VERSION_MAJOR(deviceProperties.apiVersion));
json.ContinueString(".");
json.ContinueString(VK_API_VERSION_MINOR(deviceProperties.apiVersion));
json.ContinueString(".");
json.ContinueString(VK_API_VERSION_PATCH(deviceProperties.apiVersion));
json.EndString();
json.WriteString("GPU");
json.WriteString(deviceProperties.deviceName);
json.WriteString("deviceType");
json.WriteNumber(static_cast<uint32_t>(deviceProperties.deviceType));
json.WriteString("maxMemoryAllocationCount");
json.WriteNumber(deviceProperties.limits.maxMemoryAllocationCount);
json.WriteString("bufferImageGranularity");
json.WriteNumber(deviceProperties.limits.bufferImageGranularity);
json.WriteString("nonCoherentAtomSize");
json.WriteNumber(deviceProperties.limits.nonCoherentAtomSize);
json.WriteString("memoryHeapCount");
json.WriteNumber(memoryProperties.memoryHeapCount);
json.WriteString("memoryTypeCount");
json.WriteNumber(memoryProperties.memoryTypeCount);
}
json.EndObject();
if(stats.memoryHeap[heapIndex].statistics.blockCount > 0)
}
{
json.WriteString("Total");
VmaPrintDetailedStatistics(json, stats.total);
}
{
json.WriteString("MemoryInfo");
json.BeginObject();
{
json.WriteString("Stats");
VmaPrintDetailedStatistics(json, stats.memoryHeap[heapIndex]);
}
for(uint32_t typeIndex = 0; typeIndex < allocator->GetMemoryTypeCount(); ++typeIndex)
{
if(allocator->MemoryTypeIndexToHeapIndex(typeIndex) == heapIndex)
for (uint32_t heapIndex = 0; heapIndex < allocator->GetMemoryHeapCount(); ++heapIndex)
{
json.BeginString("Type ");
json.ContinueString(typeIndex);
json.BeginString("Heap ");
json.ContinueString(heapIndex);
json.EndString();
json.BeginObject();
{
const VkMemoryHeap& heapInfo = allocator->m_MemProps.memoryHeaps[heapIndex];
json.WriteString("Flags");
json.BeginArray(true);
{
if (heapInfo.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
json.WriteString("DEVICE_LOCAL");
#if VMA_VULKAN_VERSION >= 1001000
if (heapInfo.flags & VK_MEMORY_HEAP_MULTI_INSTANCE_BIT)
json.WriteString("MULTI_INSTANCE");
#endif
json.WriteString("Flags");
json.BeginArray(true);
VkMemoryPropertyFlags flags = allocator->m_MemProps.memoryTypes[typeIndex].propertyFlags;
if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
{
json.WriteString("DEVICE_LOCAL");
}
if((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
{
json.WriteString("HOST_VISIBLE");
}
if((flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0)
{
json.WriteString("HOST_COHERENT");
}
if((flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0)
{
json.WriteString("HOST_CACHED");
}
if((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
{
json.WriteString("LAZILY_ALLOCATED");
}
#if VMA_VULKAN_VERSION >= 1001000
if((flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0)
{
json.WriteString("PROTECTED");
}
#endif // #if VMA_VULKAN_VERSION >= 1001000
#if VK_AMD_device_coherent_memory
if((flags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY) != 0)
{
json.WriteString("DEVICE_COHERENT");
}
if((flags & VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY) != 0)
{
json.WriteString("DEVICE_UNCACHED");
}
#endif // #if VK_AMD_device_coherent_memory
json.EndArray();
VkMemoryHeapFlags flags = heapInfo.flags &
~(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
#if VMA_VULKAN_VERSION >= 1001000
| VK_MEMORY_HEAP_MULTI_INSTANCE_BIT
#endif
);
if (flags != 0)
json.WriteNumber(flags);
}
json.EndArray();
json.WriteString("Size");
json.WriteNumber(heapInfo.size);
json.WriteString("Budget");
json.BeginObject();
{
json.WriteString("BudgetBytes");
json.WriteNumber(budgets[heapIndex].budget);
json.WriteString("UsageBytes");
json.WriteNumber(budgets[heapIndex].usage);
}
json.EndObject();
if(stats.memoryType[typeIndex].statistics.blockCount > 0)
{
json.WriteString("Stats");
VmaPrintDetailedStatistics(json, stats.memoryType[typeIndex]);
}
VmaPrintDetailedStatistics(json, stats.memoryHeap[heapIndex]);
json.WriteString("MemoryPools");
json.BeginObject();
{
for (uint32_t typeIndex = 0; typeIndex < allocator->GetMemoryTypeCount(); ++typeIndex)
{
if (allocator->MemoryTypeIndexToHeapIndex(typeIndex) == heapIndex)
{
json.BeginString("Type ");
json.ContinueString(typeIndex);
json.EndString();
json.BeginObject();
{
json.WriteString("Flags");
json.BeginArray(true);
{
VkMemoryPropertyFlags flags = allocator->m_MemProps.memoryTypes[typeIndex].propertyFlags;
if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
json.WriteString("DEVICE_LOCAL");
if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
json.WriteString("HOST_VISIBLE");
if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
json.WriteString("HOST_COHERENT");
if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
json.WriteString("HOST_CACHED");
if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
json.WriteString("LAZILY_ALLOCATED");
#if VMA_VULKAN_VERSION >= 1001000
if (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT)
json.WriteString("PROTECTED");
#endif
#if VK_AMD_device_coherent_memory
if (flags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY)
json.WriteString("DEVICE_COHERENT_AMD");
if (flags & VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY)
json.WriteString("DEVICE_UNCACHED_AMD");
#endif
flags &= ~(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
#if VMA_VULKAN_VERSION >= 1001000
| VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
#endif
#if VK_AMD_device_coherent_memory
| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY
| VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY
#endif
| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
if (flags != 0)
json.WriteNumber(flags);
}
json.EndArray();
json.WriteString("Stats");
VmaPrintDetailedStatistics(json, stats.memoryType[typeIndex]);
}
json.EndObject();
}
}
}
json.EndObject();
}
json.EndObject();
}
}
json.EndObject();
}
if(detailedMap == VK_TRUE)
{
if (detailedMap == VK_TRUE)
allocator->PrintDetailedMap(json);
}
json.EndObject();
}