From 2e900cae5467dd1a82a67019d78201e79b9c8bd6 Mon Sep 17 00:00:00 2001 From: Adam Sawicki Date: Thu, 6 Dec 2018 14:26:50 +0100 Subject: [PATCH] Added functions vmaAllocateMemoryPages, vmaFreeMemoryPages to VmaRecorder and VmaReplay. Bumped recording file format version to 1.5. Support for sparse binding is now finished and ready! --- docs/Recording file format.md | 26 ++++- src/VmaReplay/Common.cpp | 24 +++++ src/VmaReplay/Common.h | 1 + src/VmaReplay/VmaReplay.cpp | 187 +++++++++++++++++++++++++++------- src/vk_mem_alloc.h | 75 ++++++++++++-- 5 files changed, 268 insertions(+), 45 deletions(-) diff --git a/docs/Recording file format.md b/docs/Recording file format.md index 875c638..b56413a 100644 --- a/docs/Recording file format.md +++ b/docs/Recording file format.md @@ -23,7 +23,7 @@ Formats with only minor version incremented are backward compatible. VmaReplay application supports all older versions. Current version is: - 1,4 + 1,5 # Configuration @@ -152,6 +152,10 @@ No parameters. - allocation : pointer +**vmaFreeMemoryPages** (min format version: 1.5) + +- allocations : list of pointers + **vmaCreateLostAllocation** (min format version 1.2) - allocation (output) : pointer @@ -170,6 +174,20 @@ No parameters. - allocation (output) : pointer - allocationCreateInfo.pUserData : string (may contain additional commas) +**vmaAllocateMemoryPages** (min format version 1.5) + +- vkMemoryRequirements.size : uint64 +- vkMemoryRequirements.alignment : uint64 +- vkMemoryRequirements.memoryTypeBits : uint32 +- allocationCreateInfo.flags : uint32 +- allocationCreateInfo.usage : uint32 +- allocationCreateInfo.requiredFlags : uint32 +- allocationCreateInfo.preferredFlags : uint32 +- allocationCreateInfo.memoryTypeBits : uint32 +- allocationCreateInfo.pool : pointer +- allocations (output) : list of pointers +- allocationCreateInfo.pUserData : string (may contain additional commas) + **vmaAllocateMemoryForBuffer, vmaAllocateMemoryForImage** (min format version 1.2) - vkMemoryRequirements.size : uint64 @@ -230,10 +248,14 @@ If `VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT` was used with the allocatio It may contain additional commas. It should not contain end-of-line characters - results are then undefined. +**list of (...)** (min format version: 1.5) + +An ordered sequence of values of some type, separated by single space. + # Example file Vulkan Memory Allocator,Calls recording - 1,4 + 1,5 Config,Begin PhysicalDevice,apiVersion,4198477 PhysicalDevice,driverVersion,8388653 diff --git a/src/VmaReplay/Common.cpp b/src/VmaReplay/Common.cpp index 515c1ce..a7c723f 100644 --- a/src/VmaReplay/Common.cpp +++ b/src/VmaReplay/Common.cpp @@ -1,5 +1,29 @@ #include "Common.h" +bool StrRangeToPtrList(const StrRange& s, std::vector& out) +{ + out.clear(); + StrRange currRange = { s.beg, nullptr }; + while(currRange.beg < s.end) + { + currRange.end = currRange.beg; + while(currRange.end < s.end && *currRange.end != ' ') + { + ++currRange.end; + } + + uint64_t ptr = 0; + if(!StrRangeToPtr(currRange, ptr)) + { + return false; + } + out.push_back(ptr); + + currRange.beg = currRange.end + 1; + } + return true; +} + //////////////////////////////////////////////////////////////////////////////// // LineSplit class diff --git a/src/VmaReplay/Common.h b/src/VmaReplay/Common.h index 28b5bbc..a78524b 100644 --- a/src/VmaReplay/Common.h +++ b/src/VmaReplay/Common.h @@ -111,6 +111,7 @@ inline bool StrRangeToBool(const StrRange& s, bool& out) return true; } +bool StrRangeToPtrList(const StrRange& s, std::vector& out); class LineSplit { diff --git a/src/VmaReplay/VmaReplay.cpp b/src/VmaReplay/VmaReplay.cpp index a9acfa5..79d9bde 100644 --- a/src/VmaReplay/VmaReplay.cpp +++ b/src/VmaReplay/VmaReplay.cpp @@ -71,8 +71,10 @@ enum class VMA_FUNCTION CreateImage, DestroyImage, FreeMemory, + FreeMemoryPages, CreateLostAllocation, AllocateMemory, + AllocateMemoryPages, AllocateMemoryForBuffer, AllocateMemoryForImage, MapMemory, @@ -94,8 +96,10 @@ static const char* VMA_FUNCTION_NAMES[] = { "vmaCreateImage", "vmaDestroyImage", "vmaFreeMemory", + "vmaFreeMemoryPages", "vmaCreateLostAllocation", "vmaAllocateMemory", + "vmaAllocateMemoryPages", "vmaAllocateMemoryForBuffer", "vmaAllocateMemoryForImage", "vmaMapMemory", @@ -145,7 +149,7 @@ static size_t g_DumpStatsAfterLineNextIndex = 0; static bool ValidateFileVersion() { if(GetVersionMajor(g_FileVersion) == 1 && - GetVersionMinor(g_FileVersion) <= 4) + GetVersionMinor(g_FileVersion) <= 5) { return true; } @@ -195,7 +199,7 @@ public: void RegisterCreateImage(uint32_t usage, uint32_t tiling); void RegisterCreateBuffer(uint32_t usage); void RegisterCreatePool(); - void RegisterCreateAllocation(); + void RegisterCreateAllocation(size_t allocCount = 1); void UpdateMemStats(const VmaStats& currStats); @@ -364,9 +368,9 @@ void Statistics::RegisterCreatePool() ++m_PoolCreationCount; } -void Statistics::RegisterCreateAllocation() +void Statistics::RegisterCreateAllocation(size_t allocCount) { - ++m_AllocationCreationCount; + m_AllocationCreationCount += allocCount; } void Statistics::UpdateMemStats(const VmaStats& currStats) @@ -955,10 +959,10 @@ private: }; struct Allocation { - uint32_t allocationFlags; - VmaAllocation allocation; - VkBuffer buffer; - VkImage image; + uint32_t allocationFlags = 0; + VmaAllocation allocation = VK_NULL_HANDLE; + VkBuffer buffer = VK_NULL_HANDLE; + VkImage image = VK_NULL_HANDLE; }; std::unordered_map m_Pools; std::unordered_map m_Allocations; @@ -1003,12 +1007,14 @@ private: void ExecuteDestroyPool(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteSetAllocationUserData(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit); - void ExecuteDestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyBuffer); DestroyAllocation(lineNumber, csvSplit); } + void ExecuteDestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyBuffer); DestroyAllocation(lineNumber, csvSplit, "vmaDestroyBuffer"); } void ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit); - void ExecuteDestroyImage(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyImage); DestroyAllocation(lineNumber, csvSplit); } - void ExecuteFreeMemory(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::FreeMemory); DestroyAllocation(lineNumber, csvSplit); } + void ExecuteDestroyImage(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyImage); DestroyAllocation(lineNumber, csvSplit, "vmaDestroyImage"); } + void ExecuteFreeMemory(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::FreeMemory); DestroyAllocation(lineNumber, csvSplit, "vmaFreeMemory"); } + void ExecuteFreeMemoryPages(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteCreateLostAllocation(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteAllocateMemory(size_t lineNumber, const CsvSplit& csvSplit); + void ExecuteAllocateMemoryPages(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteAllocateMemoryForBufferOrImage(size_t lineNumber, const CsvSplit& csvSplit, OBJECT_TYPE objType); void ExecuteMapMemory(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteUnmapMemory(size_t lineNumber, const CsvSplit& csvSplit); @@ -1019,7 +1025,7 @@ private: void ExecuteMakePoolAllocationsLost(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteResizeAllocation(size_t lineNumber, const CsvSplit& csvSplit); - void DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit); + void DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit, const char* functionName); }; Player::Player() @@ -1121,45 +1127,49 @@ void Player::ExecuteLine(size_t lineNumber, const StrRange& line) // Nothing. } } - else if(StrRangeEq(functionName, "vmaCreatePool")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreatePool])) ExecuteCreatePool(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaDestroyPool")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyPool])) ExecuteDestroyPool(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaSetAllocationUserData")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::SetAllocationUserData])) ExecuteSetAllocationUserData(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaCreateBuffer")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreateBuffer])) ExecuteCreateBuffer(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaDestroyBuffer")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyBuffer])) ExecuteDestroyBuffer(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaCreateImage")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreateImage])) ExecuteCreateImage(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaDestroyImage")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyImage])) ExecuteDestroyImage(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaFreeMemory")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::FreeMemory])) ExecuteFreeMemory(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaCreateLostAllocation")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::FreeMemoryPages])) + ExecuteFreeMemoryPages(lineNumber, csvSplit); + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreateLostAllocation])) ExecuteCreateLostAllocation(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaAllocateMemory")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemory])) ExecuteAllocateMemory(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaAllocateMemoryForBuffer")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemoryPages])) + ExecuteAllocateMemoryPages(lineNumber, csvSplit); + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemoryForBuffer])) ExecuteAllocateMemoryForBufferOrImage(lineNumber, csvSplit, OBJECT_TYPE::BUFFER); - else if(StrRangeEq(functionName, "vmaAllocateMemoryForImage")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemoryForImage])) ExecuteAllocateMemoryForBufferOrImage(lineNumber, csvSplit, OBJECT_TYPE::IMAGE); - else if(StrRangeEq(functionName, "vmaMapMemory")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::MapMemory])) ExecuteMapMemory(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaUnmapMemory")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::UnmapMemory])) ExecuteUnmapMemory(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaFlushAllocation")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::FlushAllocation])) ExecuteFlushAllocation(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaInvalidateAllocation")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::InvalidateAllocation])) ExecuteInvalidateAllocation(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaTouchAllocation")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::TouchAllocation])) ExecuteTouchAllocation(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaGetAllocationInfo")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::GetAllocationInfo])) ExecuteGetAllocationInfo(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaMakePoolAllocationsLost")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::MakePoolAllocationsLost])) ExecuteMakePoolAllocationsLost(lineNumber, csvSplit); - else if(StrRangeEq(functionName, "vmaResizeAllocation")) + else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::ResizeAllocation])) ExecuteResizeAllocation(lineNumber, csvSplit); else { @@ -2029,7 +2039,7 @@ void Player::ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit) } } -void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit) +void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit, const char* functionName) { if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false)) { @@ -2059,7 +2069,7 @@ void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit) { if(IssueWarning()) { - printf("Line %zu: Invalid parameters for vmaDestroyBuffer.\n", lineNumber); + printf("Line %zu: Invalid parameters for %s.\n", lineNumber, functionName); } } } @@ -2127,6 +2137,53 @@ void Player::ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit) } } +void Player::ExecuteFreeMemoryPages(size_t lineNumber, const CsvSplit& csvSplit) +{ + m_Stats.RegisterFunctionCall(VMA_FUNCTION::FreeMemoryPages); + + if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false)) + { + std::vector origAllocPtrs; + if(StrRangeToPtrList(csvSplit.GetRange(FIRST_PARAM_INDEX), origAllocPtrs)) + { + const size_t allocCount = origAllocPtrs.size(); + size_t notNullCount = 0; + for(size_t i = 0; i < allocCount; ++i) + { + const uint64_t origAllocPtr = origAllocPtrs[i]; + if(origAllocPtr != 0) + { + const auto it = m_Allocations.find(origAllocPtr); + if(it != m_Allocations.end()) + { + Destroy(it->second); + m_Allocations.erase(it); + ++notNullCount; + } + else + { + if(IssueWarning()) + { + printf("Line %zu: Allocation %llX not found.\n", lineNumber, origAllocPtr); + } + } + } + } + if(notNullCount) + { + UpdateMemStats(); + } + } + else + { + if(IssueWarning()) + { + printf("Line %zu: Invalid parameters for vmaFreeMemoryPages.\n", lineNumber); + } + } + } +} + void Player::ExecuteCreateLostAllocation(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreateLostAllocation); @@ -2206,6 +2263,68 @@ void Player::ExecuteAllocateMemory(size_t lineNumber, const CsvSplit& csvSplit) } } +void Player::ExecuteAllocateMemoryPages(size_t lineNumber, const CsvSplit& csvSplit) +{ + m_Stats.RegisterFunctionCall(VMA_FUNCTION::AllocateMemoryPages); + + if(ValidateFunctionParameterCount(lineNumber, csvSplit, 11, true)) + { + VkMemoryRequirements memReq = {}; + VmaAllocationCreateInfo allocCreateInfo = {}; + uint64_t origPool = 0; + std::vector origPtrs; + + if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), memReq.size) && + StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), memReq.alignment) && + StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), memReq.memoryTypeBits) && + StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), allocCreateInfo.flags) && + StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), (uint32_t&)allocCreateInfo.usage) && + StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), allocCreateInfo.requiredFlags) && + StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), allocCreateInfo.preferredFlags) && + StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), allocCreateInfo.memoryTypeBits) && + StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), origPool) && + StrRangeToPtrList(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), origPtrs)) + { + const size_t allocCount = origPtrs.size(); + if(allocCount > 0) + { + FindPool(lineNumber, origPool, allocCreateInfo.pool); + + if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 10) + { + PrepareUserData( + lineNumber, + allocCreateInfo.flags, + csvSplit.GetRange(FIRST_PARAM_INDEX + 10), + csvSplit.GetLine(), + allocCreateInfo.pUserData); + } + + UpdateMemStats(); + m_Stats.RegisterCreateAllocation(allocCount); + + std::vector allocations(allocCount); + + VkResult res = vmaAllocateMemoryPages(m_Allocator, &memReq, &allocCreateInfo, allocCount, allocations.data(), nullptr); + for(size_t i = 0; i < allocCount; ++i) + { + Allocation allocDesc = {}; + allocDesc.allocationFlags = allocCreateInfo.flags; + allocDesc.allocation = allocations[i]; + AddAllocation(lineNumber, origPtrs[i], res, "vmaAllocateMemoryPages", std::move(allocDesc)); + } + } + } + else + { + if(IssueWarning()) + { + printf("Line %zu: Invalid parameters for vmaAllocateMemoryPages.\n", lineNumber); + } + } + } +} + void Player::ExecuteAllocateMemoryForBufferOrImage(size_t lineNumber, const CsvSplit& csvSplit, OBJECT_TYPE objType) { switch(objType) diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h index eebeb0f..36dcae3 100644 --- a/src/vk_mem_alloc.h +++ b/src/vk_mem_alloc.h @@ -5676,6 +5676,11 @@ public: const VkMemoryRequirements& vkMemReq, const VmaAllocationCreateInfo& createInfo, VmaAllocation allocation); + void RecordAllocateMemoryPages(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + const VmaAllocationCreateInfo& createInfo, + uint64_t allocationCount, + const VmaAllocation* pAllocations); void RecordAllocateMemoryForBuffer(uint32_t frameIndex, const VkMemoryRequirements& vkMemReq, bool requiresDedicatedAllocation, @@ -5690,6 +5695,9 @@ public: VmaAllocation allocation); void RecordFreeMemory(uint32_t frameIndex, VmaAllocation allocation); + void RecordFreeMemoryPages(uint32_t frameIndex, + uint64_t allocationCount, + const VmaAllocation* pAllocations); void RecordResizeAllocation( uint32_t frameIndex, VmaAllocation allocation, @@ -5752,6 +5760,7 @@ private: int64_t m_StartCounter; void GetBasicParams(CallParams& outParams); + void PrintPointerList(uint64_t count, const VmaAllocation* pItems); void Flush(); }; @@ -11661,7 +11670,7 @@ VkResult VmaRecorder::Init(const VmaRecordSettings& settings, bool useMutex) // Write header. fprintf(m_File, "%s\n", "Vulkan Memory Allocator,Calls recording"); - fprintf(m_File, "%s\n", "1,4"); + fprintf(m_File, "%s\n", "1,5"); return VK_SUCCESS; } @@ -11747,6 +11756,32 @@ void VmaRecorder::RecordAllocateMemory(uint32_t frameIndex, Flush(); } +void VmaRecorder::RecordAllocateMemoryPages(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + const VmaAllocationCreateInfo& createInfo, + uint64_t allocationCount, + const VmaAllocation* pAllocations) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + UserDataString userDataStr(createInfo.flags, createInfo.pUserData); + fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryPages,%llu,%llu,%u,%u,%u,%u,%u,%u,%p,", callParams.threadId, callParams.time, frameIndex, + vkMemReq.size, + vkMemReq.alignment, + vkMemReq.memoryTypeBits, + createInfo.flags, + createInfo.usage, + createInfo.requiredFlags, + createInfo.preferredFlags, + createInfo.memoryTypeBits, + createInfo.pool); + PrintPointerList(allocationCount, pAllocations); + fprintf(m_File, ",%s\n", userDataStr.GetString()); + Flush(); +} + void VmaRecorder::RecordAllocateMemoryForBuffer(uint32_t frameIndex, const VkMemoryRequirements& vkMemReq, bool requiresDedicatedAllocation, @@ -11817,6 +11852,20 @@ void VmaRecorder::RecordFreeMemory(uint32_t frameIndex, Flush(); } +void VmaRecorder::RecordFreeMemoryPages(uint32_t frameIndex, + uint64_t allocationCount, + const VmaAllocation* pAllocations) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaFreeMemoryPages,", callParams.threadId, callParams.time, frameIndex); + PrintPointerList(allocationCount, pAllocations); + fprintf(m_File, "\n"); + Flush(); +} + void VmaRecorder::RecordResizeAllocation( uint32_t frameIndex, VmaAllocation allocation, @@ -12108,6 +12157,18 @@ void VmaRecorder::GetBasicParams(CallParams& outParams) outParams.time = (double)(counter.QuadPart - m_StartCounter) / (double)m_Freq; } +void VmaRecorder::PrintPointerList(uint64_t count, const VmaAllocation* pItems) +{ + if(count) + { + fprintf(m_File, "%p", pItems[0]); + for(uint64_t i = 1; i < count; ++i) + { + fprintf(m_File, " %p", pItems[i]); + } + } +} + void VmaRecorder::Flush() { if((m_Flags & VMA_RECORD_FLUSH_AFTER_CALL_BIT) != 0) @@ -14220,14 +14281,12 @@ VkResult vmaAllocateMemoryPages( #if VMA_RECORDING_ENABLED if(allocator->GetRecorder() != VMA_NULL) { - // TODO: Extend recording format with this function. - /* allocator->GetRecorder()->RecordAllocateMemoryPages( allocator->GetCurrentFrameIndex(), *pVkMemoryRequirements, *pCreateInfo, - *pAllocation); - */ + (uint64_t)allocationCount, + pAllocations); } #endif @@ -14391,15 +14450,13 @@ void vmaFreeMemoryPages( VMA_DEBUG_GLOBAL_MUTEX_LOCK #if VMA_RECORDING_ENABLED - // TODO Add this to recording file format. - /* if(allocator->GetRecorder() != VMA_NULL) { allocator->GetRecorder()->RecordFreeMemoryPages( allocator->GetCurrentFrameIndex(), - allocation); + (uint64_t)allocationCount, + pAllocations); } - */ #endif allocator->FreeMemory(allocationCount, pAllocations);