//
// Copyright (c) 2018-2021 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_KHRONOS_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,
    void*             pUserData)
{
    g_Statistics->RegisterDeviceMemoryAllocation(memoryType, size);
}

/// Callback function called before vkFreeMemory.
static void VKAPI_CALL FreeDeviceMemoryCallback(
    VmaAllocator      allocator,
    uint32_t          memoryType,
    VkDeviceMemory    memory,
    VkDeviceSize      size,
    void*             pUserData)
{
    // 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_MIN_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_MIN_ALIGNMENT") || StrRangeEq(subOptionName, "VMA_DEBUG_ALIGNMENT"))
                    SetOption(currLineNumber, OPTION::Macro_VMA_MIN_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_KHRONOS_validation";

static VkBool32 VKAPI_PTR MyDebugReportCallback(
    VkDebugUtilsMessageSeverityFlagBitsEXT           messageSeverity,
    VkDebugUtilsMessageTypeFlagsEXT                  messageTypes,
    const VkDebugUtilsMessengerCallbackDataEXT*      pCallbackData,
    void*                                            pUserData)
{
    assert(pCallbackData && pCallbackData->pMessageIdName && pCallbackData->pMessage);
    printf("%s \xBA %s\n", pCallbackData->pMessageIdName, pCallbackData->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_vkCreateDebugUtilsMessengerEXT m_vkCreateDebugUtilsMessengerEXT = nullptr;
    PFN_vkDestroyDebugUtilsMessengerEXT m_vkDestroyDebugUtilsMessengerEXT = nullptr;
    VkDebugUtilsMessengerEXT m_DebugUtilsMessenger = VK_NULL_HANDLE;

    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();
    void UnregisterDebugCallbacks();

    // 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_KHRONOS_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);
    }

    bool VK_KHR_get_physical_device_properties2_enabled = false;
    bool VK_EXT_debug_utils_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;
        }
        else if(strcmp(extensionProperties.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0)
        {
            if(validationLayersEnabled)
            {
                enabledInstanceExtensions.push_back("VK_EXT_debug_utils");
                VK_EXT_debug_utils_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(VK_EXT_debug_utils_enabled)
    {
        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;
    }

    UnregisterDebugCallbacks();

    if(m_VulkanInstance != VK_NULL_HANDLE)
    {
        vkDestroyInstance(m_VulkanInstance, NULL);
        m_VulkanInstance = VK_NULL_HANDLE;
    }
}

void Player::RegisterDebugCallbacks()
{
    static const VkDebugUtilsMessageSeverityFlagsEXT DEBUG_UTILS_MESSENGER_MESSAGE_SEVERITY =
        //VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
        //VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
        VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
        VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
    static const VkDebugUtilsMessageTypeFlagsEXT DEBUG_UTILS_MESSENGER_MESSAGE_TYPE =
        VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
        VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
        VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;

    m_vkCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
        m_VulkanInstance, "vkCreateDebugUtilsMessengerEXT");
    m_vkDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
        m_VulkanInstance, "vkDestroyDebugUtilsMessengerEXT");
    assert(m_vkCreateDebugUtilsMessengerEXT);
    assert(m_vkDestroyDebugUtilsMessengerEXT);

    VkDebugUtilsMessengerCreateInfoEXT messengerCreateInfo = { VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT };
    messengerCreateInfo.messageSeverity = DEBUG_UTILS_MESSENGER_MESSAGE_SEVERITY;
    messengerCreateInfo.messageType = DEBUG_UTILS_MESSENGER_MESSAGE_TYPE;
    messengerCreateInfo.pfnUserCallback = MyDebugReportCallback;
    VkResult res = m_vkCreateDebugUtilsMessengerEXT(m_VulkanInstance, &messengerCreateInfo, nullptr, &m_DebugUtilsMessenger);
    if(res != VK_SUCCESS)
    {
        printf("ERROR: vkCreateDebugUtilsMessengerEXT failed (%d)\n", res);
        m_DebugUtilsMessenger = VK_NULL_HANDLE;
    }
}

void Player::UnregisterDebugCallbacks()
{
    if(m_DebugUtilsMessenger)
    {
        m_vkDestroyDebugUtilsMessengerEXT(m_VulkanInstance, m_DebugUtilsMessenger, nullptr);
    }
}

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())
                {
                    // Do nothing - the function was deprecated and has been removed.
                    //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_KHRONOS_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_KHRONOS_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_KHRONOS_VALIDATION:
                {
                    bool newValue;
                    if(StrRangeToBool(StrRange(cmdLineParser.GetParameter()), newValue))
                    {
                        g_VK_LAYER_KHRONOS_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;
    }
}
