Better tracking of allocations.

This commit is contained in:
Adam Sawicki 2018-08-07 17:09:51 +02:00
parent 4d63e9d886
commit 71f3d067c5
2 changed files with 80 additions and 87 deletions

View File

@ -233,25 +233,22 @@ private:
uint32_t m_VmaFrameIndex = 0; uint32_t m_VmaFrameIndex = 0;
// Any of these handles null means it was created in original but couldn't be created now. // Any of these handles null can mean it was created in original but couldn't be created now.
struct Pool struct Pool
{ {
VmaPool pool; VmaPool pool;
}; };
struct Buffer struct Allocation
{ {
VmaAllocation allocation;
VkBuffer buffer; VkBuffer buffer;
VmaAllocation allocation;
};
struct Image
{
VkImage image; VkImage image;
VmaAllocation allocation;
}; };
std::unordered_map<uint64_t, Pool> m_Pools; std::unordered_map<uint64_t, Pool> m_Pools;
std::unordered_map<uint64_t, Buffer> m_Buffers; std::unordered_map<uint64_t, Allocation> m_Allocations;
std::unordered_map<uint64_t, Image> m_Images;
void Destroy(const Allocation& alloc);
// Increments warning counter. Returns true if warning message should be printed. // Increments warning counter. Returns true if warning message should be printed.
bool IssueWarning() { return m_WarningCount++ < MAX_WARNINGS_TO_SHOW; } bool IssueWarning() { return m_WarningCount++ < MAX_WARNINGS_TO_SHOW; }
@ -263,12 +260,15 @@ private:
// If parmeter count doesn't match, issues warning and returns false. // If parmeter count doesn't match, issues warning and returns false.
bool ValidateFunctionParameterCount(size_t lineNumber, const CsvSplit& csvSplit, size_t expectedParamCount, bool lastUnbound); bool ValidateFunctionParameterCount(size_t lineNumber, const CsvSplit& csvSplit, size_t expectedParamCount, bool lastUnbound);
void CreatePool(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteCreatePool(size_t lineNumber, const CsvSplit& csvSplit);
void DestroyPool(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteDestroyPool(size_t lineNumber, const CsvSplit& csvSplit);
void CreateBuffer(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit);
void DestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteDestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit) { DestroyAllocation(lineNumber, csvSplit); }
void CreateImage(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit);
void DestroyImage(size_t lineNumber, const CsvSplit& csvSplit); void ExecuteDestroyImage(size_t lineNumber, const CsvSplit& csvSplit) { DestroyAllocation(lineNumber, csvSplit); }
void ExecuteFreeMemory(size_t lineNumber, const CsvSplit& csvSplit) { DestroyAllocation(lineNumber, csvSplit); }
void DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit);
}; };
Player::Player() Player::Player()
@ -322,9 +322,9 @@ void Player::ExecuteLine(size_t lineNumber, const StrRange& line)
} }
} }
else if(StrRangeEq(functionName, "vmaCreatePool")) else if(StrRangeEq(functionName, "vmaCreatePool"))
CreatePool(lineNumber, csvSplit); ExecuteCreatePool(lineNumber, csvSplit);
else if(StrRangeEq(functionName, "vmaDestroyPool")) else if(StrRangeEq(functionName, "vmaDestroyPool"))
DestroyPool(lineNumber, csvSplit); ExecuteDestroyPool(lineNumber, csvSplit);
else if(StrRangeEq(functionName, "vmaSetAllocationUserData")) else if(StrRangeEq(functionName, "vmaSetAllocationUserData"))
{ {
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 2, true)) if(ValidateFunctionParameterCount(lineNumber, csvSplit, 2, true))
@ -333,13 +333,15 @@ void Player::ExecuteLine(size_t lineNumber, const StrRange& line)
} }
} }
else if(StrRangeEq(functionName, "vmaCreateBuffer")) else if(StrRangeEq(functionName, "vmaCreateBuffer"))
CreateBuffer(lineNumber, csvSplit); ExecuteCreateBuffer(lineNumber, csvSplit);
else if(StrRangeEq(functionName, "vmaDestroyBuffer")) else if(StrRangeEq(functionName, "vmaDestroyBuffer"))
DestroyBuffer(lineNumber, csvSplit); ExecuteDestroyBuffer(lineNumber, csvSplit);
else if(StrRangeEq(functionName, "vmaCreateImage")) else if(StrRangeEq(functionName, "vmaCreateImage"))
CreateImage(lineNumber, csvSplit); ExecuteCreateImage(lineNumber, csvSplit);
else if(StrRangeEq(functionName, "vmaDestroyImage")) else if(StrRangeEq(functionName, "vmaDestroyImage"))
DestroyImage(lineNumber, csvSplit); ExecuteDestroyImage(lineNumber, csvSplit);
else if(StrRangeEq(functionName, "vmaFreeMemory"))
ExecuteFreeMemory(lineNumber, csvSplit);
else else
{ {
if(IssueWarning()) if(IssueWarning())
@ -353,6 +355,21 @@ void Player::ExecuteLine(size_t lineNumber, const StrRange& line)
} }
} }
void Player::Destroy(const Allocation& alloc)
{
if(alloc.buffer)
{
assert(alloc.image == VK_NULL_HANDLE);
vmaDestroyBuffer(m_Allocator, alloc.buffer, alloc.allocation);
}
else if(alloc.image)
{
vmaDestroyImage(m_Allocator, alloc.image, alloc.allocation);
}
else
vmaFreeMemory(m_Allocator, alloc.allocation);
}
int Player::InitVulkan() int Player::InitVulkan()
{ {
printf("Initializing Vulkan...\n"); printf("Initializing Vulkan...\n");
@ -540,24 +557,16 @@ int Player::InitVulkan()
void Player::FinalizeVulkan() void Player::FinalizeVulkan()
{ {
if(!m_Images.empty()) if(!m_Allocations.empty())
{ {
printf("WARNING: Images not destroyed: %zu.\n", m_Images.size()); printf("WARNING: Allocations not destroyed: %zu.\n", m_Allocations.size());
for(const auto it : m_Images) for(const auto it : m_Allocations)
{ {
vmaDestroyImage(m_Allocator, it.second.image, it.second.allocation); Destroy(it.second);
}
} }
if(!m_Buffers.empty()) m_Allocations.clear();
{
printf("WARNING: Buffers not destroyed: %zu.\n", m_Buffers.size());
for(const auto it : m_Buffers)
{
vmaDestroyBuffer(m_Allocator, it.second.buffer, it.second.allocation);
}
} }
if(!m_Pools.empty()) if(!m_Pools.empty())
@ -565,9 +574,9 @@ void Player::FinalizeVulkan()
printf("WARNING: Pools not destroyed: %zu.\n", m_Pools.size()); printf("WARNING: Pools not destroyed: %zu.\n", m_Pools.size());
for(const auto it : m_Pools) for(const auto it : m_Pools)
{
vmaDestroyPool(m_Allocator, it.second.pool); vmaDestroyPool(m_Allocator, it.second.pool);
}
m_Pools.clear();
} }
vkDeviceWaitIdle(m_Device); vkDeviceWaitIdle(m_Device);
@ -641,7 +650,7 @@ bool Player::ValidateFunctionParameterCount(size_t lineNumber, const CsvSplit& c
return ok; return ok;
} }
void Player::CreatePool(size_t lineNumber, const CsvSplit& csvSplit) void Player::ExecuteCreatePool(size_t lineNumber, const CsvSplit& csvSplit)
{ {
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 7, false)) if(ValidateFunctionParameterCount(lineNumber, csvSplit, 7, false))
{ {
@ -682,7 +691,7 @@ void Player::CreatePool(size_t lineNumber, const CsvSplit& csvSplit)
} }
} }
void Player::DestroyPool(size_t lineNumber, const CsvSplit& csvSplit) void Player::ExecuteDestroyPool(size_t lineNumber, const CsvSplit& csvSplit)
{ {
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false)) if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
{ {
@ -710,7 +719,7 @@ void Player::DestroyPool(size_t lineNumber, const CsvSplit& csvSplit)
} }
} }
void Player::CreateBuffer(size_t lineNumber, const CsvSplit& csvSplit) void Player::ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit)
{ {
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 12, true)) if(ValidateFunctionParameterCount(lineNumber, csvSplit, 12, true))
{ {
@ -743,15 +752,15 @@ void Player::CreateBuffer(size_t lineNumber, const CsvSplit& csvSplit)
} }
} }
Buffer bufDesc = {}; Allocation allocDesc = {};
VkResult res = vmaCreateBuffer(m_Allocator, &bufCreateInfo, &allocCreateInfo, &bufDesc.buffer, &bufDesc.allocation, nullptr); VkResult res = vmaCreateBuffer(m_Allocator, &bufCreateInfo, &allocCreateInfo, &allocDesc.buffer, &allocDesc.allocation, nullptr);
if(res == VK_SUCCESS) if(res == VK_SUCCESS)
{ {
const auto existingIt = m_Buffers.find(origPtr); const auto existingIt = m_Allocations.find(origPtr);
if(existingIt != m_Buffers.end()) if(existingIt != m_Allocations.end())
{ {
if(IssueWarning()) if(IssueWarning())
printf("Line %zu: Allocation %llX for buffer already exists.\n", lineNumber, origPtr); printf("Line %zu: Allocation %llX already exists.\n", lineNumber, origPtr);
} }
} }
else else
@ -759,7 +768,7 @@ void Player::CreateBuffer(size_t lineNumber, const CsvSplit& csvSplit)
if(IssueWarning()) if(IssueWarning())
printf("Line %zu: vmaCreateBuffer failed (%u).\n", lineNumber, res); printf("Line %zu: vmaCreateBuffer failed (%u).\n", lineNumber, res);
} }
m_Buffers[origPtr] = bufDesc; m_Allocations[origPtr] = allocDesc;
} }
else else
{ {
@ -769,7 +778,7 @@ void Player::CreateBuffer(size_t lineNumber, const CsvSplit& csvSplit)
} }
} }
void Player::DestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit) void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit)
{ {
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false)) if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
{ {
@ -777,16 +786,16 @@ void Player::DestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit)
if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origAllocPtr)) if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origAllocPtr))
{ {
const auto it = m_Buffers.find(origAllocPtr); const auto it = m_Allocations.find(origAllocPtr);
if(it != m_Buffers.end()) if(it != m_Allocations.end())
{ {
vmaDestroyBuffer(m_Allocator, it->second.buffer, it->second.allocation); Destroy(it->second);
m_Buffers.erase(it); m_Allocations.erase(it);
} }
else else
{ {
if(IssueWarning()) if(IssueWarning())
printf("Line %zu: Allocation %llX for buffer not found.\n", lineNumber, origAllocPtr); printf("Line %zu: Allocation %llX not found.\n", lineNumber, origAllocPtr);
} }
} }
else else
@ -797,7 +806,7 @@ void Player::DestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit)
} }
} }
void Player::CreateImage(size_t lineNumber, const CsvSplit& csvSplit) void Player::ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit)
{ {
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 21, true)) if(ValidateFunctionParameterCount(lineNumber, csvSplit, 21, true))
{ {
@ -839,15 +848,15 @@ void Player::CreateImage(size_t lineNumber, const CsvSplit& csvSplit)
} }
} }
Image imageDesc = {}; Allocation allocDesc = {};
VkResult res = vmaCreateImage(m_Allocator, &imageCreateInfo, &allocCreateInfo, &imageDesc.image, &imageDesc.allocation, nullptr); VkResult res = vmaCreateImage(m_Allocator, &imageCreateInfo, &allocCreateInfo, &allocDesc.image, &allocDesc.allocation, nullptr);
if(res == VK_SUCCESS) if(res == VK_SUCCESS)
{ {
const auto existingIt = m_Images.find(origPtr); const auto existingIt = m_Allocations.find(origPtr);
if(existingIt != m_Images.end()) if(existingIt != m_Allocations.end())
{ {
if(IssueWarning()) if(IssueWarning())
printf("Line %zu: Allocation %llX for image already exists.\n", lineNumber, origPtr); printf("Line %zu: Allocation %llX already exists.\n", lineNumber, origPtr);
} }
} }
else else
@ -855,7 +864,7 @@ void Player::CreateImage(size_t lineNumber, const CsvSplit& csvSplit)
if(IssueWarning()) if(IssueWarning())
printf("Line %zu: vmaCreateImage failed (%u).\n", lineNumber, res); printf("Line %zu: vmaCreateImage failed (%u).\n", lineNumber, res);
} }
m_Images[origPtr] = imageDesc; m_Allocations[origPtr] = allocDesc;
} }
else else
{ {
@ -865,34 +874,6 @@ void Player::CreateImage(size_t lineNumber, const CsvSplit& csvSplit)
} }
} }
void Player::DestroyImage(size_t lineNumber, const CsvSplit& csvSplit)
{
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
{
uint64_t origAllocPtr = 0;
if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origAllocPtr))
{
const auto it = m_Images.find(origAllocPtr);
if(it != m_Images.end())
{
vmaDestroyImage(m_Allocator, it->second.image, it->second.allocation);
m_Images.erase(it);
}
else
{
if(IssueWarning())
printf("Line %zu: Allocation %llX for image not found.\n", lineNumber, origAllocPtr);
}
}
else
{
if(IssueWarning())
printf("Line %zu: Invalid parameters for vmaDestroyBuffer.\n", lineNumber);
}
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Main functions // Main functions

View File

@ -9927,8 +9927,20 @@ void vmaFreeMemory(
VmaAllocator allocator, VmaAllocator allocator,
VmaAllocation allocation) VmaAllocation allocation)
{ {
Crash();
VMA_ASSERT(allocator); VMA_ASSERT(allocator);
{
VmaMutexLock lock(g_FileMutex, true);
EnsureFile();
LARGE_INTEGER counter; QueryPerformanceCounter(&counter);
const DWORD threadId = GetCurrentThreadId();
const double time = (double)(counter.QuadPart - g_StartCounter.QuadPart) / (double)g_Freq.QuadPart;
const uint32_t frameIndex = allocator->GetCurrentFrameIndex();
fprintf(g_File, "%u,%.3f,%u,vmaFreeMemory,%p\n", threadId, time, frameIndex,
allocation);
fflush(g_File);
}
VMA_DEBUG_LOG("vmaFreeMemory"); VMA_DEBUG_LOG("vmaFreeMemory");
VMA_DEBUG_GLOBAL_MUTEX_LOCK VMA_DEBUG_GLOBAL_MUTEX_LOCK
if(allocation != VK_NULL_HANDLE) if(allocation != VK_NULL_HANDLE)