//
// Copyright (c) 2018-2020 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "VmaUsage.h"
#include "Common.h"
#include "Constants.h"
#include <unordered_map>
#include <map>
#include <algorithm>

static VERBOSITY g_Verbosity = VERBOSITY::DEFAULT;

static const uint32_t VULKAN_API_VERSION = VK_API_VERSION_1_1;

namespace DetailedStats
{
    
struct Flag
{
    uint32_t setCount = 0;

    void PostValue(bool v)
    {
        if(v)
        {
            ++setCount;
        }
    }

    void Print(uint32_t totalCount) const
    {
        if(setCount)
        {
            printf(" %u (%.2f%%)\n", setCount, (double)setCount * 100.0 / (double)totalCount);
        }
        else
        {
            printf(" 0\n");
        }
    }
};

struct Enum
{
    Enum(size_t itemCount, const char* const* itemNames, const uint32_t* itemValues = nullptr) :
        m_ItemCount(itemCount),
        m_ItemNames(itemNames),
        m_ItemValues(itemValues)
    {
    }

    void PostValue(uint32_t v)
    {
        if(v < _countof(m_BaseCount))
        {
            ++m_BaseCount[v];
        }
        else
        {
            auto it = m_ExtendedCount.find(v);
            if(it != m_ExtendedCount.end())
            {
                ++it->second;
            }
            else
            {
                m_ExtendedCount.insert(std::make_pair(v, 1u));
            }
        }
    }

    void Print(uint32_t totalCount) const
    {
        if(totalCount &&
            (!m_ExtendedCount.empty() || std::count_if(m_BaseCount, m_BaseCount + _countof(m_BaseCount), [](uint32_t v) { return v > 0; })))
        {
            printf("\n");
            
            for(size_t i = 0; i < _countof(m_BaseCount); ++i)
            {
                const uint32_t currCount = m_BaseCount[i];
                if(currCount)
                {
                    PrintItem((uint32_t)i, currCount, totalCount);
                }
            }

            for(const auto& it : m_ExtendedCount)
            {
                PrintItem(it.first, it.second, totalCount);
            }
        }
        else
        {
            printf(" 0\n");
        }
    }

private:
    const size_t m_ItemCount;
    const char* const* const m_ItemNames;
    const uint32_t* const m_ItemValues;

    uint32_t m_BaseCount[32] = {};
    std::map<uint32_t, uint32_t> m_ExtendedCount;

    void PrintItem(uint32_t value, uint32_t count, uint32_t totalCount) const
    {
        size_t itemIndex = m_ItemCount;
        if(m_ItemValues)
        {
            for(itemIndex = 0; itemIndex < m_ItemCount; ++itemIndex)
            {
                if(m_ItemValues[itemIndex] == value)
                {
                    break;
                }
            }
        }
        else
        {
            if(value < m_ItemCount)
            {
                itemIndex = value;
            }
        }

        if(itemIndex < m_ItemCount)
        {
            printf("        %s: ", m_ItemNames[itemIndex]);
        }
        else
        {
            printf("        0x%X: ", value);
        }

        printf("%u (%.2f%%)\n", count, (double)count * 100.0 / (double)totalCount);
    }
};

struct FlagSet
{
    uint32_t count[32] = {};

    FlagSet(size_t count, const char* const* names, const uint32_t* values = nullptr) :
        m_Count(count),
        m_Names(names),
        m_Values(values)
    {
    }

    void PostValue(uint32_t v)
    {
        for(size_t i = 0; i < 32; ++i)
        {
            if((v & (1u << i)) != 0)
            {
                ++count[i];
            }
        }
    }

    void Print(uint32_t totalCount) const
    {
        if(totalCount &&
            std::count_if(count, count + _countof(count), [](uint32_t v) { return v > 0; }))
        {
            printf("\n");
            for(uint32_t bitIndex = 0; bitIndex < 32; ++bitIndex)
            {
                const uint32_t currCount = count[bitIndex];
                if(currCount)
                {
                    size_t itemIndex = m_Count;
                    if(m_Values)
                    {
                        for(itemIndex = 0; itemIndex < m_Count; ++itemIndex)
                        {
                            if(m_Values[itemIndex] == (1u << bitIndex))
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        if(bitIndex < m_Count)
                        {
                            itemIndex = bitIndex;
                        }
                    }

                    if(itemIndex < m_Count)
                    {
                        printf("        %s: ", m_Names[itemIndex]);
                    }
                    else
                    {
                        printf("        0x%X: ", 1u << bitIndex);
                    }

                    printf("%u (%.2f%%)\n", currCount, (double)currCount * 100.0 / (double)totalCount);
                }
            }
        }
        else
        {
            printf(" 0\n");
        }
    }

private:
    const size_t m_Count;
    const char* const* const m_Names;
    const uint32_t* const m_Values;
};

// T should be unsigned int
template<typename T>
struct MinMaxAvg
{
    T min = std::numeric_limits<T>::max();
    T max = 0;
    T sum = T();

    void PostValue(T v)
    {
        this->min = std::min(this->min, v);
        this->max = std::max(this->max, v);
        sum += v;
    }

    void Print(uint32_t totalCount) const
    {
        if(totalCount && sum > T())
        {
            if(this->min == this->max)
            {
                printf(" %llu\n", (uint64_t)this->max);
            }
            else
            {
                printf("\n        Min: %llu\n        Max: %llu\n        Avg: %llu\n",
                    (uint64_t)this->min,
                    (uint64_t)this->max,
                    round_div<uint64_t>(this->sum, totalCount));
            }
        }
        else
        {
            printf(" 0\n");
        }
    }
};

template<typename T>
struct BitMask
{
    uint32_t zeroCount = 0;
    uint32_t maxCount = 0;

    void PostValue(T v)
    {
        if(v)
        {
            if(v == std::numeric_limits<T>::max())
            {
                ++maxCount;
            }
        }
        else
        {
            ++zeroCount;
        }
    }

    void Print(uint32_t totalCount) const
    {
        if(totalCount > 0 && zeroCount < totalCount)
        {
            const uint32_t otherCount = totalCount - (zeroCount + maxCount);
            
            printf("\n        0: %u (%.2f%%)\n        Max: %u (%.2f%%)\n        Other: %u (%.2f%%)\n",
                zeroCount,  (double)zeroCount  * 100.0 / (double)totalCount,
                maxCount,   (double)maxCount   * 100.0 / (double)totalCount,
                otherCount, (double)otherCount * 100.0 / (double)totalCount);
        }
        else
        {
            printf(" 0\n");
        }
    }
};

struct CountPerMemType
{
    uint32_t count[VK_MAX_MEMORY_TYPES] = {};

    void PostValue(uint32_t v)
    {
        for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i)
        {
            if((v & (1u << i)) != 0)
            {
                ++count[i];
            }
        }
    }

    void Print(uint32_t totalCount) const
    {
        if(totalCount)
        {
            printf("\n");
            for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i)
            {
                if(count[i])
                {
                    printf("        %u: %u (%.2f%%)\n", i, count[i],
                        (double)count[i] * 100.0 / (double)totalCount);
                }
            }
        }
        else
        {
            printf(" 0\n");
        }
    }
};

struct StructureStats
{
    uint32_t totalCount = 0;
};

#define PRINT_FIELD(name) \
    printf("    " #name ":"); \
    (name).Print(totalCount);
#define PRINT_FIELD_NAMED(name, nameStr) \
    printf("    " nameStr ":"); \
    (name).Print(totalCount);

struct VmaPoolCreateInfoStats : public StructureStats
{
    CountPerMemType memoryTypeIndex;
    FlagSet flags;
    MinMaxAvg<VkDeviceSize> blockSize;
    MinMaxAvg<size_t> minBlockCount;
    MinMaxAvg<size_t> maxBlockCount;
    Flag minMaxBlockCountEqual;
    MinMaxAvg<uint32_t> frameInUseCount;

    VmaPoolCreateInfoStats() :
        flags(VMA_POOL_CREATE_FLAG_COUNT, VMA_POOL_CREATE_FLAG_NAMES, VMA_POOL_CREATE_FLAG_VALUES)
    {
    }

    void PostValue(const VmaPoolCreateInfo& v)
    {
        ++totalCount;

        memoryTypeIndex.PostValue(v.memoryTypeIndex);
        flags.PostValue(v.flags);
        blockSize.PostValue(v.blockSize);
        minBlockCount.PostValue(v.minBlockCount);
        maxBlockCount.PostValue(v.maxBlockCount);
        minMaxBlockCountEqual.PostValue(v.minBlockCount == v.maxBlockCount);
        frameInUseCount.PostValue(v.frameInUseCount);
    }

    void Print() const
    {
        if(totalCount == 0)
        {
            return;
        }

        printf("VmaPoolCreateInfo (%u):\n", totalCount);

        PRINT_FIELD(memoryTypeIndex);
        PRINT_FIELD(flags);
        PRINT_FIELD(blockSize);
        PRINT_FIELD(minBlockCount);
        PRINT_FIELD(maxBlockCount);
        PRINT_FIELD_NAMED(minMaxBlockCountEqual, "minBlockCount == maxBlockCount");
        PRINT_FIELD(frameInUseCount);
    }
};

struct VkBufferCreateInfoStats : public StructureStats
{
    FlagSet flags;
    MinMaxAvg<VkDeviceSize> size;
    FlagSet usage;
    Enum sharingMode;

    VkBufferCreateInfoStats() :
        flags(VK_BUFFER_CREATE_FLAG_COUNT, VK_BUFFER_CREATE_FLAG_NAMES, VK_BUFFER_CREATE_FLAG_VALUES),
        usage(VK_BUFFER_USAGE_FLAG_COUNT, VK_BUFFER_USAGE_FLAG_NAMES, VK_BUFFER_USAGE_FLAG_VALUES),
        sharingMode(VK_SHARING_MODE_COUNT, VK_SHARING_MODE_NAMES)
    {
    }

    void PostValue(const VkBufferCreateInfo& v)
    {
        ++totalCount;

        flags.PostValue(v.flags);
        size.PostValue(v.size);
        usage.PostValue(v.usage);
        sharingMode.PostValue(v.sharingMode);
    }

    void Print() const
    {
        if(totalCount == 0)
        {
            return;
        }

        printf("VkBufferCreateInfo (%u):\n", totalCount);

        PRINT_FIELD(flags);
        PRINT_FIELD(size);
        PRINT_FIELD(usage);
        PRINT_FIELD(sharingMode);
    }
};

struct VkImageCreateInfoStats : public StructureStats
{
    FlagSet flags;
    Enum imageType;
    Enum format;
    MinMaxAvg<uint32_t> width, height, depth, mipLevels, arrayLayers;
    Flag depthGreaterThanOne, mipLevelsGreaterThanOne, arrayLayersGreaterThanOne;
    Enum samples;
    Enum tiling;
    FlagSet usage;
    Enum sharingMode;
    Enum initialLayout;

    VkImageCreateInfoStats() :
        flags(VK_IMAGE_CREATE_FLAG_COUNT, VK_IMAGE_CREATE_FLAG_NAMES, VK_IMAGE_CREATE_FLAG_VALUES),
        imageType(VK_IMAGE_TYPE_COUNT, VK_IMAGE_TYPE_NAMES),
        format(VK_FORMAT_COUNT, VK_FORMAT_NAMES, VK_FORMAT_VALUES),
        samples(VK_SAMPLE_COUNT_COUNT, VK_SAMPLE_COUNT_NAMES, VK_SAMPLE_COUNT_VALUES),
        tiling(VK_IMAGE_TILING_COUNT, VK_IMAGE_TILING_NAMES),
        usage(VK_IMAGE_USAGE_FLAG_COUNT, VK_IMAGE_USAGE_FLAG_NAMES, VK_IMAGE_USAGE_FLAG_VALUES),
        sharingMode(VK_SHARING_MODE_COUNT, VK_SHARING_MODE_NAMES),
        initialLayout(VK_IMAGE_LAYOUT_COUNT, VK_IMAGE_LAYOUT_NAMES, VK_IMAGE_LAYOUT_VALUES)
    {
    }

    void PostValue(const VkImageCreateInfo& v)
    {
        ++totalCount;

        flags.PostValue(v.flags);
        imageType.PostValue(v.imageType);
        format.PostValue(v.format);
        width.PostValue(v.extent.width);
        height.PostValue(v.extent.height);
        depth.PostValue(v.extent.depth);
        mipLevels.PostValue(v.mipLevels);
        arrayLayers.PostValue(v.arrayLayers);
        depthGreaterThanOne.PostValue(v.extent.depth > 1);
        mipLevelsGreaterThanOne.PostValue(v.mipLevels > 1);
        arrayLayersGreaterThanOne.PostValue(v.arrayLayers > 1);
        samples.PostValue(v.samples);
        tiling.PostValue(v.tiling);
        usage.PostValue(v.usage);
        sharingMode.PostValue(v.sharingMode);
        initialLayout.PostValue(v.initialLayout);
    }

    void Print() const
    {
        if(totalCount == 0)
        {
            return;
        }

        printf("VkImageCreateInfo (%u):\n", totalCount);

        PRINT_FIELD(flags);
        PRINT_FIELD(imageType);
        PRINT_FIELD(format);
        PRINT_FIELD(width);
        PRINT_FIELD(height);
        PRINT_FIELD(depth);
        PRINT_FIELD(mipLevels);
        PRINT_FIELD(arrayLayers);
        PRINT_FIELD_NAMED(depthGreaterThanOne, "depth > 1");
        PRINT_FIELD_NAMED(mipLevelsGreaterThanOne, "mipLevels > 1");
        PRINT_FIELD_NAMED(arrayLayersGreaterThanOne, "arrayLayers > 1");
        PRINT_FIELD(samples);
        PRINT_FIELD(tiling);
        PRINT_FIELD(usage);
        PRINT_FIELD(sharingMode);
        PRINT_FIELD(initialLayout);
    }
};

struct VmaAllocationCreateInfoStats : public StructureStats
{
    FlagSet flags;
    Enum usage;
    FlagSet requiredFlags, preferredFlags;
    Flag requiredFlagsNotZero, preferredFlagsNotZero;
    BitMask<uint32_t> memoryTypeBits;
    Flag poolNotNull;
    Flag userDataNotNull;

    VmaAllocationCreateInfoStats() :
        flags(VMA_ALLOCATION_CREATE_FLAG_COUNT, VMA_ALLOCATION_CREATE_FLAG_NAMES, VMA_ALLOCATION_CREATE_FLAG_VALUES),
        usage(VMA_MEMORY_USAGE_COUNT, VMA_MEMORY_USAGE_NAMES),
        requiredFlags(VK_MEMORY_PROPERTY_FLAG_COUNT, VK_MEMORY_PROPERTY_FLAG_NAMES, VK_MEMORY_PROPERTY_FLAG_VALUES),
        preferredFlags(VK_MEMORY_PROPERTY_FLAG_COUNT, VK_MEMORY_PROPERTY_FLAG_NAMES, VK_MEMORY_PROPERTY_FLAG_VALUES)
    {
    }

    void PostValue(const VmaAllocationCreateInfo& v, size_t count = 1)
    {
        totalCount += (uint32_t)count;

        for(size_t i = 0; i < count; ++i)
        {
            flags.PostValue(v.flags);
            usage.PostValue(v.usage);
            requiredFlags.PostValue(v.requiredFlags);
            preferredFlags.PostValue(v.preferredFlags);
            requiredFlagsNotZero.PostValue(v.requiredFlags != 0);
            preferredFlagsNotZero.PostValue(v.preferredFlags != 0);
            memoryTypeBits.PostValue(v.memoryTypeBits);
            poolNotNull.PostValue(v.pool != VK_NULL_HANDLE);
            userDataNotNull.PostValue(v.pUserData != nullptr);
        }
    }

    void Print() const
    {
        if(totalCount == 0)
        {
            return;
        }

        printf("VmaAllocationCreateInfo (%u):\n", totalCount);

        PRINT_FIELD(flags);
        PRINT_FIELD(usage);
        PRINT_FIELD(requiredFlags);
        PRINT_FIELD(preferredFlags);
        PRINT_FIELD_NAMED(requiredFlagsNotZero, "requiredFlags != 0");
        PRINT_FIELD_NAMED(preferredFlagsNotZero, "preferredFlags != 0");
        PRINT_FIELD(memoryTypeBits);
        PRINT_FIELD_NAMED(poolNotNull, "pool != VK_NULL_HANDLE");
        PRINT_FIELD_NAMED(userDataNotNull, "pUserData != nullptr");
    }
};

struct VmaAllocateMemoryPagesStats : public StructureStats
{
    MinMaxAvg<size_t> allocationCount;

    void PostValue(size_t allocationCount)
    {
        this->allocationCount.PostValue(allocationCount);
    }

    void Print() const
    {
        if(totalCount == 0)
        {
            return;
        }

        printf("vmaAllocateMemoryPages (%u):\n", totalCount);

        PRINT_FIELD(allocationCount);
    }
};

struct VmaDefragmentationInfo2Stats : public StructureStats
{
    BitMask<VkDeviceSize> maxCpuBytesToMove;
    BitMask<uint32_t> maxCpuAllocationsToMove;
    BitMask<VkDeviceSize> maxGpuBytesToMove;
    BitMask<uint32_t> maxGpuAllocationsToMove;
    Flag commandBufferNotNull;
    MinMaxAvg<uint32_t> allocationCount;
    Flag allocationCountNotZero;
    MinMaxAvg<uint32_t> poolCount;
    Flag poolCountNotZero;

    void PostValue(const VmaDefragmentationInfo2& info)
    {
        ++totalCount;

        maxCpuBytesToMove.PostValue(info.maxCpuBytesToMove);
        maxCpuAllocationsToMove.PostValue(info.maxCpuAllocationsToMove);
        maxGpuBytesToMove.PostValue(info.maxGpuBytesToMove);
        maxGpuAllocationsToMove.PostValue(info.maxGpuAllocationsToMove);
        commandBufferNotNull.PostValue(info.commandBuffer != VK_NULL_HANDLE);
        allocationCount.PostValue(info.allocationCount);
        allocationCountNotZero.PostValue(info.allocationCount != 0);
        poolCount.PostValue(info.poolCount);
        poolCountNotZero.PostValue(info.poolCount != 0);
    }

    void Print() const
    {
        if(totalCount == 0)
        {
            return;
        }

        printf("VmaDefragmentationInfo2 (%u):\n", totalCount);

        PRINT_FIELD(maxCpuBytesToMove);
        PRINT_FIELD(maxCpuAllocationsToMove);
        PRINT_FIELD(maxGpuBytesToMove);
        PRINT_FIELD(maxGpuAllocationsToMove);
        PRINT_FIELD_NAMED(commandBufferNotNull, "commandBuffer != VK_NULL_HANDLE");
        PRINT_FIELD(allocationCount);
        PRINT_FIELD_NAMED(allocationCountNotZero, "allocationCount > 0");
        PRINT_FIELD(poolCount);
        PRINT_FIELD_NAMED(poolCountNotZero, "poolCount > 0");
    }
};

#undef PRINT_FIELD_NAMED
#undef PRINT_FIELD

} // namespace DetailedStats

