VmaReplay: Added "device memory statistics" - count and total size of successfully allocated device memory blocks, total and per memory type.
diff --git a/src/VmaReplay/VmaReplay.cpp b/src/VmaReplay/VmaReplay.cpp
index 31a53ed..edc6b95 100644
--- a/src/VmaReplay/VmaReplay.cpp
+++ b/src/VmaReplay/VmaReplay.cpp
@@ -724,7 +724,9 @@
static uint32_t ImageUsageToClass(uint32_t usage);
Statistics();
+ ~Statistics();
void Init(uint32_t memHeapCount, uint32_t memTypeCount);
+ void PrintDeviceMemStats() const;
void PrintMemStats() const;
void PrintDetailedStats() const;
@@ -745,6 +747,7 @@
void RegisterAllocateMemoryPages(size_t allocCount) { m_VmaAllocateMemoryPages.PostValue(allocCount); }
void RegisterDefragmentation(const VmaDefragmentationInfo2& info);
+ void RegisterDeviceMemoryAllocation(uint32_t memoryType, VkDeviceSize size);
void UpdateMemStats(const VmaStats& currStats);
private:
@@ -755,6 +758,17 @@
size_t m_ImageCreationCount[4] = { };
size_t m_LinearImageCreationCount = 0;
size_t m_BufferCreationCount[4] = { };
+
+ struct DeviceMemStatInfo
+ {
+ size_t allocationCount;
+ VkDeviceSize allocationTotalSize;
+ };
+ struct DeviceMemStats
+ {
+ DeviceMemStatInfo memoryType[VK_MAX_MEMORY_TYPES];
+ DeviceMemStatInfo total;
+ } m_DeviceMemStats;
// Structure similar to VmaStatInfo, but not the same.
struct MemStatInfo
@@ -785,6 +799,28 @@
static void PrintMemStatInfo(const MemStatInfo& info);
};
+// Hack for global AllocateDeviceMemoryCallback.
+static Statistics* g_Statistics;
+
+static void VKAPI_CALL AllocateDeviceMemoryCallback(
+ VmaAllocator allocator,
+ uint32_t memoryType,
+ VkDeviceMemory memory,
+ VkDeviceSize size)
+{
+ g_Statistics->RegisterDeviceMemoryAllocation(memoryType, size);
+}
+
+/// Callback function called before vkFreeMemory.
+static void VKAPI_CALL FreeDeviceMemoryCallback(
+ VmaAllocator allocator,
+ uint32_t memoryType,
+ VkDeviceMemory memory,
+ VkDeviceSize size)
+{
+ // Nothing.
+}
+
uint32_t Statistics::BufferUsageToClass(uint32_t usage)
{
// Buffer is used as source of data for fixed-function stage of graphics pipeline.
@@ -850,7 +886,17 @@
Statistics::Statistics()
{
+ ZeroMemory(&m_DeviceMemStats, sizeof(m_DeviceMemStats));
ZeroMemory(&m_PeakMemStats, sizeof(m_PeakMemStats));
+
+ assert(g_Statistics == nullptr);
+ g_Statistics = this;
+}
+
+Statistics::~Statistics()
+{
+ assert(g_Statistics == this);
+ g_Statistics = nullptr;
}
void Statistics::Init(uint32_t memHeapCount, uint32_t memTypeCount)
@@ -859,6 +905,18 @@
m_MemTypeCount = memTypeCount;
}
+void Statistics::PrintDeviceMemStats() const
+{
+ printf("Successful device memory allocations:\n");
+ printf(" Total: count = %zu, total size = %llu\n",
+ m_DeviceMemStats.total.allocationCount, m_DeviceMemStats.total.allocationTotalSize);
+ for(uint32_t i = 0; i < m_MemTypeCount; ++i)
+ {
+ printf(" Memory type %u: count = %zu, total size = %llu\n",
+ i, m_DeviceMemStats.memoryType[i].allocationCount, m_DeviceMemStats.memoryType[i].allocationTotalSize);
+ }
+}
+
void Statistics::PrintMemStats() const
{
printf("Memory statistics:\n");
@@ -953,6 +1011,15 @@
}
}
+void Statistics::RegisterDeviceMemoryAllocation(uint32_t memoryType, VkDeviceSize size)
+{
+ ++m_DeviceMemStats.total.allocationCount;
+ m_DeviceMemStats.total.allocationTotalSize += size;
+
+ ++m_DeviceMemStats.memoryType[memoryType].allocationCount;
+ m_DeviceMemStats.memoryType[memoryType].allocationTotalSize += size;
+}
+
void Statistics::UpdateMemStatInfo(MemStatInfo& inoutPeakInfo, const VmaStatInfo& currInfo)
{
#define SET_PEAK(inoutDst, src) \
@@ -2137,10 +2204,15 @@
// Create memory allocator
+ VmaDeviceMemoryCallbacks deviceMemoryCallbacks = {};
+ deviceMemoryCallbacks.pfnAllocate = AllocateDeviceMemoryCallback;
+ deviceMemoryCallbacks.pfnFree = FreeDeviceMemoryCallback;
+
VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.physicalDevice = m_PhysicalDevice;
allocatorInfo.device = m_Device;
allocatorInfo.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
+ allocatorInfo.pDeviceMemoryCallbacks = &deviceMemoryCallbacks;
if(m_DedicatedAllocationEnabled)
{
@@ -2434,6 +2506,8 @@
return;
}
+ m_Stats.PrintDeviceMemStats();
+
printf("Statistics:\n");
if(m_Stats.GetAllocationCreationCount() > 0)
{