// Set this to false to disable deleting leaked VmaAllocation, VmaPool objects
// and let VMA report asserts about them.
static const bool CLEANUP_LEAKED_OBJECTS = true;

static std::string g_FilePath;
// Most significant 16 bits are major version, least significant 16 bits are minor version.
static uint32_t g_FileVersion;

inline uint32_t MakeVersion(uint32_t major, uint32_t minor) { return (major << 16) | minor; }
inline uint32_t GetVersionMajor(uint32_t version) { return version >> 16; }
inline uint32_t GetVersionMinor(uint32_t version) { return version & 0xFFFF; }

static size_t g_IterationCount = 1;
static uint32_t g_PhysicalDeviceIndex = 0;
static RangeSequence<size_t> g_LineRanges;
static bool g_UserDataEnabled = true;
static bool g_MemStatsEnabled = false;
VULKAN_EXTENSION_REQUEST g_VK_LAYER_LUNARG_standard_validation = VULKAN_EXTENSION_REQUEST::DEFAULT;
VULKAN_EXTENSION_REQUEST g_VK_EXT_memory_budget_request        = VULKAN_EXTENSION_REQUEST::DEFAULT;
VULKAN_EXTENSION_REQUEST g_VK_AMD_device_coherent_memory_request = VULKAN_EXTENSION_REQUEST::DEFAULT;

struct StatsAfterLineEntry
{
    size_t line;
    bool detailed;

    bool operator<(const StatsAfterLineEntry& rhs) const { return line < rhs.line; }
    bool operator==(const StatsAfterLineEntry& rhs) const { return line == rhs.line; }
};
static std::vector<StatsAfterLineEntry> g_DumpStatsAfterLine;
static std::vector<size_t> g_DefragmentAfterLine;
static uint32_t g_DefragmentationFlags = 0;
static size_t g_DumpStatsAfterLineNextIndex = 0;
static size_t g_DefragmentAfterLineNextIndex = 0;

static bool ValidateFileVersion()
{
    if(GetVersionMajor(g_FileVersion) == 1 &&
        GetVersionMinor(g_FileVersion) <= 8)
    {
        return true;
    }

    return false;
}

static bool ParseFileVersion(const StrRange& s)
{
    CsvSplit csvSplit;
    csvSplit.Set(s, 2);
    uint32_t major, minor;
    if(csvSplit.GetCount() == 2 &&
        StrRangeToUint(csvSplit.GetRange(0), major) &&
        StrRangeToUint(csvSplit.GetRange(1), minor))
    {
        g_FileVersion = (major << 16) | minor;
        return true;
    }
    else
    {
        return false;
    }
}

////////////////////////////////////////////////////////////////////////////////
// class Statistics

class Statistics
{
public:
    static uint32_t BufferUsageToClass(uint32_t usage);
    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;

    const size_t* GetFunctionCallCount() const { return m_FunctionCallCount; }
    size_t GetImageCreationCount(uint32_t imgClass) const { return m_ImageCreationCount[imgClass]; }
    size_t GetLinearImageCreationCount() const { return m_LinearImageCreationCount; }
    size_t GetBufferCreationCount(uint32_t bufClass) const { return m_BufferCreationCount[bufClass]; }
    size_t GetAllocationCreationCount() const { return (size_t)m_VmaAllocationCreateInfo.totalCount + m_CreateLostAllocationCount; }
    size_t GetPoolCreationCount() const { return m_VmaPoolCreateInfo.totalCount; }
    size_t GetBufferCreationCount() const { return (size_t)m_VkBufferCreateInfo.totalCount; }

    void RegisterFunctionCall(VMA_FUNCTION func);
    void RegisterCreateImage(const VkImageCreateInfo& info);
    void RegisterCreateBuffer(const VkBufferCreateInfo& info);
    void RegisterCreatePool(const VmaPoolCreateInfo& info);
    void RegisterCreateAllocation(const VmaAllocationCreateInfo& info, size_t allocCount = 1);
    void RegisterCreateLostAllocation() { ++m_CreateLostAllocationCount; }
    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:
    uint32_t m_MemHeapCount = 0;
    uint32_t m_MemTypeCount = 0;

    size_t m_FunctionCallCount[(size_t)VMA_FUNCTION::Count] = {};
    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
    {
        uint32_t blockCount;
        uint32_t allocationCount;
        uint32_t unusedRangeCount;
        VkDeviceSize usedBytes;
        VkDeviceSize unusedBytes;
        VkDeviceSize totalBytes;
    };
    struct MemStats
    {
        MemStatInfo memoryType[VK_MAX_MEMORY_TYPES];
        MemStatInfo memoryHeap[VK_MAX_MEMORY_HEAPS];
        MemStatInfo total;
    } m_PeakMemStats;

    DetailedStats::VmaPoolCreateInfoStats m_VmaPoolCreateInfo;
    DetailedStats::VkBufferCreateInfoStats m_VkBufferCreateInfo;
    DetailedStats::VkImageCreateInfoStats m_VkImageCreateInfo;
    DetailedStats::VmaAllocationCreateInfoStats m_VmaAllocationCreateInfo;
    size_t m_CreateLostAllocationCount = 0;
    DetailedStats::VmaAllocateMemoryPagesStats m_VmaAllocateMemoryPages;
    DetailedStats::VmaDefragmentationInfo2Stats m_VmaDefragmentationInfo2;

    void UpdateMemStatInfo(MemStatInfo& inoutPeakInfo, const VmaStatInfo& currInfo);
    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.
    // It's indirect, vertex, or index buffer.
    if ((usage & (VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT |
        VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
        VK_BUFFER_USAGE_INDEX_BUFFER_BIT)) != 0)
    {
        return 0;
    }
    // Buffer is accessed by shaders for load/store/atomic.
    // Aka "UAV"
    else if ((usage & (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
        VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) != 0)
    {
        return 1;
    }
    // Buffer is accessed by shaders for reading uniform data.
    // Aka "constant buffer"
    else if ((usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) != 0)
    {
        return 2;
    }
    // Any other type of buffer.
    // Notice that VK_BUFFER_USAGE_TRANSFER_SRC_BIT and VK_BUFFER_USAGE_TRANSFER_DST_BIT
    // flags are intentionally ignored.
    else
    {
        return 3;
    }
}

uint32_t Statistics::ImageUsageToClass(uint32_t usage)
{
    // Image is used as depth/stencil "texture/surface".
    if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
    {
        return 0;
    }
    // Image is used as other type of attachment.
    // Aka "render target"
    else if ((usage & (VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
        VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) != 0)
    {
        return 1;
    }
    // Image is accessed by shaders for sampling.
    // Aka "texture"
    else if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
    {
        return 2;
    }
    // Any other type of image.
    // Notice that VK_IMAGE_USAGE_TRANSFER_SRC_BIT and VK_IMAGE_USAGE_TRANSFER_DST_BIT
    // flags are intentionally ignored.
    else
    {
        return 3;
    }
}

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)
{
    m_MemHeapCount = memHeapCount;
    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");

    printf("    Total:\n");
    PrintMemStatInfo(m_PeakMemStats.total);

    for(uint32_t i = 0; i < m_MemHeapCount; ++i)
    {
        const MemStatInfo& info = m_PeakMemStats.memoryHeap[i];
        if(info.blockCount > 0 || info.totalBytes > 0)
        {
            printf("    Heap %u:\n", i);
            PrintMemStatInfo(info);
        }
    }

    for(uint32_t i = 0; i < m_MemTypeCount; ++i)
    {
        const MemStatInfo& info = m_PeakMemStats.memoryType[i];
        if(info.blockCount > 0 || info.totalBytes > 0)
        {
            printf("    Type %u:\n", i);
            PrintMemStatInfo(info);
        }
    }
}

void Statistics::PrintDetailedStats() const
{
    m_VmaPoolCreateInfo.Print();
    m_VmaAllocationCreateInfo.Print();
    m_VmaAllocateMemoryPages.Print();
    m_VkBufferCreateInfo.Print();
    m_VkImageCreateInfo.Print();
    m_VmaDefragmentationInfo2.Print();
}

void Statistics::RegisterFunctionCall(VMA_FUNCTION func)
{
    ++m_FunctionCallCount[(size_t)func];
}

void Statistics::RegisterCreateImage(const VkImageCreateInfo& info)
{
    if(info.tiling == VK_IMAGE_TILING_LINEAR)
        ++m_LinearImageCreationCount;
    else
    {
        const uint32_t imgClass = ImageUsageToClass(info.usage);
        ++m_ImageCreationCount[imgClass];
    }

    m_VkImageCreateInfo.PostValue(info);
}

void Statistics::RegisterCreateBuffer(const VkBufferCreateInfo& info)
{
    const uint32_t bufClass = BufferUsageToClass(info.usage);
    ++m_BufferCreationCount[bufClass];

    m_VkBufferCreateInfo.PostValue(info);
}

void Statistics::RegisterCreatePool(const VmaPoolCreateInfo& info)
{
    m_VmaPoolCreateInfo.PostValue(info);
}

void Statistics::RegisterCreateAllocation(const VmaAllocationCreateInfo& info, size_t allocCount)
{
    m_VmaAllocationCreateInfo.PostValue(info, allocCount);
}

void Statistics::RegisterDefragmentation(const VmaDefragmentationInfo2& info)
{
    m_VmaDefragmentationInfo2.PostValue(info);
}

void Statistics::UpdateMemStats(const VmaStats& currStats)
{
    UpdateMemStatInfo(m_PeakMemStats.total, currStats.total);
    
    for(uint32_t i = 0; i < m_MemHeapCount; ++i)
    {
        UpdateMemStatInfo(m_PeakMemStats.memoryHeap[i], currStats.memoryHeap[i]);
    }

    for(uint32_t i = 0; i < m_MemTypeCount; ++i)
    {
        UpdateMemStatInfo(m_PeakMemStats.memoryType[i], currStats.memoryType[i]);
    }
}

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) \
    if((src) > (inoutDst)) \
    { \
        (inoutDst) = (src); \
    }

    SET_PEAK(inoutPeakInfo.blockCount, currInfo.blockCount);
    SET_PEAK(inoutPeakInfo.allocationCount, currInfo.allocationCount);
    SET_PEAK(inoutPeakInfo.unusedRangeCount, currInfo.unusedRangeCount);
    SET_PEAK(inoutPeakInfo.usedBytes, currInfo.usedBytes);
    SET_PEAK(inoutPeakInfo.unusedBytes, currInfo.unusedBytes);
    SET_PEAK(inoutPeakInfo.totalBytes, currInfo.usedBytes + currInfo.unusedBytes);

#undef SET_PEAK
}

void Statistics::PrintMemStatInfo(const MemStatInfo& info)
{
    printf("        Peak blocks %u, allocations %u, unused ranges %u\n",
        info.blockCount,
        info.allocationCount,
        info.unusedRangeCount);
    printf("        Peak total bytes %llu, used bytes %llu, unused bytes %llu\n",
        info.totalBytes,
        info.usedBytes,
        info.unusedBytes);
}

////////////////////////////////////////////////////////////////////////////////
// class ConfigurationParser

class ConfigurationParser
{
public:
    ConfigurationParser();
    
    bool Parse(LineSplit& lineSplit);

    void Compare(
        const VkPhysicalDeviceProperties& currDevProps,
        const VkPhysicalDeviceMemoryProperties& currMemProps,
        uint32_t vulkanApiVersion,
        bool currMemoryBudgetEnabled);

private:
    enum class OPTION
    {
        VulkanApiVersion,
        PhysicalDevice_apiVersion,
        PhysicalDevice_driverVersion,
        PhysicalDevice_vendorID,
        PhysicalDevice_deviceID,
        PhysicalDevice_deviceType,
        PhysicalDevice_deviceName,
        PhysicalDeviceLimits_maxMemoryAllocationCount,
        PhysicalDeviceLimits_bufferImageGranularity,
        PhysicalDeviceLimits_nonCoherentAtomSize,
        Extension_VK_KHR_dedicated_allocation,
        Extension_VK_KHR_bind_memory2,
        Extension_VK_EXT_memory_budget,
        Extension_VK_AMD_device_coherent_memory,
        Macro_VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,
        Macro_VMA_DEBUG_ALIGNMENT,
        Macro_VMA_DEBUG_MARGIN,
        Macro_VMA_DEBUG_INITIALIZE_ALLOCATIONS,
        Macro_VMA_DEBUG_DETECT_CORRUPTION,
        Macro_VMA_DEBUG_GLOBAL_MUTEX,
        Macro_VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,
        Macro_VMA_SMALL_HEAP_MAX_SIZE,
        Macro_VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE,
        Count
    };

    std::vector<bool> m_OptionSet;
    std::vector<std::string> m_OptionValue;
    VkPhysicalDeviceMemoryProperties m_MemProps;

    bool m_WarningHeaderPrinted = false;

    void SetOption(
        size_t lineNumber,
        OPTION option,
        const StrRange& str);
    void EnsureWarningHeader();
    void CompareOption(VERBOSITY minVerbosity, const char* name,
        OPTION option, uint32_t currValue);
    void CompareOption(VERBOSITY minVerbosity, const char* name,
        OPTION option, uint64_t currValue);
    void CompareOption(VERBOSITY minVerbosity, const char* name,
        OPTION option, bool currValue);
    void CompareOption(VERBOSITY minVerbosity, const char* name,
        OPTION option, const char* currValue);
    void CompareMemProps(
        const VkPhysicalDeviceMemoryProperties& currMemProps);
};

ConfigurationParser::ConfigurationParser() :
    m_OptionSet((size_t)OPTION::Count),
    m_OptionValue((size_t)OPTION::Count)
{
    ZeroMemory(&m_MemProps, sizeof(m_MemProps));
}

bool ConfigurationParser::Parse(LineSplit& lineSplit)
{
    for(auto& it : m_OptionSet)
    {
        it = false;
    }
    for(auto& it : m_OptionValue)
    {
        it.clear();
    }

    StrRange line;

    if(!lineSplit.GetNextLine(line) && !StrRangeEq(line, "Config,Begin"))
    {
        return false;
    }

    CsvSplit csvSplit;
    while(lineSplit.GetNextLine(line))
    {
        if(StrRangeEq(line, "Config,End"))
        {
            break;
        }

        const size_t currLineNumber = lineSplit.GetNextLineIndex();

        csvSplit.Set(line);
        if(csvSplit.GetCount() == 0)
        {
            return false;
        }

        const StrRange optionName = csvSplit.GetRange(0);
        if(StrRangeEq(optionName, "VulkanApiVersion"))
        {
            SetOption(currLineNumber, OPTION::VulkanApiVersion, StrRange{csvSplit.GetRange(1).beg, csvSplit.GetRange(2).end});
        }
        else if(StrRangeEq(optionName, "PhysicalDevice"))
        {
            if(csvSplit.GetCount() >= 3)
            {
                const StrRange subOptionName = csvSplit.GetRange(1);
                if(StrRangeEq(subOptionName, "apiVersion"))
                    SetOption(currLineNumber, OPTION::PhysicalDevice_apiVersion, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "driverVersion"))
                    SetOption(currLineNumber, OPTION::PhysicalDevice_driverVersion, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "vendorID"))
                    SetOption(currLineNumber, OPTION::PhysicalDevice_vendorID, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "deviceID"))
                    SetOption(currLineNumber, OPTION::PhysicalDevice_deviceID, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "deviceType"))
                    SetOption(currLineNumber, OPTION::PhysicalDevice_deviceType, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "deviceName"))
                    SetOption(currLineNumber, OPTION::PhysicalDevice_deviceName, StrRange(csvSplit.GetRange(2).beg, line.end));
                else
                    printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);
            }
            else
                printf("Line %zu: Too few columns.\n", currLineNumber);
        }
        else if(StrRangeEq(optionName, "PhysicalDeviceLimits"))
        {
            if(csvSplit.GetCount() >= 3)
            {
                const StrRange subOptionName = csvSplit.GetRange(1);
                if(StrRangeEq(subOptionName, "maxMemoryAllocationCount"))
                    SetOption(currLineNumber, OPTION::PhysicalDeviceLimits_maxMemoryAllocationCount, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "bufferImageGranularity"))
                    SetOption(currLineNumber, OPTION::PhysicalDeviceLimits_bufferImageGranularity, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "nonCoherentAtomSize"))
                    SetOption(currLineNumber, OPTION::PhysicalDeviceLimits_nonCoherentAtomSize, csvSplit.GetRange(2));
                else
                    printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);
            }
            else
                printf("Line %zu: Too few columns.\n", currLineNumber);
        }
        else if(StrRangeEq(optionName, "Extension"))
        {
            if(csvSplit.GetCount() >= 3)
            {
                const StrRange subOptionName = csvSplit.GetRange(1);
                if(StrRangeEq(subOptionName, "VK_KHR_dedicated_allocation"))
                {
                    // Ignore because this extension is promoted to Vulkan 1.1.
                }
                else if(StrRangeEq(subOptionName, "VK_KHR_bind_memory2"))
                    SetOption(currLineNumber, OPTION::Extension_VK_KHR_bind_memory2, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VK_EXT_memory_budget"))
                    SetOption(currLineNumber, OPTION::Extension_VK_EXT_memory_budget, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VK_AMD_device_coherent_memory"))
                    SetOption(currLineNumber, OPTION::Extension_VK_AMD_device_coherent_memory, csvSplit.GetRange(2));
                else
                    printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);
            }
            else
                printf("Line %zu: Too few columns.\n", currLineNumber);
        }
        else if(StrRangeEq(optionName, "Macro"))
        {
            if(csvSplit.GetCount() >= 3)
            {
                const StrRange subOptionName = csvSplit.GetRange(1);
                if(StrRangeEq(subOptionName, "VMA_DEBUG_ALWAYS_DEDICATED_MEMORY"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_ALWAYS_DEDICATED_MEMORY, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VMA_DEBUG_ALIGNMENT"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_ALIGNMENT, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VMA_DEBUG_MARGIN"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_MARGIN, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VMA_DEBUG_INITIALIZE_ALLOCATIONS"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_INITIALIZE_ALLOCATIONS, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VMA_DEBUG_DETECT_CORRUPTION"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_DETECT_CORRUPTION, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VMA_DEBUG_GLOBAL_MUTEX"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_GLOBAL_MUTEX, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VMA_SMALL_HEAP_MAX_SIZE"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_SMALL_HEAP_MAX_SIZE, csvSplit.GetRange(2));
                else if(StrRangeEq(subOptionName, "VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE, csvSplit.GetRange(2));
                else
                    printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);
            }
            else
                printf("Line %zu: Too few columns.\n", currLineNumber);
        }
        else if(StrRangeEq(optionName, "PhysicalDeviceMemory"))
        {
            uint32_t value = 0;
            if(csvSplit.GetCount() == 3 && StrRangeEq(csvSplit.GetRange(1), "HeapCount") &&
                StrRangeToUint(csvSplit.GetRange(2), value))
            {
                m_MemProps.memoryHeapCount = value;
            }
            else if(csvSplit.GetCount() == 3 && StrRangeEq(csvSplit.GetRange(1), "TypeCount") &&
                StrRangeToUint(csvSplit.GetRange(2), value))
            {
                m_MemProps.memoryTypeCount = value;
            }
            else if(csvSplit.GetCount() == 5 && StrRangeEq(csvSplit.GetRange(1), "Heap") &&
                StrRangeToUint(csvSplit.GetRange(2), value) &&
                value < m_MemProps.memoryHeapCount)
            {
                if(StrRangeEq(csvSplit.GetRange(3), "size") &&
                    StrRangeToUint(csvSplit.GetRange(4), m_MemProps.memoryHeaps[value].size))
                {
                     // Parsed.
                }
                else if(StrRangeEq(csvSplit.GetRange(3), "flags") &&
                    StrRangeToUint(csvSplit.GetRange(4), m_MemProps.memoryHeaps[value].flags))
                {
                     // Parsed.
                }
                else
                    printf("Line %zu: Invalid configuration option.\n", currLineNumber);
            }
            else if(csvSplit.GetCount() == 5 && StrRangeEq(csvSplit.GetRange(1), "Type") &&
                StrRangeToUint(csvSplit.GetRange(2), value) &&
                value < m_MemProps.memoryTypeCount)
            {
                if(StrRangeEq(csvSplit.GetRange(3), "heapIndex") &&
                    StrRangeToUint(csvSplit.GetRange(4), m_MemProps.memoryTypes[value].heapIndex))
                {
                     // Parsed.
                }
                else if(StrRangeEq(csvSplit.GetRange(3), "propertyFlags") &&
                    StrRangeToUint(csvSplit.GetRange(4), m_MemProps.memoryTypes[value].propertyFlags))
                {
                     // Parsed.
                }
                else
                    printf("Line %zu: Invalid configuration option.\n", currLineNumber);
            }
            else
                printf("Line %zu: Invalid configuration option.\n", currLineNumber);
        }
        else
            printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);
    }

    return true;
}

void ConfigurationParser::Compare(
    const VkPhysicalDeviceProperties& currDevProps,
    const VkPhysicalDeviceMemoryProperties& currMemProps,
    uint32_t vulkanApiVersion,
    bool currMemoryBudgetEnabled)
{
    char vulkanApiVersionStr[32];
    sprintf_s(vulkanApiVersionStr, "%u,%u", VK_VERSION_MAJOR(vulkanApiVersion), VK_VERSION_MINOR(vulkanApiVersion));
    CompareOption(VERBOSITY::DEFAULT, "VulkanApiVersion",
        OPTION::VulkanApiVersion, vulkanApiVersionStr);

    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice apiVersion",
        OPTION::PhysicalDevice_apiVersion, currDevProps.apiVersion);
    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice driverVersion",
        OPTION::PhysicalDevice_driverVersion, currDevProps.driverVersion);
    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice vendorID",
        OPTION::PhysicalDevice_vendorID, currDevProps.vendorID);
    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice deviceID",
        OPTION::PhysicalDevice_deviceID, currDevProps.deviceID);
    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice deviceType",
        OPTION::PhysicalDevice_deviceType, (uint32_t)currDevProps.deviceType);
    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice deviceName",
        OPTION::PhysicalDevice_deviceName, currDevProps.deviceName);

    CompareOption(VERBOSITY::DEFAULT, "PhysicalDeviceLimits maxMemoryAllocationCount",
        OPTION::PhysicalDeviceLimits_maxMemoryAllocationCount, currDevProps.limits.maxMemoryAllocationCount);
    CompareOption(VERBOSITY::DEFAULT, "PhysicalDeviceLimits bufferImageGranularity",
        OPTION::PhysicalDeviceLimits_bufferImageGranularity, currDevProps.limits.bufferImageGranularity);
    CompareOption(VERBOSITY::DEFAULT, "PhysicalDeviceLimits nonCoherentAtomSize",
        OPTION::PhysicalDeviceLimits_nonCoherentAtomSize, currDevProps.limits.nonCoherentAtomSize);

    CompareMemProps(currMemProps);
}

void ConfigurationParser::SetOption(
    size_t lineNumber,
    OPTION option,
    const StrRange& str)
{
    if(m_OptionSet[(size_t)option])
    {
        printf("Line %zu: Option already specified.\n" ,lineNumber);
    }

    m_OptionSet[(size_t)option] = true;

    std::string val;
    str.to_str(val);
    m_OptionValue[(size_t)option] = std::move(val);
}

void ConfigurationParser::EnsureWarningHeader()
{
    if(!m_WarningHeaderPrinted)
    {
        printf("WARNING: Following configuration parameters don't match:\n");
        m_WarningHeaderPrinted = true;
    }
}

void ConfigurationParser::CompareOption(VERBOSITY minVerbosity, const char* name,
    OPTION option, uint32_t currValue)
{
    if(m_OptionSet[(size_t)option] &&
        g_Verbosity >= minVerbosity)
    {
        uint32_t origValue;
        if(StrRangeToUint(StrRange(m_OptionValue[(size_t)option]), origValue))
        {
            if(origValue != currValue)
            {
                EnsureWarningHeader();
                printf("    %s: original %u, current %u\n", name, origValue, currValue);
            }
        }
    }
}

void ConfigurationParser::CompareOption(VERBOSITY minVerbosity, const char* name,
    OPTION option, uint64_t currValue)
{
    if(m_OptionSet[(size_t)option] &&
        g_Verbosity >= minVerbosity)
    {
        uint64_t origValue;
        if(StrRangeToUint(StrRange(m_OptionValue[(size_t)option]), origValue))
        {
            if(origValue != currValue)
            {
                EnsureWarningHeader();
                printf("    %s: original %llu, current %llu\n", name, origValue, currValue);
            }
        }
    }
}

void ConfigurationParser::CompareOption(VERBOSITY minVerbosity, const char* name,
    OPTION option, bool currValue)
{
    if(m_OptionSet[(size_t)option] &&
        g_Verbosity >= minVerbosity)
    {
        bool origValue;
        if(StrRangeToBool(StrRange(m_OptionValue[(size_t)option]), origValue))
        {
            if(origValue != currValue)
            {
                EnsureWarningHeader();
                printf("    %s: original %u, current %u\n", name,
                    origValue ? 1 : 0,
                    currValue ? 1 : 0);
            }
        }
    }
}

void ConfigurationParser::CompareOption(VERBOSITY minVerbosity, const char* name,
    OPTION option, const char* currValue)
{
    if(m_OptionSet[(size_t)option] &&
        g_Verbosity >= minVerbosity)
    {
        const std::string& origValue = m_OptionValue[(size_t)option];
        if(origValue != currValue)
        {
            EnsureWarningHeader();
            printf("    %s: original \"%s\", current \"%s\"\n", name, origValue.c_str(), currValue);
        }
    }
}

void ConfigurationParser::CompareMemProps(
    const VkPhysicalDeviceMemoryProperties& currMemProps)
{
    if(g_Verbosity < VERBOSITY::DEFAULT)
    {
        return;
    }

    bool memoryMatch =
        currMemProps.memoryHeapCount == m_MemProps.memoryHeapCount &&
        currMemProps.memoryTypeCount == m_MemProps.memoryTypeCount;

    for(uint32_t i = 0; memoryMatch && i < currMemProps.memoryHeapCount; ++i)
    {
        memoryMatch =
            currMemProps.memoryHeaps[i].flags == m_MemProps.memoryHeaps[i].flags;
    }
    for(uint32_t i = 0; memoryMatch && i < currMemProps.memoryTypeCount; ++i)
    {
        memoryMatch =
            currMemProps.memoryTypes[i].heapIndex == m_MemProps.memoryTypes[i].heapIndex &&
            currMemProps.memoryTypes[i].propertyFlags == m_MemProps.memoryTypes[i].propertyFlags;
    }

    if(memoryMatch && g_Verbosity == VERBOSITY::MAXIMUM)
    {
        bool memorySizeMatch = true;
        for(uint32_t i = 0; memorySizeMatch && i < currMemProps.memoryHeapCount; ++i)
        {
            memorySizeMatch =
                currMemProps.memoryHeaps[i].size == m_MemProps.memoryHeaps[i].size;
        }

        if(!memorySizeMatch)
        {
            printf("WARNING: Sizes of original memory heaps are different from current ones.\n");
        }
    }
    else
    {
        printf("WARNING: Layout of original memory heaps and types is different from current one.\n");
    }
}

////////////////////////////////////////////////////////////////////////////////
// class Player

static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_LUNARG_standard_validation";

static const bool g_MemoryAliasingWarningEnabled = false;

static VKAPI_ATTR VkBool32 VKAPI_CALL MyDebugReportCallback(
    VkDebugReportFlagsEXT flags,
    VkDebugReportObjectTypeEXT objectType,
    uint64_t object,
    size_t location,
    int32_t messageCode,
    const char* pLayerPrefix,
    const char* pMessage,
    void* pUserData)
{
    // "Non-linear image 0xebc91 is aliased with linear buffer 0xeb8e4 which may indicate a bug."
    if(!g_MemoryAliasingWarningEnabled && flags == VK_DEBUG_REPORT_WARNING_BIT_EXT &&
        (strstr(pMessage, " is aliased with non-linear ") || strstr(pMessage, " is aliased with linear ")))
    {
        return VK_FALSE;
    }

    // Ignoring because when VK_KHR_dedicated_allocation extension is enabled,
    // vkGetBufferMemoryRequirements2KHR function is used instead, while Validation
    // Layer seems to be unaware of it.
    if (strstr(pMessage, "but vkGetBufferMemoryRequirements() has not been called on that buffer") != nullptr)
    {
        return VK_FALSE;
    }
    if (strstr(pMessage, "but vkGetImageMemoryRequirements() has not been called on that image") != nullptr)
    {
        return VK_FALSE;
    }
    
    /*
    "Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used."
    Ignoring because we map entire VkDeviceMemory blocks, where different types of
    images and buffers may end up together, especially on GPUs with unified memory
    like Intel.
    */
    if(strstr(pMessage, "Mapping an image with layout") != nullptr &&
        strstr(pMessage, "can result in undefined behavior if this memory is used by the device") != nullptr)
    {
        return VK_FALSE;
    }

    printf("%s \xBA %s\n", pLayerPrefix, pMessage);

    return VK_FALSE;
}

static bool IsLayerSupported(const VkLayerProperties* pProps, size_t propCount, const char* pLayerName)
{
    const VkLayerProperties* propsEnd = pProps + propCount;
    return std::find_if(
        pProps,
        propsEnd,
        [pLayerName](const VkLayerProperties& prop) -> bool {
            return strcmp(pLayerName, prop.layerName) == 0;
        }) != propsEnd;
}

static const size_t FIRST_PARAM_INDEX = 4;

static void InitVulkanFeatures(
    VkPhysicalDeviceFeatures& outFeatures,
    const VkPhysicalDeviceFeatures& supportedFeatures)
{
    ZeroMemory(&outFeatures, sizeof(outFeatures));

    // Enable something what may interact with memory/buffer/image support.

    outFeatures.fullDrawIndexUint32 = supportedFeatures.fullDrawIndexUint32;
    outFeatures.imageCubeArray = supportedFeatures.imageCubeArray;
    outFeatures.geometryShader = supportedFeatures.geometryShader;
    outFeatures.tessellationShader = supportedFeatures.tessellationShader;
    outFeatures.multiDrawIndirect = supportedFeatures.multiDrawIndirect;
    outFeatures.textureCompressionETC2 = supportedFeatures.textureCompressionETC2;
    outFeatures.textureCompressionASTC_LDR = supportedFeatures.textureCompressionASTC_LDR;
    outFeatures.textureCompressionBC = supportedFeatures.textureCompressionBC;
}

class Player
{
public:
    Player();
    int Init();
    ~Player();

    void ApplyConfig(ConfigurationParser& configParser);
    void ExecuteLine(size_t lineNumber, const StrRange& line);
    void DumpStats(const char* fileNameFormat, size_t lineNumber, bool detailed);
    void Defragment();

    void PrintStats();

private:
    static const size_t MAX_WARNINGS_TO_SHOW = 64;

    size_t m_WarningCount = 0;
    bool m_AllocateForBufferImageWarningIssued = false;

    VkInstance m_VulkanInstance = VK_NULL_HANDLE;
    VkPhysicalDevice m_PhysicalDevice = VK_NULL_HANDLE;
    uint32_t m_GraphicsQueueFamilyIndex = UINT32_MAX;
    uint32_t m_TransferQueueFamilyIndex = UINT32_MAX;
    VkDevice m_Device = VK_NULL_HANDLE;
    VkQueue m_GraphicsQueue = VK_NULL_HANDLE;
    VkQueue m_TransferQueue = VK_NULL_HANDLE;
    VmaAllocator m_Allocator = VK_NULL_HANDLE;
    VkCommandPool m_CommandPool = VK_NULL_HANDLE;
    VkCommandBuffer m_CommandBuffer = VK_NULL_HANDLE;
    bool m_MemoryBudgetEnabled = false;
    const VkPhysicalDeviceProperties* m_DevProps = nullptr;
    const VkPhysicalDeviceMemoryProperties* m_MemProps = nullptr;

    PFN_vkCreateDebugReportCallbackEXT m_pvkCreateDebugReportCallbackEXT;
    PFN_vkDebugReportMessageEXT m_pvkDebugReportMessageEXT;
    PFN_vkDestroyDebugReportCallbackEXT m_pvkDestroyDebugReportCallbackEXT;
    VkDebugReportCallbackEXT m_hCallback;

    uint32_t m_VmaFrameIndex = 0;

    // Any of these handles null can mean it was created in original but couldn't be created now.
    struct Pool
    {
        VmaPool pool;
    };
    struct Allocation
    {
        uint32_t allocationFlags = 0;
        VmaAllocation allocation = VK_NULL_HANDLE;
        VkBuffer buffer = VK_NULL_HANDLE;
        VkImage image = VK_NULL_HANDLE;
    };
    std::unordered_map<uint64_t, Pool> m_Pools;
    std::unordered_map<uint64_t, Allocation> m_Allocations;
    std::unordered_map<uint64_t, VmaDefragmentationContext> m_DefragmentationContexts;

    struct Thread
    {
        uint32_t callCount;
    };
    std::unordered_map<uint32_t, Thread> m_Threads;

    // Copy of column [1] from previously parsed line.
    std::string m_LastLineTimeStr;
    Statistics m_Stats;

    std::vector<char> m_UserDataTmpStr;

    void Destroy(const Allocation& alloc);

    // Finds VmaPool bu original pointer.
    // If origPool = null, returns true and outPool = null.
    // If failed, prints warning, returns false and outPool = null.
    bool FindPool(size_t lineNumber, uint64_t origPool, VmaPool& outPool);
    // If allocation with that origPtr already exists, prints warning and replaces it.
    void AddAllocation(size_t lineNumber, uint64_t origPtr, VkResult res, const char* functionName, Allocation&& allocDesc);

    // Increments warning counter. Returns true if warning message should be printed.
    bool IssueWarning();

    int InitVulkan();
    void FinalizeVulkan();
    void RegisterDebugCallbacks();

    // If parmeter count doesn't match, issues warning and returns false.
    bool ValidateFunctionParameterCount(size_t lineNumber, const CsvSplit& csvSplit, size_t expectedParamCount, bool lastUnbound);

    // If failed, prints warning, returns false, and sets allocCreateInfo.pUserData to null.
    bool PrepareUserData(size_t lineNumber, uint32_t allocCreateFlags, const StrRange& userDataColumn, const StrRange& wholeLine, void*& outUserData);

    void UpdateMemStats();

    void ExecuteCreatePool(size_t lineNumber, const CsvSplit& csvSplit);
    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, "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, "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);
    void ExecuteFlushAllocation(size_t lineNumber, const CsvSplit& csvSplit);
    void ExecuteInvalidateAllocation(size_t lineNumber, const CsvSplit& csvSplit);
    void ExecuteTouchAllocation(size_t lineNumber, const CsvSplit& csvSplit);
    void ExecuteGetAllocationInfo(size_t lineNumber, const CsvSplit& csvSplit);
    void ExecuteMakePoolAllocationsLost(size_t lineNumber, const CsvSplit& csvSplit);
    void ExecuteResizeAllocation(size_t lineNumber, const CsvSplit& csvSplit);
    void ExecuteDefragmentationBegin(size_t lineNumber, const CsvSplit& csvSplit);
    void ExecuteDefragmentationEnd(size_t lineNumber, const CsvSplit& csvSplit);
    void ExecuteSetPoolName(size_t lineNumber, const CsvSplit& csvSplit);

    void DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit, const char* functionName);

    void PrintStats(const VmaStats& stats, const char* suffix);
    void PrintStatInfo(const VmaStatInfo& info);
};

Player::Player()
{
}

int Player::Init()
{
    int result = InitVulkan();
    
    if(result == 0)
    {
        m_Stats.Init(m_MemProps->memoryHeapCount, m_MemProps->memoryTypeCount);
        UpdateMemStats();
    }
    
    return result;
}

Player::~Player()
{
    FinalizeVulkan();

    if(g_Verbosity < VERBOSITY::MAXIMUM && m_WarningCount > MAX_WARNINGS_TO_SHOW)
        printf("WARNING: %zu more warnings not shown.\n", m_WarningCount - MAX_WARNINGS_TO_SHOW);
}

void Player::ApplyConfig(ConfigurationParser& configParser)
{
    configParser.Compare(*m_DevProps, *m_MemProps,
        VULKAN_API_VERSION,
        m_MemoryBudgetEnabled);
}

void Player::ExecuteLine(size_t lineNumber, const StrRange& line)
{
    CsvSplit csvSplit;
    csvSplit.Set(line);

    if(csvSplit.GetCount() >= FIRST_PARAM_INDEX)
    {
        // Check thread ID.
        uint32_t threadId;
        if(StrRangeToUint(csvSplit.GetRange(0), threadId))
        {
            const auto it = m_Threads.find(threadId);
            if(it != m_Threads.end())
            {
                ++it->second.callCount;
            }
            else
            {
                Thread threadInfo{};
                threadInfo.callCount = 1;
                m_Threads[threadId] = threadInfo;
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Incorrect thread ID.\n", lineNumber);
            }
        }

        // Save time.
        csvSplit.GetRange(1).to_str(m_LastLineTimeStr);

        // Update VMA current frame index.
        StrRange frameIndexStr = csvSplit.GetRange(2);
        uint32_t frameIndex;
        if(StrRangeToUint(frameIndexStr, frameIndex))
        {
            if(frameIndex != m_VmaFrameIndex)
            {
                vmaSetCurrentFrameIndex(m_Allocator, frameIndex);
                m_VmaFrameIndex = frameIndex;
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Incorrect frame index.\n", lineNumber);
            }
        }

        StrRange functionName = csvSplit.GetRange(3);

        if(StrRangeEq(functionName, "vmaCreateAllocator"))
        {
            if(ValidateFunctionParameterCount(lineNumber, csvSplit, 0, false))
            {
                // Nothing.
            }
        }
        else if(StrRangeEq(functionName, "vmaDestroyAllocator"))
        {
            if(ValidateFunctionParameterCount(lineNumber, csvSplit, 0, false))
            {
                // Nothing.
            }
        }
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreatePool]))
            ExecuteCreatePool(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyPool]))
            ExecuteDestroyPool(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::SetAllocationUserData]))
            ExecuteSetAllocationUserData(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreateBuffer]))
            ExecuteCreateBuffer(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyBuffer]))
            ExecuteDestroyBuffer(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreateImage]))
            ExecuteCreateImage(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyImage]))
            ExecuteDestroyImage(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::FreeMemory]))
            ExecuteFreeMemory(lineNumber, csvSplit);
        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, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemory]))
            ExecuteAllocateMemory(lineNumber, csvSplit);
        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, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemoryForImage]))
            ExecuteAllocateMemoryForBufferOrImage(lineNumber, csvSplit, OBJECT_TYPE::IMAGE);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::MapMemory]))
            ExecuteMapMemory(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::UnmapMemory]))
            ExecuteUnmapMemory(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::FlushAllocation]))
            ExecuteFlushAllocation(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::InvalidateAllocation]))
            ExecuteInvalidateAllocation(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::TouchAllocation]))
            ExecuteTouchAllocation(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::GetAllocationInfo]))
            ExecuteGetAllocationInfo(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::MakePoolAllocationsLost]))
            ExecuteMakePoolAllocationsLost(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::ResizeAllocation]))
            ExecuteResizeAllocation(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DefragmentationBegin]))
            ExecuteDefragmentationBegin(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DefragmentationEnd]))
            ExecuteDefragmentationEnd(lineNumber, csvSplit);
        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::SetPoolName]))
            ExecuteSetPoolName(lineNumber, csvSplit);
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Unknown function.\n", lineNumber);
            }
        }
    }
    else
    {
        if(IssueWarning())
        {
            printf("Line %zu: Too few columns.\n", lineNumber);
        }
    }
}

void Player::DumpStats(const char* fileNameFormat, size_t lineNumber, bool detailed)
{
    char* pStatsString = nullptr;
    vmaBuildStatsString(m_Allocator, &pStatsString, detailed ? VK_TRUE : VK_FALSE);

    char fileName[MAX_PATH];
    sprintf_s(fileName, fileNameFormat, lineNumber);

    FILE* file = nullptr;
    errno_t err = fopen_s(&file, fileName, "wb");
    if(err == 0)
    {
        fwrite(pStatsString, 1, strlen(pStatsString), file);
        fclose(file);
    }
    else
    {
        printf("ERROR: Failed to write file: %s\n", fileName);
    }

    vmaFreeStatsString(m_Allocator, pStatsString);
}

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);
}

bool Player::FindPool(size_t lineNumber, uint64_t origPool, VmaPool& outPool)
{
    outPool = VK_NULL_HANDLE;

    if(origPool != 0)
    {
        const auto poolIt = m_Pools.find(origPool);
        if(poolIt != m_Pools.end())
        {
            outPool = poolIt->second.pool;
            return true;
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Pool %llX not found.\n", lineNumber, origPool);
            }
        }
    }

    return true;
}

void Player::AddAllocation(size_t lineNumber, uint64_t origPtr, VkResult res, const char* functionName, Allocation&& allocDesc)
{
    if(origPtr)
    {
        if(res == VK_SUCCESS)
        {
            // Originally succeeded, currently succeeded.
            // Just save pointer (done below).
        }
        else
        {
            // Originally succeeded, currently failed.
            // Print warning. Save null pointer.
            if(IssueWarning())
            {
                printf("Line %zu: %s failed (%d), while originally succeeded.\n", lineNumber, functionName, res);
            }
        }

        const auto existingIt = m_Allocations.find(origPtr);
        if(existingIt != m_Allocations.end())
        {
            if(IssueWarning())
            {
                printf("Line %zu: Allocation %llX already exists.\n", lineNumber, origPtr);
            }
        }
        m_Allocations[origPtr] = std::move(allocDesc);
    }
    else
    {
        if(res == VK_SUCCESS)
        {
            // Originally failed, currently succeeded.
            // Print warning, destroy the object.
            if(IssueWarning())
            {
                printf("Line %zu: %s succeeded, originally failed.\n", lineNumber, functionName);
            }

            Destroy(allocDesc);
        }
        else
        {
            // Originally failed, currently failed.
            // Print warning.
            if(IssueWarning())
            {
                printf("Line %zu: %s failed (%d), originally also failed.\n", lineNumber, functionName, res);
            }
        }
    }
}

bool Player::IssueWarning()
{
    if(g_Verbosity < VERBOSITY::MAXIMUM)
    {
        return m_WarningCount++ < MAX_WARNINGS_TO_SHOW;
    }
    else
    {
        ++m_WarningCount;
        return true;
    }
}

int Player::InitVulkan()
{
    if(g_Verbosity == VERBOSITY::MAXIMUM)
    {
        printf("Initializing Vulkan...\n");
    }

    uint32_t instanceLayerPropCount = 0;
    VkResult res = vkEnumerateInstanceLayerProperties(&instanceLayerPropCount, nullptr);
    assert(res == VK_SUCCESS);

    std::vector<VkLayerProperties> instanceLayerProps(instanceLayerPropCount);
    if(instanceLayerPropCount > 0)
    {
        res = vkEnumerateInstanceLayerProperties(&instanceLayerPropCount, instanceLayerProps.data());
        assert(res == VK_SUCCESS);
    }

    const bool validationLayersAvailable =
        IsLayerSupported(instanceLayerProps.data(), instanceLayerProps.size(), VALIDATION_LAYER_NAME);

    bool validationLayersEnabled = false;
    switch(g_VK_LAYER_LUNARG_standard_validation)
    {
    case VULKAN_EXTENSION_REQUEST::DISABLED:
        break;
    case VULKAN_EXTENSION_REQUEST::DEFAULT:
        validationLayersEnabled = validationLayersAvailable;
        break;
    case VULKAN_EXTENSION_REQUEST::ENABLED:
        validationLayersEnabled = validationLayersAvailable;
        if(!validationLayersAvailable)
        {
            printf("WARNING: %s layer cannot be enabled.\n", VALIDATION_LAYER_NAME);
        }
        break;
    default: assert(0);
    }

    uint32_t availableInstanceExtensionCount = 0;
    res = vkEnumerateInstanceExtensionProperties(nullptr, &availableInstanceExtensionCount, nullptr);
    assert(res == VK_SUCCESS);
    std::vector<VkExtensionProperties> availableInstanceExtensions(availableInstanceExtensionCount);
    if(availableInstanceExtensionCount > 0)
    {
        res = vkEnumerateInstanceExtensionProperties(nullptr, &availableInstanceExtensionCount, availableInstanceExtensions.data());
        assert(res == VK_SUCCESS);
    }

    std::vector<const char*> enabledInstanceExtensions;
    //enabledInstanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
    //enabledInstanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);

    std::vector<const char*> instanceLayers;
    if(validationLayersEnabled)
    {
        instanceLayers.push_back(VALIDATION_LAYER_NAME);
        enabledInstanceExtensions.push_back("VK_EXT_debug_report");
    }

    bool VK_KHR_get_physical_device_properties2_enabled = false;
    for(const auto& extensionProperties : availableInstanceExtensions)
    {
        if(strcmp(extensionProperties.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0)
        {
            enabledInstanceExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
            VK_KHR_get_physical_device_properties2_enabled = true;
        }
    }

    VkApplicationInfo appInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
    appInfo.pApplicationName = "VmaReplay";
    appInfo.applicationVersion = VK_MAKE_VERSION(2, 3, 0);
    appInfo.pEngineName = "Vulkan Memory Allocator";
    appInfo.engineVersion = VK_MAKE_VERSION(2, 3, 0);
    appInfo.apiVersion = VULKAN_API_VERSION;

    VkInstanceCreateInfo instInfo = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
    instInfo.pApplicationInfo = &appInfo;
    instInfo.enabledExtensionCount = (uint32_t)enabledInstanceExtensions.size();
    instInfo.ppEnabledExtensionNames = enabledInstanceExtensions.data();
    instInfo.enabledLayerCount = (uint32_t)instanceLayers.size();
    instInfo.ppEnabledLayerNames = instanceLayers.data();

    res = vkCreateInstance(&instInfo, NULL, &m_VulkanInstance);
    if(res != VK_SUCCESS)
    {
        printf("ERROR: vkCreateInstance failed (%d)\n", res);
        return RESULT_ERROR_VULKAN;
    }

    if(validationLayersEnabled)
    {
        RegisterDebugCallbacks();
    }

    // Find physical device

    uint32_t physicalDeviceCount = 0;
    res = vkEnumeratePhysicalDevices(m_VulkanInstance, &physicalDeviceCount, nullptr);
    assert(res == VK_SUCCESS);
    if(physicalDeviceCount == 0)
    {
        printf("ERROR: No Vulkan physical devices found.\n");
        return RESULT_ERROR_VULKAN;
    }

    std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
    res = vkEnumeratePhysicalDevices(m_VulkanInstance, &physicalDeviceCount, physicalDevices.data());
    assert(res == VK_SUCCESS);

    if(g_PhysicalDeviceIndex >= physicalDeviceCount)
    {
        printf("ERROR: Incorrect Vulkan physical device index %u. System has %u physical devices.\n",
            g_PhysicalDeviceIndex,
            physicalDeviceCount);
        return RESULT_ERROR_VULKAN;
    }

    m_PhysicalDevice = physicalDevices[0];

    // Find queue family index

    uint32_t queueFamilyCount = 0;
    vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDevice, &queueFamilyCount, nullptr);
    if(queueFamilyCount)
    {
        std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
        vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDevice, &queueFamilyCount, queueFamilies.data());
        for(uint32_t i = 0; i < queueFamilyCount; ++i)
        {
            if(queueFamilies[i].queueCount > 0)
            {
                if(m_GraphicsQueueFamilyIndex == UINT32_MAX &&
                    (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
                {
                    m_GraphicsQueueFamilyIndex = i;
                }
                if(m_TransferQueueFamilyIndex == UINT32_MAX &&
                    (queueFamilies[i].queueFlags & VK_QUEUE_TRANSFER_BIT) != 0)
                {
                    m_TransferQueueFamilyIndex = i;
                }
            }
        }
    }
    if(m_GraphicsQueueFamilyIndex == UINT_MAX)
    {
        printf("ERROR: Couldn't find graphics queue.\n");
        return RESULT_ERROR_VULKAN;
    }
    if(m_TransferQueueFamilyIndex == UINT_MAX)
    {
        printf("ERROR: Couldn't find transfer queue.\n");
        return RESULT_ERROR_VULKAN;
    }

    VkPhysicalDeviceFeatures supportedFeatures;
    vkGetPhysicalDeviceFeatures(m_PhysicalDevice, &supportedFeatures);

    // Create logical device

    const float queuePriority = 1.f;

    VkDeviceQueueCreateInfo deviceQueueCreateInfo[2] = {};
    deviceQueueCreateInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    deviceQueueCreateInfo[0].queueFamilyIndex = m_GraphicsQueueFamilyIndex;
    deviceQueueCreateInfo[0].queueCount = 1;
    deviceQueueCreateInfo[0].pQueuePriorities = &queuePriority;

    if(m_TransferQueueFamilyIndex != m_GraphicsQueueFamilyIndex)
    {
        deviceQueueCreateInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        deviceQueueCreateInfo[1].queueFamilyIndex = m_TransferQueueFamilyIndex;
        deviceQueueCreateInfo[1].queueCount = 1;
        deviceQueueCreateInfo[1].pQueuePriorities = &queuePriority;
    }

    // Enable something what may interact with memory/buffer/image support.
    VkPhysicalDeviceFeatures enabledFeatures;
    InitVulkanFeatures(enabledFeatures, supportedFeatures);

    bool VK_KHR_get_memory_requirements2_available = false;

    // Determine list of device extensions to enable.
    std::vector<const char*> enabledDeviceExtensions;
    //enabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
    bool memoryBudgetAvailable = false;
    {
        uint32_t propertyCount = 0;
        res = vkEnumerateDeviceExtensionProperties(m_PhysicalDevice, nullptr, &propertyCount, nullptr);
        assert(res == VK_SUCCESS);

        if(propertyCount)
        {
            std::vector<VkExtensionProperties> properties{propertyCount};
            res = vkEnumerateDeviceExtensionProperties(m_PhysicalDevice, nullptr, &propertyCount, properties.data());
            assert(res == VK_SUCCESS);

            for(uint32_t i = 0; i < propertyCount; ++i)
            {
                if(strcmp(properties[i].extensionName, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME) == 0)
                {
                    VK_KHR_get_memory_requirements2_available = true;
                }
                else if(strcmp(properties[i].extensionName, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME) == 0)
                {
                    if(VK_KHR_get_physical_device_properties2_enabled)
                    {
                        memoryBudgetAvailable = true;
                    }
                }
            }
        }
    }

    switch(g_VK_EXT_memory_budget_request)
    {
    case VULKAN_EXTENSION_REQUEST::DISABLED:
        break;
    case VULKAN_EXTENSION_REQUEST::DEFAULT:
        m_MemoryBudgetEnabled = memoryBudgetAvailable;
        break;
    case VULKAN_EXTENSION_REQUEST::ENABLED:
        m_MemoryBudgetEnabled = memoryBudgetAvailable;
        if(!memoryBudgetAvailable)
        {
            printf("WARNING: VK_EXT_memory_budget extension cannot be enabled.\n");
        }
        break;
    default: assert(0);
    }

    if(g_VK_AMD_device_coherent_memory_request == VULKAN_EXTENSION_REQUEST::ENABLED)
    {
        printf("WARNING: AMD_device_coherent_memory requested but not currently supported by the player.\n");
    }

    if(m_MemoryBudgetEnabled)
    {
        enabledDeviceExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
    }

    VkDeviceCreateInfo deviceCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
    deviceCreateInfo.enabledExtensionCount = (uint32_t)enabledDeviceExtensions.size();
    deviceCreateInfo.ppEnabledExtensionNames = !enabledDeviceExtensions.empty() ? enabledDeviceExtensions.data() : nullptr;
    deviceCreateInfo.queueCreateInfoCount = m_TransferQueueFamilyIndex != m_GraphicsQueueFamilyIndex ? 2 : 1;
    deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfo;
    deviceCreateInfo.pEnabledFeatures = &enabledFeatures;

    res = vkCreateDevice(m_PhysicalDevice, &deviceCreateInfo, nullptr, &m_Device);
    if(res != VK_SUCCESS)
    {
        printf("ERROR: vkCreateDevice failed (%d)\n", res);
        return RESULT_ERROR_VULKAN;
    }

    // Fetch queues
    vkGetDeviceQueue(m_Device, m_GraphicsQueueFamilyIndex, 0, &m_GraphicsQueue);
    vkGetDeviceQueue(m_Device, m_TransferQueueFamilyIndex, 0, &m_TransferQueue);

    // Create memory allocator

    VmaDeviceMemoryCallbacks deviceMemoryCallbacks = {};
    deviceMemoryCallbacks.pfnAllocate = AllocateDeviceMemoryCallback;
    deviceMemoryCallbacks.pfnFree = FreeDeviceMemoryCallback;

    VmaAllocatorCreateInfo allocatorInfo = {};
    allocatorInfo.instance = m_VulkanInstance;
    allocatorInfo.physicalDevice = m_PhysicalDevice;
    allocatorInfo.device = m_Device;
    allocatorInfo.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
    allocatorInfo.pDeviceMemoryCallbacks = &deviceMemoryCallbacks;
    allocatorInfo.vulkanApiVersion = VULKAN_API_VERSION;

    if(m_MemoryBudgetEnabled)
    {
        allocatorInfo.flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT;
    }

    res = vmaCreateAllocator(&allocatorInfo, &m_Allocator);
    if(res != VK_SUCCESS)
    {
        printf("ERROR: vmaCreateAllocator failed (%d)\n", res);
        return RESULT_ERROR_VULKAN;
    }

    vmaGetPhysicalDeviceProperties(m_Allocator, &m_DevProps);
    vmaGetMemoryProperties(m_Allocator, &m_MemProps);

    // Create command pool

    VkCommandPoolCreateInfo cmdPoolCreateInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO };
    cmdPoolCreateInfo.queueFamilyIndex = m_TransferQueueFamilyIndex;
    cmdPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;

    res = vkCreateCommandPool(m_Device, &cmdPoolCreateInfo, nullptr, &m_CommandPool);
    if(res != VK_SUCCESS)
    {
        printf("ERROR: vkCreateCommandPool failed (%d)\n", res);
        return RESULT_ERROR_VULKAN;
    }

    // Create command buffer

    VkCommandBufferAllocateInfo cmdBufAllocInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
    cmdBufAllocInfo.commandBufferCount = 1;
    cmdBufAllocInfo.commandPool = m_CommandPool;
    cmdBufAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
    res = vkAllocateCommandBuffers(m_Device, &cmdBufAllocInfo, &m_CommandBuffer);
    if(res != VK_SUCCESS)
    {
        printf("ERROR: vkAllocateCommandBuffers failed (%d)\n", res);
        return RESULT_ERROR_VULKAN;
    }

    return 0;
}

void Player::FinalizeVulkan()
{
    if(!m_DefragmentationContexts.empty())
    {
        printf("WARNING: Defragmentation contexts not destroyed: %zu.\n", m_DefragmentationContexts.size());

        if(CLEANUP_LEAKED_OBJECTS)
        {
            for(const auto& it : m_DefragmentationContexts)
            {
                vmaDefragmentationEnd(m_Allocator, it.second);
            }
        }

        m_DefragmentationContexts.clear();
    }

    if(!m_Allocations.empty())
    {
        printf("WARNING: Allocations not destroyed: %zu.\n", m_Allocations.size());

        if(CLEANUP_LEAKED_OBJECTS)
        {
            for(const auto it : m_Allocations)
            {
                Destroy(it.second);
            }
        }

        m_Allocations.clear();
    }

    if(!m_Pools.empty())
    {
        printf("WARNING: Custom pools not destroyed: %zu.\n", m_Pools.size());

        if(CLEANUP_LEAKED_OBJECTS)
        {
            for(const auto it : m_Pools)
            {
                vmaDestroyPool(m_Allocator, it.second.pool);
            }
        }

        m_Pools.clear();
    }

    vkDeviceWaitIdle(m_Device);

    if(m_CommandBuffer != VK_NULL_HANDLE)
    {
        vkFreeCommandBuffers(m_Device, m_CommandPool, 1, &m_CommandBuffer);
        m_CommandBuffer = VK_NULL_HANDLE;
    }

    if(m_CommandPool != VK_NULL_HANDLE)
    {
        vkDestroyCommandPool(m_Device, m_CommandPool, nullptr);
        m_CommandPool = VK_NULL_HANDLE;
    }

    if(m_Allocator != VK_NULL_HANDLE)
    {
        vmaDestroyAllocator(m_Allocator);
        m_Allocator = nullptr;
    }

    if(m_Device != VK_NULL_HANDLE)
    {
        vkDestroyDevice(m_Device, nullptr);
        m_Device = nullptr;
    }

    if(m_pvkDestroyDebugReportCallbackEXT && m_hCallback != VK_NULL_HANDLE)
    {
        m_pvkDestroyDebugReportCallbackEXT(m_VulkanInstance, m_hCallback, nullptr);
        m_hCallback = VK_NULL_HANDLE;
    }

    if(m_VulkanInstance != VK_NULL_HANDLE)
    {
        vkDestroyInstance(m_VulkanInstance, NULL);
        m_VulkanInstance = VK_NULL_HANDLE;
    }
}

void Player::RegisterDebugCallbacks()
{
    m_pvkCreateDebugReportCallbackEXT =
        reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>
            (vkGetInstanceProcAddr(m_VulkanInstance, "vkCreateDebugReportCallbackEXT"));
    m_pvkDebugReportMessageEXT =
        reinterpret_cast<PFN_vkDebugReportMessageEXT>
            (vkGetInstanceProcAddr(m_VulkanInstance, "vkDebugReportMessageEXT"));
    m_pvkDestroyDebugReportCallbackEXT =
        reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>
            (vkGetInstanceProcAddr(m_VulkanInstance, "vkDestroyDebugReportCallbackEXT"));
    assert(m_pvkCreateDebugReportCallbackEXT);
    assert(m_pvkDebugReportMessageEXT);
    assert(m_pvkDestroyDebugReportCallbackEXT);

    VkDebugReportCallbackCreateInfoEXT callbackCreateInfo = { VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT };
    callbackCreateInfo.flags = //VK_DEBUG_REPORT_INFORMATION_BIT_EXT |
        VK_DEBUG_REPORT_ERROR_BIT_EXT |
        VK_DEBUG_REPORT_WARNING_BIT_EXT |
        VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT /*|
        VK_DEBUG_REPORT_DEBUG_BIT_EXT*/;
    callbackCreateInfo.pfnCallback = &MyDebugReportCallback;

    VkResult res = m_pvkCreateDebugReportCallbackEXT(m_VulkanInstance, &callbackCreateInfo, nullptr, &m_hCallback);
    assert(res == VK_SUCCESS);
}

void Player::Defragment()
{
    VmaStats stats;
    vmaCalculateStats(m_Allocator, &stats);
    PrintStats(stats, "before defragmentation");

    const size_t allocCount = m_Allocations.size();
    std::vector<VmaAllocation> allocations(allocCount);
    size_t notNullAllocCount = 0;
    for(const auto& it : m_Allocations)
    {
        if(it.second.allocation != VK_NULL_HANDLE)
        {
            allocations[notNullAllocCount] = it.second.allocation;
            ++notNullAllocCount;
        }
    }
    if(notNullAllocCount == 0)
    {
        printf("    Nothing to defragment.\n");
        return;
    }

    allocations.resize(notNullAllocCount);
    std::vector<VkBool32> allocationsChanged(notNullAllocCount);

    VmaDefragmentationStats defragStats = {};

    VkCommandBufferBeginInfo cmdBufBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
    cmdBufBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
    VkResult res = vkBeginCommandBuffer(m_CommandBuffer, &cmdBufBeginInfo);
    if(res != VK_SUCCESS)
    {
        printf("ERROR: vkBeginCommandBuffer failed (%d)\n", res);
        return;
    }

    const time_point timeBeg = std::chrono::high_resolution_clock::now();

    VmaDefragmentationInfo2 defragInfo = {};
    defragInfo.allocationCount = (uint32_t)notNullAllocCount;
    defragInfo.pAllocations = allocations.data();
    defragInfo.pAllocationsChanged = allocationsChanged.data();
    defragInfo.maxCpuAllocationsToMove = UINT32_MAX;
    defragInfo.maxCpuBytesToMove = VK_WHOLE_SIZE;
    defragInfo.maxGpuAllocationsToMove = UINT32_MAX;
    defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE;
    defragInfo.flags = g_DefragmentationFlags;
    defragInfo.commandBuffer = m_CommandBuffer;

    VmaDefragmentationContext defragCtx = VK_NULL_HANDLE;
    res = vmaDefragmentationBegin(m_Allocator, &defragInfo, &defragStats, &defragCtx);
    
    const time_point timeAfterDefragBegin = std::chrono::high_resolution_clock::now();

    vkEndCommandBuffer(m_CommandBuffer);

    if(res >= VK_SUCCESS)
    {
        VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
        submitInfo.commandBufferCount = 1;
        submitInfo.pCommandBuffers = &m_CommandBuffer;
        vkQueueSubmit(m_TransferQueue, 1, &submitInfo, VK_NULL_HANDLE);
        vkQueueWaitIdle(m_TransferQueue);

        const time_point timeAfterGpu = std::chrono::high_resolution_clock::now();

        vmaDefragmentationEnd(m_Allocator, defragCtx);

        const time_point timeAfterDefragEnd = std::chrono::high_resolution_clock::now();

        const duration defragDurationBegin = timeAfterDefragBegin - timeBeg;
        const duration defragDurationGpu   = timeAfterGpu - timeAfterDefragBegin;
        const duration defragDurationEnd   = timeAfterDefragEnd - timeAfterGpu;

        // If anything changed.
        if(defragStats.allocationsMoved > 0)
        {
            // Go over allocation that changed and destroy their buffers and images.
            size_t i = 0;
            for(auto& it : m_Allocations)
            {
                if(allocationsChanged[i] != VK_FALSE)
                {
                    if(it.second.buffer != VK_NULL_HANDLE)
                    {
                        vkDestroyBuffer(m_Device, it.second.buffer, nullptr);
                        it.second.buffer = VK_NULL_HANDLE;
                    }
                    if(it.second.image != VK_NULL_HANDLE)
                    {
                        vkDestroyImage(m_Device, it.second.image, nullptr);
                        it.second.image = VK_NULL_HANDLE;
                    }
                }
                ++i;
            }
        }

        // Print statistics
        std::string defragDurationBeginStr;
        std::string defragDurationGpuStr;
        std::string defragDurationEndStr;
        SecondsToFriendlyStr(ToFloatSeconds(defragDurationBegin), defragDurationBeginStr);
        SecondsToFriendlyStr(ToFloatSeconds(defragDurationGpu), defragDurationGpuStr);
        SecondsToFriendlyStr(ToFloatSeconds(defragDurationEnd), defragDurationEndStr);

        printf("    Defragmentation took:\n");
        printf("        vmaDefragmentationBegin: %s\n", defragDurationBeginStr.c_str());
        printf("        GPU: %s\n", defragDurationGpuStr.c_str());
        printf("        vmaDefragmentationEnd: %s\n", defragDurationEndStr.c_str());
        printf("    VmaDefragmentationStats:\n");
        printf("        bytesMoved: %llu\n", defragStats.bytesMoved);
        printf("        bytesFreed: %llu\n", defragStats.bytesFreed);
        printf("        allocationsMoved: %u\n", defragStats.allocationsMoved);
        printf("        deviceMemoryBlocksFreed: %u\n", defragStats.deviceMemoryBlocksFreed);

        vmaCalculateStats(m_Allocator, &stats);
        PrintStats(stats, "after defragmentation");
    }
    else
    {
        printf("vmaDefragmentationBegin failed (%d).\n", res);
    }

    vkResetCommandPool(m_Device, m_CommandPool, 0);
}

void Player::PrintStats()
{
    if(g_Verbosity == VERBOSITY::MINIMUM)
    {
        return;
    }

    m_Stats.PrintDeviceMemStats();

    printf("Statistics:\n");
    if(m_Stats.GetAllocationCreationCount() > 0)
    {
        printf("    Total allocations created: %zu\n", m_Stats.GetAllocationCreationCount());
    }

    // Buffers
    if(m_Stats.GetBufferCreationCount())
    {
        printf("    Total buffers created: %zu\n", m_Stats.GetBufferCreationCount());
        if(g_Verbosity == VERBOSITY::MAXIMUM)
        {
            printf("        Class 0 (indirect/vertex/index): %zu\n", m_Stats.GetBufferCreationCount(0));
            printf("        Class 1 (storage): %zu\n", m_Stats.GetBufferCreationCount(1));
            printf("        Class 2 (uniform): %zu\n", m_Stats.GetBufferCreationCount(2));
            printf("        Class 3 (other): %zu\n", m_Stats.GetBufferCreationCount(3));
        }
    }
    
    // Images
    const size_t imageCreationCount =
        m_Stats.GetImageCreationCount(0) +
        m_Stats.GetImageCreationCount(1) +
        m_Stats.GetImageCreationCount(2) +
        m_Stats.GetImageCreationCount(3) +
        m_Stats.GetLinearImageCreationCount();
    if(imageCreationCount > 0)
    {
        printf("    Total images created: %zu\n", imageCreationCount);
        if(g_Verbosity == VERBOSITY::MAXIMUM)
        {
            printf("        Class 0 (depth/stencil): %zu\n", m_Stats.GetImageCreationCount(0));
            printf("        Class 1 (attachment): %zu\n", m_Stats.GetImageCreationCount(1));
            printf("        Class 2 (sampled): %zu\n", m_Stats.GetImageCreationCount(2));
            printf("        Class 3 (other): %zu\n", m_Stats.GetImageCreationCount(3));
            if(m_Stats.GetLinearImageCreationCount() > 0)
            {
                printf("        LINEAR tiling: %zu\n", m_Stats.GetLinearImageCreationCount());
            }
        }
    }
    
    if(m_Stats.GetPoolCreationCount() > 0)
    {
        printf("    Total custom pools created: %zu\n", m_Stats.GetPoolCreationCount());
    }

    float lastTime;
    if(!m_LastLineTimeStr.empty() && StrRangeToFloat(StrRange(m_LastLineTimeStr), lastTime))
    {
        std::string origTimeStr;
        SecondsToFriendlyStr(lastTime, origTimeStr);
        printf("    Original recording time: %s\n", origTimeStr.c_str());
    }

    // Thread statistics.
    const size_t threadCount = m_Threads.size();
    if(threadCount > 1)
    {
        uint32_t threadCallCountMax = 0;
        uint32_t threadCallCountSum = 0;
        for(const auto& it : m_Threads)
        {
            threadCallCountMax = std::max(threadCallCountMax, it.second.callCount);
            threadCallCountSum += it.second.callCount;
        }
        printf("    Threads making calls to VMA: %zu\n", threadCount);
        printf("        %.2f%% calls from most active thread.\n",
            (float)threadCallCountMax * 100.f / (float)threadCallCountSum);
    }
    else
    {
        printf("    VMA used from only one thread.\n");
    }

    // Function call count
    if(g_Verbosity == VERBOSITY::MAXIMUM)
    {
        printf("    Function call count:\n");
        const size_t* const functionCallCount = m_Stats.GetFunctionCallCount();
        for(size_t i = 0; i < (size_t)VMA_FUNCTION::Count; ++i)
        {
            if(functionCallCount[i] > 0)
            {
                printf("        %s %zu\n", VMA_FUNCTION_NAMES[i], functionCallCount[i]);
            }
        }
    }

    // Detailed stats
    if(g_Verbosity == VERBOSITY::MAXIMUM)
    {
        m_Stats.PrintDetailedStats();
    }

    if(g_MemStatsEnabled)
    {
        m_Stats.PrintMemStats();
    }
}

bool Player::ValidateFunctionParameterCount(size_t lineNumber, const CsvSplit& csvSplit, size_t expectedParamCount, bool lastUnbound)
{
    bool ok;
    if(lastUnbound)
        ok = csvSplit.GetCount() >= FIRST_PARAM_INDEX + expectedParamCount - 1;
    else
        ok = csvSplit.GetCount() == FIRST_PARAM_INDEX + expectedParamCount;

    if(!ok)
    {
        if(IssueWarning())
        {
            printf("Line %zu: Incorrect number of function parameters.\n", lineNumber);
        }
    }

    return ok;
}

bool Player::PrepareUserData(size_t lineNumber, uint32_t allocCreateFlags, const StrRange& userDataColumn, const StrRange& wholeLine, void*& outUserData)
{
    if(!g_UserDataEnabled)
    {
        outUserData = nullptr;
        return true;
    }

    // String
    if((allocCreateFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0)
    {
        const size_t len = wholeLine.end - userDataColumn.beg;
        m_UserDataTmpStr.resize(len + 1);
        memcpy(m_UserDataTmpStr.data(), userDataColumn.beg, len);
        m_UserDataTmpStr[len] = '\0';
        outUserData = m_UserDataTmpStr.data();
        return true;
    }
    // Pointer
    else
    {
        uint64_t pUserData = 0;
        if(StrRangeToPtr(userDataColumn, pUserData))
        {
            outUserData = (void*)(uintptr_t)pUserData;
            return true;
        }
    }

    if(IssueWarning())
    {
        printf("Line %zu: Invalid pUserData.\n", lineNumber);
    }
    outUserData = 0;
    return false;
}

void Player::UpdateMemStats()
{
    if(!g_MemStatsEnabled)
    {
        return;
    }

    VmaStats stats;
    vmaCalculateStats(m_Allocator, &stats);
    m_Stats.UpdateMemStats(stats);
}

void Player::ExecuteCreatePool(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreatePool);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 7, false))
    {
        VmaPoolCreateInfo poolCreateInfo = {};
        uint64_t origPtr = 0;

        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), poolCreateInfo.memoryTypeIndex) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), poolCreateInfo.flags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), poolCreateInfo.blockSize) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), poolCreateInfo.minBlockCount) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), poolCreateInfo.maxBlockCount) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), poolCreateInfo.frameInUseCount) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), origPtr))
        {
            m_Stats.RegisterCreatePool(poolCreateInfo);

            Pool poolDesc = {};
            VkResult res = vmaCreatePool(m_Allocator, &poolCreateInfo, &poolDesc.pool);

            if(origPtr)
            {
                if(res == VK_SUCCESS)
                {
                    // Originally succeeded, currently succeeded.
                    // Just save pointer (done below).
                }
                else
                {
                    // Originally succeeded, currently failed.
                    // Print warning. Save null pointer.
                    if(IssueWarning())
                    {
                        printf("Line %zu: vmaCreatePool failed (%d), while originally succeeded.\n", lineNumber, res);
                    }
               }

                const auto existingIt = m_Pools.find(origPtr);
                if(existingIt != m_Pools.end())
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Pool %llX already exists.\n", lineNumber, origPtr);
                    }
                }
                m_Pools[origPtr] = poolDesc;
            }
            else
            {
                if(res == VK_SUCCESS)
                {
                    // Originally failed, currently succeeded.
                    // Print warning, destroy the pool.
                    if(IssueWarning())
                    {
                        printf("Line %zu: vmaCreatePool succeeded, originally failed.\n", lineNumber);
                    }

                    vmaDestroyPool(m_Allocator, poolDesc.pool);
                }
                else
                {
                    // Originally failed, currently failed.
                    // Print warning.
                    if(IssueWarning())
                    {
                        printf("Line %zu: vmaCreatePool failed (%d), originally also failed.\n", lineNumber, res);
                    }
                }
            }

            UpdateMemStats();
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaCreatePool.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteDestroyPool(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyPool);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origPtr = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            if(origPtr != 0)
            {
                const auto it = m_Pools.find(origPtr);
                if(it != m_Pools.end())
                {
                    vmaDestroyPool(m_Allocator, it->second.pool);
                    UpdateMemStats();
                    m_Pools.erase(it);
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Pool %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaDestroyPool.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteSetAllocationUserData(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::SetAllocationUserData);

    if(!g_UserDataEnabled)
    {
        return;
    }

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 2, true))
    {
        uint64_t origPtr = 0;
        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            const auto it = m_Allocations.find(origPtr);
            if(it != m_Allocations.end())
            {
                void* pUserData = nullptr;
                if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 1)
                {
                    PrepareUserData(
                        lineNumber,
                        it->second.allocationFlags,
                        csvSplit.GetRange(FIRST_PARAM_INDEX + 1),
                        csvSplit.GetLine(),
                        pUserData);
                }

                vmaSetAllocationUserData(m_Allocator, it->second.allocation, pUserData);
            }
            else
            {
                if(IssueWarning())
                {
                    printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaSetAllocationUserData.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreateBuffer);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 12, true))
    {
        VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
        VmaAllocationCreateInfo allocCreateInfo = {};
        uint64_t origPool = 0;
        uint64_t origPtr = 0;

        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), bufCreateInfo.flags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), bufCreateInfo.size) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), bufCreateInfo.usage) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), (uint32_t&)bufCreateInfo.sharingMode) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), allocCreateInfo.flags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), (uint32_t&)allocCreateInfo.usage) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), allocCreateInfo.requiredFlags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), allocCreateInfo.preferredFlags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), allocCreateInfo.memoryTypeBits) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), origPool) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 10), origPtr))
        {
            FindPool(lineNumber, origPool, allocCreateInfo.pool);

            if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 11)
            {
                PrepareUserData(
                    lineNumber,
                    allocCreateInfo.flags,
                    csvSplit.GetRange(FIRST_PARAM_INDEX + 11),
                    csvSplit.GetLine(),
                    allocCreateInfo.pUserData);
            }

            m_Stats.RegisterCreateBuffer(bufCreateInfo);
            m_Stats.RegisterCreateAllocation(allocCreateInfo);

            // Forcing VK_SHARING_MODE_EXCLUSIVE because we use only one queue anyway.
            bufCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

            Allocation allocDesc = { };
            allocDesc.allocationFlags = allocCreateInfo.flags;
            VkResult res = vmaCreateBuffer(m_Allocator, &bufCreateInfo, &allocCreateInfo, &allocDesc.buffer, &allocDesc.allocation, nullptr);
            UpdateMemStats();
            AddAllocation(lineNumber, origPtr, res, "vmaCreateBuffer", std::move(allocDesc));
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaCreateBuffer.\n", lineNumber);
            }
        }
    }
}

void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit, const char* functionName)
{
    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origAllocPtr = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origAllocPtr))
        {
            if(origAllocPtr != 0)
            {
                const auto it = m_Allocations.find(origAllocPtr);
                if(it != m_Allocations.end())
                {
                    Destroy(it->second);
                    UpdateMemStats();
                    m_Allocations.erase(it);
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origAllocPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for %s.\n", lineNumber, functionName);
            }
        }
    }
}

void Player::PrintStats(const VmaStats& stats, const char* suffix)
{
    printf("    VmaStats %s:\n", suffix);
    printf("        total:\n");
    PrintStatInfo(stats.total);

    if(g_Verbosity == VERBOSITY::MAXIMUM)
    {
        for(uint32_t i = 0; i < m_MemProps->memoryHeapCount; ++i)
        {
            printf("        memoryHeap[%u]:\n", i);
            PrintStatInfo(stats.memoryHeap[i]);
        }
        for(uint32_t i = 0; i < m_MemProps->memoryTypeCount; ++i)
        {
            printf("        memoryType[%u]:\n", i);
            PrintStatInfo(stats.memoryType[i]);
        }
    }
}

void Player::PrintStatInfo(const VmaStatInfo& info)
{
    printf("            blockCount: %u\n", info.blockCount);
    printf("            allocationCount: %u\n", info.allocationCount);
    printf("            unusedRangeCount: %u\n", info.unusedRangeCount);
    printf("            usedBytes: %llu\n", info.usedBytes);
    printf("            unusedBytes: %llu\n", info.unusedBytes);
    printf("            allocationSizeMin: %llu\n", info.allocationSizeMin);
    printf("            allocationSizeAvg: %llu\n", info.allocationSizeAvg);
    printf("            allocationSizeMax: %llu\n", info.allocationSizeMax);
    printf("            unusedRangeSizeMin: %llu\n", info.unusedRangeSizeMin);
    printf("            unusedRangeSizeAvg: %llu\n", info.unusedRangeSizeAvg);
    printf("            unusedRangeSizeMax: %llu\n", info.unusedRangeSizeMax);
}

void Player::ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreateImage);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 21, true))
    {
        VkImageCreateInfo imageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
        VmaAllocationCreateInfo allocCreateInfo = {};
        uint64_t origPool = 0;
        uint64_t origPtr = 0;

        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), imageCreateInfo.flags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), (uint32_t&)imageCreateInfo.imageType) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), (uint32_t&)imageCreateInfo.format) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), imageCreateInfo.extent.width) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), imageCreateInfo.extent.height) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), imageCreateInfo.extent.depth) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), imageCreateInfo.mipLevels) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), imageCreateInfo.arrayLayers) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), (uint32_t&)imageCreateInfo.samples) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), (uint32_t&)imageCreateInfo.tiling) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 10), imageCreateInfo.usage) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 11), (uint32_t&)imageCreateInfo.sharingMode) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 12), (uint32_t&)imageCreateInfo.initialLayout) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 13), allocCreateInfo.flags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 14), (uint32_t&)allocCreateInfo.usage) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 15), allocCreateInfo.requiredFlags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 16), allocCreateInfo.preferredFlags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 17), allocCreateInfo.memoryTypeBits) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 18), origPool) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 19), origPtr))
        {
            FindPool(lineNumber, origPool, allocCreateInfo.pool);

            if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 20)
            {
                PrepareUserData(
                    lineNumber,
                    allocCreateInfo.flags,
                    csvSplit.GetRange(FIRST_PARAM_INDEX + 20),
                    csvSplit.GetLine(),
                    allocCreateInfo.pUserData);
            }

            m_Stats.RegisterCreateImage(imageCreateInfo);
            m_Stats.RegisterCreateAllocation(allocCreateInfo);

            // Forcing VK_SHARING_MODE_EXCLUSIVE because we use only one queue anyway.
            imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

            Allocation allocDesc = {};
            allocDesc.allocationFlags = allocCreateInfo.flags;
            VkResult res = vmaCreateImage(m_Allocator, &imageCreateInfo, &allocCreateInfo, &allocDesc.image, &allocDesc.allocation, nullptr);
            UpdateMemStats();
            AddAllocation(lineNumber, origPtr, res, "vmaCreateImage", std::move(allocDesc));
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaCreateImage.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteFreeMemoryPages(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::FreeMemoryPages);
    
    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        std::vector<uint64_t> 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);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origPtr = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            Allocation allocDesc = {};
            vmaCreateLostAllocation(m_Allocator, &allocDesc.allocation);
            UpdateMemStats();
            m_Stats.RegisterCreateLostAllocation();

            AddAllocation(lineNumber, origPtr, VK_SUCCESS, "vmaCreateLostAllocation", std::move(allocDesc));
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaCreateLostAllocation.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteAllocateMemory(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::AllocateMemory);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 11, true))
    {
        VkMemoryRequirements memReq = {};
        VmaAllocationCreateInfo allocCreateInfo = {};
        uint64_t origPool = 0;
        uint64_t origPtr = 0;

        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) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), origPtr))
        {
            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(allocCreateInfo);

            Allocation allocDesc = {};
            allocDesc.allocationFlags = allocCreateInfo.flags;
            VkResult res = vmaAllocateMemory(m_Allocator, &memReq, &allocCreateInfo, &allocDesc.allocation, nullptr);
            AddAllocation(lineNumber, origPtr, res, "vmaAllocateMemory", std::move(allocDesc));
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaAllocateMemory.\n", lineNumber);
            }
        }
    }
}

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<uint64_t> 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(allocCreateInfo, allocCount);
                m_Stats.RegisterAllocateMemoryPages(allocCount);

                std::vector<VmaAllocation> 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)
    {
    case OBJECT_TYPE::BUFFER:
        m_Stats.RegisterFunctionCall(VMA_FUNCTION::AllocateMemoryForBuffer);
        break;
    case OBJECT_TYPE::IMAGE:
        m_Stats.RegisterFunctionCall(VMA_FUNCTION::AllocateMemoryForImage);
        break;
    default: assert(0);
    }

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 13, true))
    {
        VkMemoryRequirements memReq = {};
        VmaAllocationCreateInfo allocCreateInfo = {};
        bool requiresDedicatedAllocation = false;
        bool prefersDedicatedAllocation = false;
        uint64_t origPool = 0;
        uint64_t origPtr = 0;

        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) &&
            StrRangeToBool(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), requiresDedicatedAllocation) &&
            StrRangeToBool(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), prefersDedicatedAllocation) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), (uint32_t&)allocCreateInfo.usage) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), allocCreateInfo.requiredFlags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), allocCreateInfo.preferredFlags) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), allocCreateInfo.memoryTypeBits) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 10), origPool) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 11), origPtr))
        {
            FindPool(lineNumber, origPool, allocCreateInfo.pool);

            if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 12)
            {
                PrepareUserData(
                    lineNumber,
                    allocCreateInfo.flags,
                    csvSplit.GetRange(FIRST_PARAM_INDEX + 12),
                    csvSplit.GetLine(),
                    allocCreateInfo.pUserData);
            }

            UpdateMemStats();
            m_Stats.RegisterCreateAllocation(allocCreateInfo);

            if(requiresDedicatedAllocation || prefersDedicatedAllocation)
            {
                allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
            }

            if(!m_AllocateForBufferImageWarningIssued)
            {
                if(IssueWarning())
                {
                    printf("Line %zu: vmaAllocateMemoryForBuffer or vmaAllocateMemoryForImage cannot be replayed accurately. Using vmaCreateAllocation instead.\n", lineNumber);
                }
                m_AllocateForBufferImageWarningIssued = true;
            }

            Allocation allocDesc = {};
            allocDesc.allocationFlags = allocCreateInfo.flags;
            VkResult res = vmaAllocateMemory(m_Allocator, &memReq, &allocCreateInfo, &allocDesc.allocation, nullptr);
            AddAllocation(lineNumber, origPtr, res, "vmaAllocateMemory (called as vmaAllocateMemoryForBuffer or vmaAllocateMemoryForImage)", std::move(allocDesc));
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaAllocateMemoryForBuffer or vmaAllocateMemoryForImage.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteMapMemory(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::MapMemory);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origPtr = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            if(origPtr != 0)
            {
                const auto it = m_Allocations.find(origPtr);
                if(it != m_Allocations.end())
                {
                    if(it->second.allocation)
                    {
                        void* pData;
                        VkResult res = vmaMapMemory(m_Allocator, it->second.allocation, &pData);
                        if(res != VK_SUCCESS)
                        {
                            printf("Line %zu: vmaMapMemory failed (%d)\n", lineNumber, res);
                        }
                    }
                    else
                    {
                        if(IssueWarning())
                        {
                            printf("Line %zu: Cannot call vmaMapMemory - allocation is null.\n", lineNumber);
                        }
                    }
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaMapMemory.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteUnmapMemory(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::UnmapMemory);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origPtr = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            if(origPtr != 0)
            {
                const auto it = m_Allocations.find(origPtr);
                if(it != m_Allocations.end())
                {
                    if(it->second.allocation)
                    {
                        vmaUnmapMemory(m_Allocator, it->second.allocation);
                    }
                    else
                    {
                        if(IssueWarning())
                        {
                            printf("Line %zu: Cannot call vmaUnmapMemory - allocation is null.\n", lineNumber);
                        }
                    }
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaMapMemory.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteFlushAllocation(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::FlushAllocation);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 3, false))
    {
        uint64_t origPtr = 0;
        uint64_t offset = 0;
        uint64_t size = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), offset) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), size))
        {
            if(origPtr != 0)
            {
                const auto it = m_Allocations.find(origPtr);
                if(it != m_Allocations.end())
                {
                    if(it->second.allocation)
                    {
                        vmaFlushAllocation(m_Allocator, it->second.allocation, offset, size);
                    }
                    else
                    {
                        if(IssueWarning())
                        {
                            printf("Line %zu: Cannot call vmaFlushAllocation - allocation is null.\n", lineNumber);
                        }
                    }
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaFlushAllocation.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteInvalidateAllocation(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::InvalidateAllocation);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 3, false))
    {
        uint64_t origPtr = 0;
        uint64_t offset = 0;
        uint64_t size = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), offset) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), size))
        {
            if(origPtr != 0)
            {
                const auto it = m_Allocations.find(origPtr);
                if(it != m_Allocations.end())
                {
                    if(it->second.allocation)
                    {
                        vmaInvalidateAllocation(m_Allocator, it->second.allocation, offset, size);
                    }
                    else
                    {
                        if(IssueWarning())
                        {
                            printf("Line %zu: Cannot call vmaInvalidateAllocation - allocation is null.\n", lineNumber);
                        }
                    }
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaInvalidateAllocation.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteTouchAllocation(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::TouchAllocation);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origPtr = 0;
        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            const auto it = m_Allocations.find(origPtr);
            if(it != m_Allocations.end())
            {
                if(it->second.allocation)
                {
                    vmaTouchAllocation(m_Allocator, it->second.allocation);
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Cannot call vmaTouchAllocation - allocation is null.\n", lineNumber);
                    }
                }
            }
            else
            {
                if(IssueWarning())
                {
                    printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaTouchAllocation.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteGetAllocationInfo(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::GetAllocationInfo);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origPtr = 0;
        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            const auto it = m_Allocations.find(origPtr);
            if(it != m_Allocations.end())
            {
                if(it->second.allocation)
                {
                    VmaAllocationInfo allocInfo;
                    vmaGetAllocationInfo(m_Allocator, it->second.allocation, &allocInfo);
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Cannot call vmaGetAllocationInfo - allocation is null.\n", lineNumber);
                    }
                }
            }
            else
            {
                if(IssueWarning())
                {
                    printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaGetAllocationInfo.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteMakePoolAllocationsLost(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::MakePoolAllocationsLost);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origPtr = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            if(origPtr != 0)
            {
                const auto it = m_Pools.find(origPtr);
                if(it != m_Pools.end())
                {
                    vmaMakePoolAllocationsLost(m_Allocator, it->second.pool, nullptr);
                    UpdateMemStats();
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Pool %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaMakePoolAllocationsLost.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteResizeAllocation(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::ResizeAllocation);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 2, false))
    {
        uint64_t origPtr = 0;
        uint64_t newSize = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), newSize))
        {
            if(origPtr != 0)
            {
                const auto it = m_Allocations.find(origPtr);
                if(it != m_Allocations.end())
                {
                    vmaResizeAllocation(m_Allocator, it->second.allocation, newSize);
                    UpdateMemStats();
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaResizeAllocation.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteDefragmentationBegin(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::DefragmentationBegin);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 9, false))
    {
        VmaDefragmentationInfo2 defragInfo = {};
        std::vector<uint64_t> allocationOrigPtrs;
        std::vector<uint64_t> poolOrigPtrs;
        uint64_t cmdBufOrigPtr = 0;
        uint64_t defragCtxOrigPtr = 0;

        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), defragInfo.flags) &&
            StrRangeToPtrList(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), allocationOrigPtrs) &&
            StrRangeToPtrList(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), poolOrigPtrs) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), defragInfo.maxCpuBytesToMove) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), defragInfo.maxCpuAllocationsToMove) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), defragInfo.maxGpuBytesToMove) &&
            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), defragInfo.maxGpuAllocationsToMove) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), cmdBufOrigPtr) &&
            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), defragCtxOrigPtr))
        {
            const size_t allocationOrigPtrCount = allocationOrigPtrs.size();
            std::vector<VmaAllocation> allocations;
            allocations.reserve(allocationOrigPtrCount);
            for(size_t i = 0; i < allocationOrigPtrCount; ++i)
            {
                const auto it = m_Allocations.find(allocationOrigPtrs[i]);
                if(it != m_Allocations.end() && it->second.allocation)
                {
                    allocations.push_back(it->second.allocation);
                }
            }
            if(!allocations.empty())
            {
                defragInfo.allocationCount = (uint32_t)allocations.size();
                defragInfo.pAllocations = allocations.data();
            }

            const size_t poolOrigPtrCount = poolOrigPtrs.size();
            std::vector<VmaPool> pools;
            pools.reserve(poolOrigPtrCount);
            for(size_t i = 0; i < poolOrigPtrCount; ++i)
            {
                const auto it = m_Pools.find(poolOrigPtrs[i]);
                if(it != m_Pools.end() && it->second.pool)
                {
                    pools.push_back(it->second.pool);
                }
            }
            if(!pools.empty())
            {
                defragInfo.poolCount = (uint32_t)pools.size();
                defragInfo.pPools = pools.data();
            }

            if(allocations.size() != allocationOrigPtrCount ||
                pools.size() != poolOrigPtrCount)
            {
                if(IssueWarning())
                {
                    printf("Line %zu: Passing %zu allocations and %zu pools to vmaDefragmentationBegin, while originally %zu allocations and %zu pools were passed.\n",
                        lineNumber,
                        allocations.size(), pools.size(),
                        allocationOrigPtrCount, poolOrigPtrCount);
                }
            }

            if(cmdBufOrigPtr)
            {
                VkCommandBufferBeginInfo cmdBufBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
                cmdBufBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
                VkResult res = vkBeginCommandBuffer(m_CommandBuffer, &cmdBufBeginInfo);
                if(res == VK_SUCCESS)
                {
                    defragInfo.commandBuffer = m_CommandBuffer;
                }
                else
                {
                    printf("Line %zu: vkBeginCommandBuffer failed (%d)\n", lineNumber, res);
                }
            }

            m_Stats.RegisterDefragmentation(defragInfo);

            VmaDefragmentationContext defragCtx = nullptr;
            VkResult res = vmaDefragmentationBegin(m_Allocator, &defragInfo, nullptr, &defragCtx);

            if(defragInfo.commandBuffer)
            {
                vkEndCommandBuffer(m_CommandBuffer);

                VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
                submitInfo.commandBufferCount = 1;
                submitInfo.pCommandBuffers = &m_CommandBuffer;
                vkQueueSubmit(m_TransferQueue, 1, &submitInfo, VK_NULL_HANDLE);
                vkQueueWaitIdle(m_TransferQueue);
            }

            if(res >= VK_SUCCESS)
            {
                if(defragCtx)
                {
                    if(defragCtxOrigPtr)
                    {
                        // We have defragmentation context, originally had defragmentation context: Store it.
                        m_DefragmentationContexts[defragCtxOrigPtr] = defragCtx;
                    }
                    else
                    {
                        // We have defragmentation context, originally it was null: End immediately.
                        vmaDefragmentationEnd(m_Allocator, defragCtx);
                    }
                }
                else
                {
                    if(defragCtxOrigPtr)
                    {
                        // We have no defragmentation context, originally there was one: Store null.
                        m_DefragmentationContexts[defragCtxOrigPtr] = nullptr;
                    }
                    else
                    {
                        // We have no defragmentation context, originally there wasn't as well - nothing to do.
                    }
                }
            }
            else
            {
                if(defragCtxOrigPtr)
                {
                    // Currently failed, originally succeeded.
                    if(IssueWarning())
                    {
                        printf("Line %zu: vmaDefragmentationBegin failed (%d), while originally succeeded.\n", lineNumber, res);
                    }
                }
                else
                {
                    // Currently failed, originally don't know.
                    if(IssueWarning())
                    {
                        printf("Line %zu: vmaDefragmentationBegin failed (%d).\n", lineNumber, res);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaDefragmentationBegin.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteDefragmentationEnd(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::DefragmentationEnd);

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
    {
        uint64_t origPtr = 0;

        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            if(origPtr != 0)
            {
                const auto it = m_DefragmentationContexts.find(origPtr);
                if(it != m_DefragmentationContexts.end())
                {
                    vmaDefragmentationEnd(m_Allocator, it->second);
                    m_DefragmentationContexts.erase(it);
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Defragmentation context %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaDefragmentationEnd.\n", lineNumber);
            }
        }
    }
}

void Player::ExecuteSetPoolName(size_t lineNumber, const CsvSplit& csvSplit)
{
    m_Stats.RegisterFunctionCall(VMA_FUNCTION::SetPoolName);

    if(!g_UserDataEnabled)
    {
        return;
    }

    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 2, true))
    {
        uint64_t origPtr = 0;
        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))
        {
            if(origPtr != 0)
            {
                const auto it = m_Pools.find(origPtr);
                if(it != m_Pools.end())
                {
                    std::string poolName;
                    csvSplit.GetRange(FIRST_PARAM_INDEX + 1).to_str(poolName);
                    vmaSetPoolName(m_Allocator, it->second.pool, !poolName.empty() ? poolName.c_str() : nullptr);
                }
                else
                {
                    if(IssueWarning())
                    {
                        printf("Line %zu: Pool %llX not found.\n", lineNumber, origPtr);
                    }
                }
            }
        }
        else
        {
            if(IssueWarning())
            {
                printf("Line %zu: Invalid parameters for vmaSetPoolName.\n", lineNumber);
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////
// Main functions

static void PrintCommandLineSyntax()
{
    printf(
        "Command line syntax:\n"
        "    VmaReplay [Options] <SrcFile.csv>\n"
        "Available options:\n"
        "    -v <Number> - Verbosity level:\n"
        "        0 - Minimum verbosity. Prints only warnings and errors.\n"
        "        1 - Default verbosity. Prints important messages and statistics.\n"
        "        2 - Maximum verbosity. Prints a lot of information.\n"
        "    -i <Number> - Repeat playback given number of times (iterations)\n"
        "        Default is 1. Vulkan is reinitialized with every iteration.\n"
        "    --MemStats <Value> - 0 to disable or 1 to enable memory statistics.\n"
        "        Default is 0. Enabling it may negatively impact playback performance.\n"
        "    --DumpStatsAfterLine <Line> - Dump VMA statistics to JSON file after specified source file line finishes execution.\n"
        "        File is written to current directory with name: VmaReplay_Line####.json.\n"
        "        This parameter can be repeated.\n"
        "    --DumpDetailedStatsAfterLine <Line> - Like command above, but includes detailed map.\n"
        "    --DefragmentAfterLine <Line> - Defragment memory after specified source file line and print statistics.\n"
        "        It also prints detailed statistics to files VmaReplay_Line####_Defragment*.json\n"
        "    --DefragmentationFlags <Flags> - Flags to be applied when using DefragmentAfterLine.\n"
        "    --Lines <Ranges> - Replay only limited set of lines from file\n"
        "        Ranges is comma-separated list of ranges, e.g. \"-10,15,18-25,31-\".\n"
        "    --PhysicalDevice <Index> - Choice of Vulkan physical device. Default: 0.\n"
        "    --UserData <Value> - 0 to disable or 1 to enable setting pUserData during playback.\n"
        "        Default is 1. Affects both creation of buffers and images, as well as calls to vmaSetAllocationUserData.\n"
        "    --VK_LAYER_LUNARG_standard_validation <Value> - 0 to disable or 1 to enable validation layers.\n"
        "        By default the layers are silently enabled if available.\n"
        "    --VK_EXT_memory_budget <Value> - 0 to disable or 1 to enable this extension.\n"
        "        By default the extension is silently enabled if available.\n"
    );
}

static int ProcessFile(size_t iterationIndex, const char* data, size_t numBytes, duration& outDuration)
{
    outDuration = duration::max();

    const bool useLineRanges = !g_LineRanges.IsEmpty();
    const bool useDumpStatsAfterLine = !g_DumpStatsAfterLine.empty();
    const bool useDefragmentAfterLine = !g_DefragmentAfterLine.empty();

    LineSplit lineSplit(data, numBytes);
    StrRange line;

    if(!lineSplit.GetNextLine(line) ||
        !StrRangeEq(line, "Vulkan Memory Allocator,Calls recording"))
    {
        printf("ERROR: Incorrect file format.\n");
        return RESULT_ERROR_FORMAT;
    }

    if(!lineSplit.GetNextLine(line) || !ParseFileVersion(line) || !ValidateFileVersion())
    {
        printf("ERROR: Incorrect file format version.\n");
        return RESULT_ERROR_FORMAT;
    }

    if(g_Verbosity == VERBOSITY::MAXIMUM)
    {
        printf("Format version: %u,%u\n",
            GetVersionMajor(g_FileVersion),
            GetVersionMinor(g_FileVersion));
    }

    // Parse configuration
    const bool configEnabled = g_FileVersion >= MakeVersion(1, 3);
    ConfigurationParser configParser;
    if(configEnabled)
    {
        if(!configParser.Parse(lineSplit))
        {
            return RESULT_ERROR_FORMAT;
        }
    }

    Player player;
    int result = player.Init();

    if(configEnabled)
    {
        player.ApplyConfig(configParser);
    }

    size_t executedLineCount = 0;
    if(result == 0)
    {
        if(g_Verbosity > VERBOSITY::MINIMUM)
        {
            if(useLineRanges)
            {
                printf("Playing #%zu (limited range of lines)...\n", iterationIndex + 1);
            }
            else
            {
                printf("Playing #%zu...\n", iterationIndex + 1);
            }
        }

        const time_point timeBeg = std::chrono::high_resolution_clock::now();

        while(lineSplit.GetNextLine(line))
        {
            const size_t currLineNumber = lineSplit.GetNextLineIndex();

            bool execute = true;
            if(useLineRanges)
            {
                execute = g_LineRanges.Includes(currLineNumber);
            }

            if(execute)
            {
                player.ExecuteLine(currLineNumber, line);
                ++executedLineCount;
            }

            while(useDumpStatsAfterLine &&
                g_DumpStatsAfterLineNextIndex < g_DumpStatsAfterLine.size() &&
                currLineNumber >= g_DumpStatsAfterLine[g_DumpStatsAfterLineNextIndex].line)
            {
                const size_t requestedLine = g_DumpStatsAfterLine[g_DumpStatsAfterLineNextIndex].line;
                const bool detailed = g_DumpStatsAfterLine[g_DumpStatsAfterLineNextIndex].detailed;
                
                if(g_Verbosity == VERBOSITY::MAXIMUM)
                {
                    printf("Dumping %sstats after line %zu actual line %zu...\n",
                        detailed ? "detailed " : "",
                        requestedLine,
                        currLineNumber);
                }

                player.DumpStats("VmaReplay_Line%04zu.json", requestedLine, detailed);
                
                ++g_DumpStatsAfterLineNextIndex;
            }

            while(useDefragmentAfterLine &&
                g_DefragmentAfterLineNextIndex < g_DefragmentAfterLine.size() &&
                currLineNumber >= g_DefragmentAfterLine[g_DefragmentAfterLineNextIndex])
            {
                const size_t requestedLine = g_DefragmentAfterLine[g_DefragmentAfterLineNextIndex];
                if(g_Verbosity >= VERBOSITY::DEFAULT)
                {
                    printf("Defragmenting after line %zu actual line %zu...\n",
                        requestedLine,
                        currLineNumber);
                }

                player.DumpStats("VmaReplay_Line%04zu_Defragment_1Before.json", requestedLine, true);
                player.Defragment();
                player.DumpStats("VmaReplay_Line%04zu_Defragment_2After.json", requestedLine, true);
                
                ++g_DefragmentAfterLineNextIndex;
            }
        }

        const duration playDuration = std::chrono::high_resolution_clock::now() - timeBeg;
        outDuration = playDuration;

        // End stats.
        if(g_Verbosity > VERBOSITY::MINIMUM)
        {
            std::string playDurationStr;
            SecondsToFriendlyStr(ToFloatSeconds(playDuration), playDurationStr);

            printf("Done.\n");
            printf("Playback took: %s\n", playDurationStr.c_str());
        }
        if(g_Verbosity == VERBOSITY::MAXIMUM)
        {
            printf("File lines: %zu\n", lineSplit.GetNextLineIndex());
            printf("Executed %zu file lines\n", executedLineCount);
        }

        player.PrintStats();
    }

    return result;
}

static int ProcessFile()
{
    if(g_Verbosity > VERBOSITY::MINIMUM)
    {
        printf("Loading file \"%s\"...\n", g_FilePath.c_str());
    }
    int result = 0;

    FILE* file = nullptr;
    const errno_t err = fopen_s(&file, g_FilePath.c_str(), "rb");
    if(err == 0)
    {
        _fseeki64(file, 0, SEEK_END);
        const size_t fileSize = (size_t)_ftelli64(file);
        _fseeki64(file, 0, SEEK_SET);

        if(fileSize > 0)
        {
            std::vector<char> fileContents(fileSize);
            fread(fileContents.data(), 1, fileSize, file);

            // Begin stats.
            if(g_Verbosity == VERBOSITY::MAXIMUM)
            {
                printf("File size: %zu B\n", fileSize);
            }

            duration durationSum = duration::zero();
            for(size_t i = 0; i < g_IterationCount; ++i)
            {
                duration currDuration;
                ProcessFile(i, fileContents.data(), fileContents.size(), currDuration);
                durationSum += currDuration;
            }

            if(g_IterationCount > 1)
            {
                std::string playDurationStr;
                SecondsToFriendlyStr(ToFloatSeconds(durationSum / g_IterationCount), playDurationStr);
                printf("Average playback time from %zu iterations: %s\n", g_IterationCount, playDurationStr.c_str());
            }
        }
        else
        {
            printf("ERROR: Source file is empty.\n");
            result = RESULT_ERROR_SOURCE_FILE;
        }

        fclose(file);
    }
    else
    {
        printf("ERROR: Couldn't open file (%i).\n", err);
        result = RESULT_ERROR_SOURCE_FILE;
    }

    return result;
}

static int main2(int argc, char** argv)
{
    CmdLineParser cmdLineParser(argc, argv);

    cmdLineParser.RegisterOpt(CMD_LINE_OPT_VERBOSITY, 'v', true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_ITERATIONS, 'i', true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_LINES, "Lines", true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_PHYSICAL_DEVICE, "PhysicalDevice", true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_USER_DATA, "UserData", true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_VK_EXT_MEMORY_BUDGET, "VK_EXT_memory_budget", true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_VK_LAYER_LUNARG_STANDARD_VALIDATION, VALIDATION_LAYER_NAME, true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_MEM_STATS, "MemStats", true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_DUMP_STATS_AFTER_LINE, "DumpStatsAfterLine", true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_DEFRAGMENT_AFTER_LINE, "DefragmentAfterLine", true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_DEFRAGMENTATION_FLAGS, "DefragmentationFlags", true);
    cmdLineParser.RegisterOpt(CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE, "DumpDetailedStatsAfterLine", true);

    CmdLineParser::RESULT res;
    while((res = cmdLineParser.ReadNext()) != CmdLineParser::RESULT_END)
    {
        switch(res)
        {
        case CmdLineParser::RESULT_OPT:
            switch(cmdLineParser.GetOptId())
            {
            case CMD_LINE_OPT_VERBOSITY:
                {
                    uint32_t verbosityVal = UINT32_MAX;
                    if(StrRangeToUint(StrRange(cmdLineParser.GetParameter()), verbosityVal) &&
                        verbosityVal < (uint32_t)VERBOSITY::COUNT)
                    {
                        g_Verbosity = (VERBOSITY)verbosityVal;
                    }
                    else
                    {
                        PrintCommandLineSyntax();
                        return RESULT_ERROR_COMMAND_LINE;
                    }
                }
                break;
            case CMD_LINE_OPT_ITERATIONS:
                if(!StrRangeToUint(StrRange(cmdLineParser.GetParameter()), g_IterationCount))
                {
                    PrintCommandLineSyntax();
                    return RESULT_ERROR_COMMAND_LINE;
                }
                break;
            case CMD_LINE_OPT_LINES:
                if(!g_LineRanges.Parse(StrRange(cmdLineParser.GetParameter())))
                {
                    PrintCommandLineSyntax();
                    return RESULT_ERROR_COMMAND_LINE;
                }
                break;
            case CMD_LINE_OPT_PHYSICAL_DEVICE:
                if(!StrRangeToUint(StrRange(cmdLineParser.GetParameter()), g_PhysicalDeviceIndex))
                {
                    PrintCommandLineSyntax();
                    return RESULT_ERROR_COMMAND_LINE;
                }
                break;
            case CMD_LINE_OPT_USER_DATA:
                if(!StrRangeToBool(StrRange(cmdLineParser.GetParameter()), g_UserDataEnabled))
                {
                    PrintCommandLineSyntax();
                    return RESULT_ERROR_COMMAND_LINE;
                }
                break;
            case CMD_LINE_OPT_VK_EXT_MEMORY_BUDGET:
                {
                    bool newValue;
                    if(StrRangeToBool(StrRange(cmdLineParser.GetParameter()), newValue))
                    {
                        g_VK_EXT_memory_budget_request = newValue ?
                            VULKAN_EXTENSION_REQUEST::ENABLED :
                            VULKAN_EXTENSION_REQUEST::DISABLED;
                    }
                    else
                    {
                        PrintCommandLineSyntax();
                        return RESULT_ERROR_COMMAND_LINE;
                    }
                }
                break;
            case CMD_LINE_OPT_VK_LAYER_LUNARG_STANDARD_VALIDATION:
                {
                    bool newValue;
                    if(StrRangeToBool(StrRange(cmdLineParser.GetParameter()), newValue))
                    {
                        g_VK_LAYER_LUNARG_standard_validation = newValue ?
                            VULKAN_EXTENSION_REQUEST::ENABLED :
                            VULKAN_EXTENSION_REQUEST::DISABLED;
                    }
                    else
                    {
                        PrintCommandLineSyntax();
                        return RESULT_ERROR_COMMAND_LINE;
                    }
                }
                break;
            case CMD_LINE_OPT_MEM_STATS:
                if(!StrRangeToBool(StrRange(cmdLineParser.GetParameter()), g_MemStatsEnabled))
                {
                    PrintCommandLineSyntax();
                    return RESULT_ERROR_COMMAND_LINE;
                }
                break;
            case CMD_LINE_OPT_DUMP_STATS_AFTER_LINE:
            case CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE:
                {
                    size_t line;
                    if(StrRangeToUint(StrRange(cmdLineParser.GetParameter()), line))
                    {
                        const bool detailed =
                            cmdLineParser.GetOptId() == CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE;
                        g_DumpStatsAfterLine.push_back({line, detailed});
                    }
                    else
                    {
                        PrintCommandLineSyntax();
                        return RESULT_ERROR_COMMAND_LINE;
                    }
                }
                break;
            case CMD_LINE_OPT_DEFRAGMENT_AFTER_LINE:
                {
                    size_t line;
                    if(StrRangeToUint(StrRange(cmdLineParser.GetParameter()), line))
                    {
                        g_DefragmentAfterLine.push_back(line);
                    }
                    else
                    {
                        PrintCommandLineSyntax();
                        return RESULT_ERROR_COMMAND_LINE;
                    }
                }
                break;
            case CMD_LINE_OPT_DEFRAGMENTATION_FLAGS:
                {
                    if(!StrRangeToUint(StrRange(cmdLineParser.GetParameter()), g_DefragmentationFlags))
                    {
                        PrintCommandLineSyntax();
                        return RESULT_ERROR_COMMAND_LINE;
                    }
                }
                break;
            default:
                assert(0);
            }
            break;
        case CmdLineParser::RESULT_PARAMETER:
            if(g_FilePath.empty())
            {
                g_FilePath = cmdLineParser.GetParameter();
            }
            else
            {
                PrintCommandLineSyntax();
                return RESULT_ERROR_COMMAND_LINE;
            }
            break;
        case CmdLineParser::RESULT_ERROR:
            PrintCommandLineSyntax();
            return RESULT_ERROR_COMMAND_LINE;
            break;
        default:
            assert(0);
        }
    }

    // Postprocess command line parameters.

    if(g_FilePath.empty())
    {
        PrintCommandLineSyntax();
        return RESULT_ERROR_COMMAND_LINE;
    }

    // Sort g_DumpStatsAfterLine and make unique.
    std::sort(g_DumpStatsAfterLine.begin(), g_DumpStatsAfterLine.end());
    g_DumpStatsAfterLine.erase(
        std::unique(g_DumpStatsAfterLine.begin(), g_DumpStatsAfterLine.end()),
        g_DumpStatsAfterLine.end());

    // Sort g_DefragmentAfterLine and make unique.
    std::sort(g_DefragmentAfterLine.begin(), g_DefragmentAfterLine.end());
    g_DefragmentAfterLine.erase(
        std::unique(g_DefragmentAfterLine.begin(), g_DefragmentAfterLine.end()),
        g_DefragmentAfterLine.end());

    return ProcessFile();
}

int main(int argc, char** argv)
{
    try
    {
        return main2(argc, argv);
    }
    catch(const std::exception& e)
    {
        printf("ERROR: %s\n", e.what());
        return RESULT_EXCEPTION;
    }
    catch(...)
    {
        printf("UNKNOWN ERROR\n");
        return RESULT_EXCEPTION;
    }
}
