//
// Copyright (c) 2019-2025 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 "Common.h"
#include "Tests.h"
#include <thread>

// Define to the same value as you did for D3D12MemAlloc.cpp.
#ifndef D3D12MA_DEBUG_MARGIN
    #define D3D12MA_DEBUG_MARGIN 0
#endif

extern ID3D12GraphicsCommandList* BeginCommandList();
extern DXGI_ADAPTER_DESC1 g_AdapterDesc;
extern void EndCommandList(ID3D12GraphicsCommandList* cmdList);

enum CONFIG_TYPE
{
    CONFIG_TYPE_MINIMUM,
    CONFIG_TYPE_SMALL,
    CONFIG_TYPE_AVERAGE,
    CONFIG_TYPE_LARGE,
    CONFIG_TYPE_MAXIMUM,
    CONFIG_TYPE_COUNT
};

enum class FREE_ORDER { FORWARD, BACKWARD, RANDOM, COUNT };

static const char* CODE_DESCRIPTION = "D3D12MA Tests";
static constexpr UINT64 KILOBYTE = 1024;
static constexpr UINT64 MEGABYTE = 1024 * KILOBYTE;
static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_AVERAGE;
static const char* FREE_ORDER_NAMES[] = { "FORWARD", "BACKWARD", "RANDOM", };

// Indexes match enum D3D12_HEAP_TYPE.
static const WCHAR* const HEAP_TYPE_NAMES[] =
{
    L"",
    L"DEFAULT",
    L"UPLOAD",
    L"READBACK",
    L"CUSTOM",
    L"GPU_UPLOAD",
};

bool operator==(const D3D12MA::Statistics& lhs, const D3D12MA::Statistics& rhs)
{
    return lhs.BlockCount == rhs.BlockCount &&
        lhs.AllocationCount == rhs.AllocationCount &&
        lhs.BlockBytes == rhs.BlockBytes &&
        lhs.AllocationBytes == rhs.AllocationBytes;
}

static void CurrentTimeToStr(std::string& out)
{
    time_t rawTime; time(&rawTime);
    struct tm timeInfo; localtime_s(&timeInfo, &rawTime);
    char timeStr[128];
    strftime(timeStr, _countof(timeStr), "%c", &timeInfo);
    out = timeStr;
}

static float ToFloatSeconds(duration d)
{
    return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
}

static const char* AlgorithmToStr(D3D12MA::POOL_FLAGS algorithm)
{
    switch (algorithm)
    {
    case D3D12MA::POOL_FLAG_ALGORITHM_LINEAR:
        return "Linear";
    case 0:
        return "TLSF";
    default:
        assert(0);
        return "";
    }
}

static const char* VirtualAlgorithmToStr(D3D12MA::VIRTUAL_BLOCK_FLAGS algorithm)
{
    switch (algorithm)
    {
    case D3D12MA::VIRTUAL_BLOCK_FLAG_ALGORITHM_LINEAR:
        return "Linear";
    case 0:
        return "TLSF";
    default:
        assert(0);
        return "";
    }
}

static const wchar_t* DefragmentationAlgorithmToStr(UINT32 algorithm)
{
    switch (algorithm)
    {
    case D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED:
        return L"Balanced";
    case D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_FAST:
        return L"Fast";
    case D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_FULL:
        return L"Full";
    case 0:
        return L"Default";
    default:
        assert(0);
        return L"";
    }
}

struct ResourceWithAllocation
{
    ComPtr<ID3D12Resource> resource;
    ComPtr<D3D12MA::Allocation> allocation;
    UINT64 size = UINT64_MAX;
    UINT dataSeed = 0;

    void Reset()
    {
        resource.Reset();
        allocation.Reset();
        size = UINT64_MAX;
        dataSeed = 0;
    }
};

template<typename D3D12_RESOURCE_DESC_T>
static void FillResourceDescForBuffer(D3D12_RESOURCE_DESC_T& outResourceDesc, UINT64 size)
{
    outResourceDesc = {};
    outResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
    outResourceDesc.Alignment = 0;
    outResourceDesc.Width = size;
    outResourceDesc.Height = 1;
    outResourceDesc.DepthOrArraySize = 1;
    outResourceDesc.MipLevels = 1;
    outResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
    outResourceDesc.SampleDesc.Count = 1;
    outResourceDesc.SampleDesc.Quality = 0;
    outResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
    outResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
}

static void FillData(void* outPtr, const UINT64 sizeInBytes, UINT seed)
{
    UINT* outValues = (UINT*)outPtr;
    const UINT64 sizeInValues = sizeInBytes / sizeof(UINT);
    UINT value = seed;
    for(UINT i = 0; i < sizeInValues; ++i)
    {
        outValues[i] = value++;
    }
}

static void FillAllocationsData(const ComPtr<D3D12MA::Allocation>* allocs, size_t allocCount, UINT seed)
{
    std::for_each(allocs, allocs + allocCount, [seed](const ComPtr<D3D12MA::Allocation>& alloc)
        {
            D3D12_RANGE range = {};
            void* ptr;
            CHECK_HR(alloc->GetResource()->Map(0, &range, &ptr));
            FillData(ptr, alloc->GetSize(), seed);
            alloc->GetResource()->Unmap(0, nullptr);
        });
}

static void FillAllocationsDataGPU(const TestContext& ctx, const ComPtr<D3D12MA::Allocation>* allocs, size_t allocCount, UINT seed)
{
    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_UPLOAD,
        D3D12MA::ALLOCATION_FLAG_COMMITTED,
        NULL, // privateData
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS }; // extraHeapFlags

    std::vector<D3D12_RESOURCE_BARRIER> barriers;
    std::vector<ComPtr<D3D12MA::Allocation>> uploadAllocs;
    barriers.reserve(allocCount);
    uploadAllocs.reserve(allocCount);

    // Move resource into right state
    D3D12_RESOURCE_BARRIER barrier = {};
    barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
    barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
    barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;

    ID3D12GraphicsCommandList* cl = BeginCommandList();
    std::for_each(allocs, allocs + allocCount, [&](const ComPtr<D3D12MA::Allocation>& alloc)
        {
            // Copy only buffers for now
            D3D12_RESOURCE_DESC resDesc = alloc->GetResource()->GetDesc();
            if (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
            {
                ComPtr<D3D12MA::Allocation> uploadAlloc;
                CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
                    nullptr, &uploadAlloc, IID_NULL, nullptr));

                D3D12_RANGE range = {};
                void* ptr;
                CHECK_HR(uploadAlloc->GetResource()->Map(0, &range, &ptr));
                FillData(ptr, resDesc.Width, seed);
                uploadAlloc->GetResource()->Unmap(0, nullptr);

                cl->CopyResource(alloc->GetResource(), uploadAlloc->GetResource());
                uploadAllocs.emplace_back(std::move(uploadAlloc));
            }

            barrier.Transition.pResource = alloc->GetResource();
            barrier.Transition.StateAfter = (D3D12_RESOURCE_STATES)(uintptr_t)alloc->GetPrivateData();
            barriers.emplace_back(barrier);
        });
    cl->ResourceBarrier(static_cast<UINT>(allocCount), barriers.data());
    EndCommandList(cl);
}

static bool ValidateData(const void* ptr, const UINT64 sizeInBytes, UINT seed)
{
    const UINT* values = (const UINT*)ptr;
    const UINT64 sizeInValues = sizeInBytes / sizeof(UINT);
    UINT value = seed;
    for(UINT i = 0; i < sizeInValues; ++i)
    {
        if(values[i] != value++)
        {
            //CHECK_BOOL(0 && "ValidateData failed.");
            return false;
        }
    }
    return true;
}

static bool ValidateDataZero(const void* ptr, const UINT64 sizeInBytes)
{
    const UINT* values = (const UINT*)ptr;
    const UINT64 sizeInValues = sizeInBytes / sizeof(UINT);
    for(UINT i = 0; i < sizeInValues; ++i)
    {
        if(values[i] != 0)
        {
            //CHECK_BOOL(0 && "ValidateData failed.");
            return false;
        }
    }
    return true;
}

static void ValidateAllocationsData(const ComPtr<D3D12MA::Allocation>* allocs, size_t allocCount, UINT seed)
{
    std::for_each(allocs, allocs + allocCount, [seed](const ComPtr<D3D12MA::Allocation>& alloc)
        {
            D3D12_RANGE range = {};
            void* ptr;
            CHECK_HR(alloc->GetResource()->Map(0, &range, &ptr));
            CHECK_BOOL(ValidateData(ptr, alloc->GetSize(), seed));
            alloc->GetResource()->Unmap(0, nullptr);
        });
}

static void ValidateAllocationsDataGPU(const TestContext& ctx, const ComPtr<D3D12MA::Allocation>* allocs, size_t allocCount, UINT seed)
{
    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_READBACK,
        D3D12MA::ALLOCATION_FLAG_COMMITTED,
        NULL, // privateData
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS }; // extraHeapFlags

    std::vector<D3D12_RESOURCE_BARRIER> barriers;
    std::vector<ComPtr<D3D12MA::Allocation>> downloadAllocs;
    barriers.reserve(allocCount);
    downloadAllocs.reserve(allocCount);

    // Move resource into right state
    D3D12_RESOURCE_BARRIER barrier = {};
    barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
    barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
    barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;

    ID3D12GraphicsCommandList* cl = BeginCommandList();
    size_t resCount = allocCount;
    std::for_each(allocs, allocs + allocCount, [&](const ComPtr<D3D12MA::Allocation>& alloc)
        {
            // Check only buffers for now
            D3D12_RESOURCE_DESC resDesc = alloc->GetResource()->GetDesc();
            if (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
            {
                ComPtr<D3D12MA::Allocation> downloadAlloc;
                CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST,
                    nullptr, &downloadAlloc, IID_NULL, nullptr));

                barrier.Transition.pResource = alloc->GetResource();
                barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)(uintptr_t)alloc->GetPrivateData();
                barriers.emplace_back(barrier);
                downloadAllocs.emplace_back(std::move(downloadAlloc));
            }
            else
                --resCount;
        });

    cl->ResourceBarrier(static_cast<UINT>(resCount), barriers.data());
    for (size_t i = 0, j = 0; i < resCount; ++j)
    {
        if (allocs[j]->GetResource()->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
        {
            cl->CopyResource(downloadAllocs.at(i)->GetResource(), allocs[j]->GetResource());
            barriers.at(i).Transition.StateAfter = barriers.at(i).Transition.StateBefore;
            barriers.at(i).Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
            ++i;
        }
    }
    cl->ResourceBarrier(static_cast<UINT>(resCount), barriers.data());
    EndCommandList(cl);

    for (auto& alloc : downloadAllocs)
    {
        D3D12_RANGE range = {};
        void* ptr;
        CHECK_HR(alloc->GetResource()->Map(0, &range, &ptr));
        CHECK_BOOL(ValidateData(ptr, alloc->GetResource()->GetDesc().Width, seed));
        alloc->GetResource()->Unmap(0, nullptr);
    }
}

static void SaveStatsStringToFile(const TestContext& ctx, const wchar_t* dstFilePath, BOOL detailed = TRUE)
{
    WCHAR* s = nullptr;
    ctx.allocator->BuildStatsString(&s, detailed);
    SaveFile(dstFilePath, s, wcslen(s) * sizeof(WCHAR));
    ctx.allocator->FreeStatsString(s);
}


static void TestDebugMargin(const TestContext& ctx)
{
    using namespace D3D12MA;

    if(D3D12MA_DEBUG_MARGIN == 0)
    {
        return;
    }

    wprintf(L"Test D3D12MA_DEBUG_MARGIN = %u\n", (uint32_t)D3D12MA_DEBUG_MARGIN);

    ALLOCATION_DESC allocDesc = {};

    D3D12_RESOURCE_DESC resDesc = {};

    CPOOL_DESC poolDesc = CPOOL_DESC{ D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };

    for(size_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
    {
        switch(algorithmIndex)
        {
        case 0: poolDesc.Flags = POOL_FLAG_NONE; break;
        case 1: poolDesc.Flags = POOL_FLAG_ALGORITHM_LINEAR; break;
        default: assert(0);
        }
        ComPtr<Pool> pool;
        CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

        allocDesc.CustomPool = pool.Get();

        // Create few buffers of different size.
        const size_t BUF_COUNT = 10;
        ComPtr<Allocation> buffers[BUF_COUNT];
        for(size_t allocIndex = 0; allocIndex < 10; ++allocIndex)
        {
            const bool isLast = allocIndex == BUF_COUNT - 1;
            FillResourceDescForBuffer(resDesc, (UINT64)(allocIndex + 1) * 0x10000);

            CHECK_HR(ctx.allocator->CreateResource(
                &allocDesc,
                &resDesc,
                D3D12_RESOURCE_STATE_GENERIC_READ,
                nullptr,
                &buffers[allocIndex],
                IID_NULL, nullptr));
        }

        // JSON dump
        wchar_t* json = nullptr;
        ctx.allocator->BuildStatsString(&json, TRUE);
        int I = 1; // Put breakpoint here to manually inspect json in a debugger.

        // Check if their offsets preserve margin between them.
        std::sort(buffers, buffers + BUF_COUNT, [](const ComPtr<Allocation>& lhs, const ComPtr<Allocation>& rhs) -> bool
            {
                if(lhs->GetHeap() != rhs->GetHeap())
                {
                    return lhs->GetHeap() < rhs->GetHeap();
                }
                return lhs->GetOffset() < rhs->GetOffset();
            });
        for(size_t i = 1; i < BUF_COUNT; ++i)
        {
            if(buffers[i]->GetHeap() == buffers[i - 1]->GetHeap())
            {
                const UINT64 allocStart = buffers[i]->GetOffset();
                const UINT64 prevAllocEnd = buffers[i - 1]->GetOffset() + buffers[i - 1]->GetSize();
                CHECK_BOOL(allocStart >= prevAllocEnd + D3D12MA_DEBUG_MARGIN);
            }
        }

        ctx.allocator->FreeStatsString(json);
    }
}

static void TestDebugMarginNotInVirtualAllocator(const TestContext& ctx)
{
    wprintf(L"Test D3D12MA_DEBUG_MARGIN not applied to virtual allocator\n");
    using namespace D3D12MA;
    constexpr size_t ALLOCATION_COUNT = 10;
    for(size_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
    {
        CVIRTUAL_BLOCK_DESC blockDesc = CVIRTUAL_BLOCK_DESC{ ALLOCATION_COUNT * MEGABYTE };
        switch(algorithmIndex)
        {
        case 0: blockDesc.Flags = VIRTUAL_BLOCK_FLAG_NONE; break;
        case 1: blockDesc.Flags = VIRTUAL_BLOCK_FLAG_ALGORITHM_LINEAR; break;
        default: assert(0);
        }

        ComPtr<VirtualBlock> block;
        CHECK_HR(CreateVirtualBlock(&blockDesc, &block));

        // Fill the entire block
        VirtualAllocation allocs[ALLOCATION_COUNT];
        for(size_t i = 0; i < ALLOCATION_COUNT; ++i)
        {
            CVIRTUAL_ALLOCATION_DESC allocDesc = CVIRTUAL_ALLOCATION_DESC{ 1 * MEGABYTE, 0 };
            CHECK_HR(block->Allocate(&allocDesc, &allocs[i], nullptr));
        }

        block->Clear();
    }
}

static void TestJson(const TestContext& ctx)
{
    wprintf(L"Test JSON\n");

    std::vector<ComPtr<D3D12MA::Pool>> pools;
    std::vector<ComPtr<D3D12MA::Allocation>> allocs;

    D3D12MA::ALLOCATION_DESC allocDesc = {};
    D3D12_RESOURCE_DESC resDesc = {};
    resDesc.Alignment = 0;
    resDesc.MipLevels = 1;
    resDesc.SampleDesc.Count = 1;
    resDesc.SampleDesc.Quality = 0;

    D3D12_RESOURCE_ALLOCATION_INFO allocInfo = {};
    allocInfo.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
    allocInfo.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;

    // Select if using custom pool or default
    for (UINT8 poolType = 0; poolType < 2; ++poolType)
    {
        // Select different heaps
        for (UINT8 heapType = 0; heapType < 5; ++heapType)
        {
            D3D12_RESOURCE_STATES state;
            D3D12_CPU_PAGE_PROPERTY cpuPageType = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
            D3D12_MEMORY_POOL memoryPool = D3D12_MEMORY_POOL_UNKNOWN;
            switch (heapType)
            {
            case 0:
                allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
                state = D3D12_RESOURCE_STATE_COMMON;
                break;
            case 1:
                allocDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD;
                state = D3D12_RESOURCE_STATE_GENERIC_READ;
                break;
            case 2:
                allocDesc.HeapType = D3D12_HEAP_TYPE_READBACK;
                state = D3D12_RESOURCE_STATE_COPY_DEST;
                break;
            case 3:
                allocDesc.HeapType = D3D12_HEAP_TYPE_CUSTOM;
                state = D3D12_RESOURCE_STATE_COMMON;
                cpuPageType = D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE;
                memoryPool = ctx.allocator->IsUMA() ? D3D12_MEMORY_POOL_L0 : D3D12_MEMORY_POOL_L1;
                break;
            case 4:
                allocDesc.HeapType = D3D12_HEAP_TYPE_CUSTOM;
                state = D3D12_RESOURCE_STATE_GENERIC_READ;
                cpuPageType = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE;
                memoryPool = D3D12_MEMORY_POOL_L0;
                break;
            }
            // Skip custom heaps for default pools
            if (poolType == 0 && heapType > 2)
                continue;
            const bool texturesPossible = heapType == 0 || heapType == 3;

            // Select different resource region types
            for (UINT8 resType = 0; resType < 3; ++resType)
            {
                allocDesc.ExtraHeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
                D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE;
                if (texturesPossible)
                {
                    switch (resType)
                    {
                    case 1:
                        allocDesc.ExtraHeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES;
                        break;
                    case 2:
                        allocDesc.ExtraHeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES;
                        resFlags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
                        break;
                    }
                }

                switch (poolType)
                {
                case 0:
                    allocDesc.CustomPool = nullptr;
                    break;
                case 1:
                {
                    ComPtr<D3D12MA::Pool> pool;
                    D3D12MA::POOL_DESC poolDesc = {};
                    poolDesc.HeapFlags = allocDesc.ExtraHeapFlags;
                    poolDesc.HeapProperties.Type = allocDesc.HeapType;
                    poolDesc.HeapProperties.CPUPageProperty = cpuPageType;
                    poolDesc.HeapProperties.MemoryPoolPreference = memoryPool;
                    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

                    allocDesc.CustomPool = pool.Get();
                    pools.emplace_back(std::move(pool));
                    break;
                }
                }

                // Select different allocation flags
                for (UINT8 allocFlag = 0; allocFlag < 2; ++allocFlag)
                {
                    switch (allocFlag)
                    {
                    case 0:
                        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
                        break;
                    case 1:
                        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
                        break;
                    }

                    // Select different alloc types (block, buffer, texture, etc.)
                    for (UINT8 allocType = 0; allocType < 5; ++allocType)
                    {
                        // Select different data stored in the allocation
                        for (UINT8 data = 0; data < 4; ++data)
                        {
                            ComPtr<D3D12MA::Allocation> alloc;

                            if (texturesPossible && resType != 0)
                            {
                                resDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
                                resDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
                                switch (allocType % 3)
                                {
                                case 0:
                                    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE1D;
                                    resDesc.Width = 512;
                                    resDesc.Height = 1;
                                    resDesc.DepthOrArraySize = 1;
                                    resDesc.Flags = resFlags;
                                    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, state, nullptr, &alloc, IID_NULL, nullptr));
                                    break;
                                case 1:
                                    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
                                    resDesc.Width = 1024;
                                    resDesc.Height = 512;
                                    resDesc.DepthOrArraySize = 1;
                                    resDesc.Flags = resFlags;
                                    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, state, nullptr, &alloc, IID_NULL, nullptr));
                                    break;
                                case 2:
                                    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D;
                                    resDesc.Width = 512;
                                    resDesc.Height = 256;
                                    resDesc.DepthOrArraySize = 128;
                                    resDesc.Flags = resFlags;
                                    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, state, nullptr, &alloc, IID_NULL, nullptr));
                                    break;
                                }
                            }
                            else
                            {
                                switch (allocType % 2)
                                {
                                case 0:
                                    CHECK_HR(ctx.allocator->AllocateMemory(&allocDesc, &allocInfo, &alloc));
                                    break;
                                case 1:
                                    FillResourceDescForBuffer(resDesc, 1024);
                                    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, state, nullptr, &alloc, IID_NULL, nullptr));
                                    break;
                                }
                            }

                            switch (data)
                            {
                            case 1:
                                alloc->SetPrivateData((void*)16112007);
                                break;
                            case 2:
                                alloc->SetName(L"SHEPURD");
                                break;
                            case 3:
                                alloc->SetPrivateData((void*)26012010);
                                alloc->SetName(L"JOKER");
                                break;
                            }
                            allocs.emplace_back(std::move(alloc));
                        }
                    }

                }
            }
        }
    }
    SaveStatsStringToFile(ctx, L"JSON_D3D12.json");
}

static void TestCommittedResourcesAndJson(const TestContext& ctx)
{
    wprintf(L"Test committed resources and JSON\n");
    
    const UINT count = 4;
    const UINT64 bufSize = 32ull * 1024;
    const wchar_t* names[count] = {
        L"Resource\nFoo\r\nBar",
        L"Resource \"'&<>?#@!&-=_+[]{};:,./\\",
        nullptr,
        L"",
    };

    ResourceWithAllocation resources[count];

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12MA::ALLOCATION_FLAG_COMMITTED };

    D3D12_RESOURCE_DESC resourceDesc;
    FillResourceDescForBuffer(resourceDesc, bufSize);

    for(UINT i = 0; i < count; ++i)
    {
        const bool receiveExplicitResource = i < 2;

        CHECK_HR( ctx.allocator->CreateResource(
            &allocDesc,
            &resourceDesc,
            D3D12_RESOURCE_STATE_COPY_DEST,
            NULL,
            &resources[i].allocation,
            __uuidof(ID3D12Resource),
            receiveExplicitResource ? (void**)&resources[i].resource : NULL));

        if(receiveExplicitResource)
        {
            ID3D12Resource* res = resources[i].resource.Get();
            CHECK_BOOL(res && res == resources[i].allocation->GetResource());
            const ULONG refCountAfterAdd = res->AddRef();
            CHECK_BOOL(refCountAfterAdd == 3);
            res->Release();
        }
        
        // Make sure it has implicit heap.
        CHECK_BOOL( resources[i].allocation->GetHeap() == NULL && resources[i].allocation->GetOffset() == 0 );

        resources[i].allocation->SetName(names[i]);
    }

    // Check names.
    for(UINT i = 0; i < count; ++i)
    {
        const wchar_t* const allocName = resources[i].allocation->GetName();
        if(allocName)
        {
            CHECK_BOOL( wcscmp(allocName, names[i]) == 0 );
        }
        else
        {
            CHECK_BOOL(names[i] == NULL);
        }
    }

    WCHAR* jsonString;
    ctx.allocator->BuildStatsString(&jsonString, TRUE);
    CHECK_BOOL(wcsstr(jsonString, L"\"Resource\\nFoo\\r\\nBar\"") != NULL);
    CHECK_BOOL(wcsstr(jsonString, L"\"Resource \\\"'&<>?#@!&-=_+[]{};:,.\\/\\\\\"") != NULL);
    CHECK_BOOL(wcsstr(jsonString, L"\"\"") != NULL);
    ctx.allocator->FreeStatsString(jsonString);
}

static void TestSmallBuffers(const TestContext& ctx)
{
    wprintf(L"Test small buffers\n");

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, 8 * KILOBYTE);

    D3D12_RESOURCE_DESC largeResDesc = resDesc;
    largeResDesc.Width = 128 * KILOBYTE;

    std::vector<ResourceWithAllocation> resources;

    // A large buffer placed inside the heap to allocate first block.
    {
        resources.emplace_back();
        ResourceWithAllocation& resWithAlloc = resources.back();
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &largeResDesc, D3D12_RESOURCE_STATE_COMMON,
            nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));
        CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());
        CHECK_BOOL(resWithAlloc.allocation->GetHeap()); // Expected to be placed.
    }

    // Test 1: COMMITTED.
    {
        resources.emplace_back();
        ResourceWithAllocation& resWithAlloc = resources.back();
        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,
            nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));
        CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());
        CHECK_BOOL(!resWithAlloc.allocation->GetHeap()); // Expected to be committed.
    }

    // Test 2: Default.
    {
        resources.emplace_back();
        ResourceWithAllocation& resWithAlloc = resources.back();
        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,
            nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));
        CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());
        // May or may not be committed, depending on the PREFER_SMALL_BUFFERS_COMMITTED
        // and TIGHT_ALIGNMENT settings.
        const bool isCommitted = resWithAlloc.allocation->GetHeap() == NULL;
        if (isCommitted)
            wprintf(L"    Small buffer %llu B inside a custom pool was created as committed.\n", resDesc.Width);
        else
            wprintf(L"    Small buffer %llu B inside a custom pool was created as placed.\n", resDesc.Width);
    }

    // Test 3: NEVER_ALLOCATE.
    {
        resources.emplace_back();
        ResourceWithAllocation& resWithAlloc = resources.back();
        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,
            nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));
        CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());
        CHECK_BOOL(resWithAlloc.allocation->GetHeap()); // Expected to be placed.
    }
}

static void TestCustomHeapFlags(const TestContext& ctx)
{
    wprintf(L"Test custom heap flags\n");

    // 1. Just memory heap with custom flags
    {
        D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
            D3D12_HEAP_TYPE_DEFAULT,
            D3D12MA::ALLOCATION_FLAG_NONE,
            NULL, // privateData
            D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES |
            D3D12_HEAP_FLAG_SHARED }; // Extra flag.

        D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = {};
        resAllocInfo.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
        resAllocInfo.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;

        ResourceWithAllocation res;
        CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &resAllocInfo, &res.allocation) );

        // Must be created as separate allocation.
        CHECK_BOOL( res.allocation->GetOffset() == 0 );
    }

    // 2. Committed resource with custom flags
    {
        D3D12_RESOURCE_DESC resourceDesc = {};
        resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
        resourceDesc.Alignment = 0;
        resourceDesc.Width = 1920;
        resourceDesc.Height = 1080;
        resourceDesc.DepthOrArraySize = 1;
        resourceDesc.MipLevels = 1;
        resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        resourceDesc.SampleDesc.Count = 1;
        resourceDesc.SampleDesc.Quality = 0;
        resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
        resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER;

        D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
            D3D12_HEAP_TYPE_DEFAULT,
            D3D12MA::ALLOCATION_FLAG_NONE,
            NULL, // privateData,
            D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER };

        ResourceWithAllocation res;
        CHECK_HR( ctx.allocator->CreateResource(
            &allocDesc,
            &resourceDesc,
            D3D12_RESOURCE_STATE_COMMON,
            NULL,
            &res.allocation,
            IID_PPV_ARGS(&res.resource)) );

        // Must be created as committed.
        CHECK_BOOL( res.allocation->GetHeap() == NULL );
    }
}

static void TestPlacedResources(const TestContext& ctx)
{
    wprintf(L"Test placed resources\n");

    const bool alwaysCommitted = (ctx.allocatorFlags & D3D12MA::ALLOCATOR_FLAG_ALWAYS_COMMITTED) != 0;

    const UINT count = 4;
    const UINT64 bufSize = 64ull * 1024;
    ResourceWithAllocation resources[count];

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_DEFAULT };

    D3D12_RESOURCE_DESC resourceDesc;
    FillResourceDescForBuffer(resourceDesc, bufSize);

    for(UINT i = 0; i < count; ++i)
    {
        CHECK_HR( ctx.allocator->CreateResource(
            &allocDesc,
            &resourceDesc,
            D3D12_RESOURCE_STATE_GENERIC_READ,
            NULL,
            &resources[i].allocation,
            IID_PPV_ARGS(&resources[i].resource)) );

        // Make sure it doesn't have implicit heap.
        if(!alwaysCommitted)
        {
            CHECK_BOOL( resources[i].allocation->GetHeap() != NULL );
        }
    }

    // Make sure at least some of the resources belong to the same heap, but their memory ranges don't overlap.
    bool sameHeapFound = false;
    for(size_t i = 0; i < count; ++i)
    {
        for(size_t j = i + 1; j < count; ++j)
        {
            const ResourceWithAllocation& resI = resources[i];
            const ResourceWithAllocation& resJ = resources[j];
            if(resI.allocation->GetHeap() != NULL &&
                resI.allocation->GetHeap() == resJ.allocation->GetHeap())
            {
                sameHeapFound = true;
                CHECK_BOOL(resI.allocation->GetOffset() + resI.allocation->GetSize() <= resJ.allocation->GetOffset() ||
                    resJ.allocation->GetOffset() + resJ.allocation->GetSize() <= resI.allocation->GetOffset());
            }
        }
    }
    if(!alwaysCommitted)
    {
        CHECK_BOOL(sameHeapFound);
    }

    // Additionally create a texture to see if no error occurs due to bad handling of Resource Tier.
    resourceDesc = {};
    resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resourceDesc.Alignment = 0;
    resourceDesc.Width = 1024;
    resourceDesc.Height = 1024;
    resourceDesc.DepthOrArraySize = 1;
    resourceDesc.MipLevels = 1;
    resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resourceDesc.SampleDesc.Count = 1;
    resourceDesc.SampleDesc.Quality = 0;
    resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
    ResourceWithAllocation textureRes;
    CHECK_HR( ctx.allocator->CreateResource(
        &allocDesc,
        &resourceDesc,
        D3D12_RESOURCE_STATE_COPY_DEST,
        NULL,
        &textureRes.allocation,
        IID_PPV_ARGS(&textureRes.resource)) );
    
    // Additionally create an MSAA render target to see if no error occurs due to bad handling of Resource Tier.
    resourceDesc = {};
    resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resourceDesc.Alignment = 0;
    resourceDesc.Width = 1920;
    resourceDesc.Height = 1080;
    resourceDesc.DepthOrArraySize = 1;
    resourceDesc.MipLevels = 1;
    resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resourceDesc.SampleDesc.Count = 2;
    resourceDesc.SampleDesc.Quality = 0;
    resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
    ResourceWithAllocation renderTargetRes;
    CHECK_HR( ctx.allocator->CreateResource(
        &allocDesc,
        &resourceDesc,
        D3D12_RESOURCE_STATE_RENDER_TARGET,
        NULL,
        &renderTargetRes.allocation,
        IID_PPV_ARGS(&renderTargetRes.resource)) );
}

static void TestOtherComInterface(const TestContext& ctx)
{
    wprintf(L"Test other COM interface\n");

    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, 0x10000);

    for(uint32_t i = 0; i < 2; ++i)
    {
        D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_DEFAULT };
        if(i == 1)
        {
            allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
        }

        ComPtr<D3D12MA::Allocation> alloc;
        ComPtr<ID3D12Pageable> pageable;
        CHECK_HR(ctx.allocator->CreateResource(
            &allocDesc,
            &resDesc,
            D3D12_RESOURCE_STATE_COMMON,
            nullptr, // pOptimizedClearValue
            &alloc,
            IID_PPV_ARGS(&pageable)));

        // Do something with the interface to make sure it's valid.
        ComPtr<ID3D12Device> device;
        CHECK_HR(pageable->GetDevice(IID_PPV_ARGS(&device)));
        CHECK_BOOL(device.Get() == ctx.device);
    }
}

static void TestCustomPools(const TestContext& ctx)
{
    wprintf(L"Test custom pools\n");

    // # Fetch global stats 1

    D3D12MA::TotalStatistics globalStatsBeg = {};
    ctx.allocator->CalculateStatistics(&globalStatsBeg);

    // # Create pool, 1..2 blocks of 11 MB

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        D3D12MA::POOL_FLAG_NONE,
        11 * MEGABYTE, // blockSize
        1, // minBlockCount
        2, // maxBlockCount
        D3D12_RESIDENCY_PRIORITY_HIGH }; // Test some residency priority, by the way.

    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR( ctx.allocator->CreatePool(&poolDesc, &pool) );

    // # Validate stats for empty pool

    D3D12MA::DetailedStatistics poolStats = {};
    pool->CalculateStatistics(&poolStats);
    CHECK_BOOL( poolStats.Stats.BlockCount == 1 );
    CHECK_BOOL( poolStats.Stats.AllocationCount == 0 );
    CHECK_BOOL( poolStats.Stats.AllocationBytes == 0 );
    CHECK_BOOL( poolStats.Stats.BlockBytes - poolStats.Stats.AllocationBytes ==
        poolStats.Stats.BlockCount * poolDesc.BlockSize );

    // # SetName and GetName

    static const wchar_t* NAME = L"Custom pool name 1";
    pool->SetName(NAME);
    CHECK_BOOL( wcscmp(pool->GetName(), NAME) == 0 );

    // # Create buffers 2x 5 MB

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };
    allocDesc.ExtraHeapFlags = (D3D12_HEAP_FLAGS)0xCDCDCDCD; // Should be ignored.
    allocDesc.HeapType = (D3D12_HEAP_TYPE)0xCDCDCDCD; // Should be ignored.

    const UINT64 BUFFER_SIZE = 5 * MEGABYTE;
    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, BUFFER_SIZE);

    ComPtr<D3D12MA::Allocation> allocs[4];
    for(uint32_t i = 0; i < 2; ++i)
    {
        CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
            D3D12_RESOURCE_STATE_GENERIC_READ,
            NULL, // pOptimizedClearValue
            &allocs[i],
            __uuidof(ID3D12Resource), NULL) ); // riidResource, ppvResource
    }

    // # Validate pool stats now

    pool->CalculateStatistics(&poolStats);
    CHECK_BOOL( poolStats.Stats.BlockCount == 1 );
    CHECK_BOOL( poolStats.Stats.AllocationCount == 2 );
    CHECK_BOOL( poolStats.Stats.AllocationBytes == 2 * BUFFER_SIZE );
    CHECK_BOOL( poolStats.Stats.BlockBytes - poolStats.Stats.AllocationBytes ==
        poolDesc.BlockSize - poolStats.Stats.AllocationBytes );

    // # Check that global stats are updated as well

    D3D12MA::TotalStatistics globalStatsCurr = {};
    ctx.allocator->CalculateStatistics(&globalStatsCurr);

    CHECK_BOOL( globalStatsCurr.Total.Stats.AllocationCount ==
        globalStatsBeg.Total.Stats.AllocationCount + poolStats.Stats.AllocationCount );
    CHECK_BOOL( globalStatsCurr.Total.Stats.BlockCount ==
        globalStatsBeg.Total.Stats.BlockCount + poolStats.Stats.BlockCount );
    CHECK_BOOL( globalStatsCurr.Total.Stats.AllocationBytes ==
        globalStatsBeg.Total.Stats.AllocationBytes + poolStats.Stats.AllocationBytes );

    // # NEVER_ALLOCATE and COMMITTED should fail
    // (Committed allocations not allowed in this pool because BlockSize != 0.)

    for(uint32_t i = 0; i < 2; ++i)
    {
        allocDesc.Flags = i == 0 ?
            D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE:
            D3D12MA::ALLOCATION_FLAG_COMMITTED;
        ComPtr<D3D12MA::Allocation> alloc;
        const HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &resDesc,
            D3D12_RESOURCE_STATE_GENERIC_READ,
            NULL, // pOptimizedClearValue
            &alloc,
            __uuidof(ID3D12Resource), NULL); // riidResource, ppvResource
        CHECK_BOOL( FAILED(hr) );
    }

    // # 3 more buffers. 3rd should fail.

    allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
    for(uint32_t i = 2; i < 5; ++i)
    {
        ComPtr<D3D12MA::Allocation> alloc;
        HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &resDesc,
            D3D12_RESOURCE_STATE_GENERIC_READ,
            NULL, // pOptimizedClearValue
            &alloc,
            __uuidof(ID3D12Resource), NULL); // riidResource, ppvResource
        if(i < 4)
        {
            CHECK_HR( hr );
            allocs[i] = std::move(alloc);
        }
        else
        {
            CHECK_BOOL( FAILED(hr) );
        }
    }

    pool->CalculateStatistics(&poolStats);
    CHECK_BOOL( poolStats.Stats.BlockCount == 2 );
    CHECK_BOOL( poolStats.Stats.AllocationCount == 4 );
    CHECK_BOOL( poolStats.Stats.AllocationBytes == 4 * BUFFER_SIZE );
    CHECK_BOOL( poolStats.Stats.BlockBytes - poolStats.Stats.AllocationBytes ==
        poolStats.Stats.BlockCount * poolDesc.BlockSize - poolStats.Stats.AllocationBytes );

    // # Make room, AllocateMemory, CreateAliasingResource

    allocs[3].Reset();
    allocs[0].Reset();

    D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = {};
    resAllocInfo.SizeInBytes = 5 * MEGABYTE;
    resAllocInfo.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;

    CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &resAllocInfo, &allocs[0]) );

    resDesc.Width = 1 * MEGABYTE;
    ComPtr<ID3D12Resource> res;
    CHECK_HR( ctx.allocator->CreateAliasingResource(allocs[0].Get(),
        0, // AllocationLocalOffset
        &resDesc,
        D3D12_RESOURCE_STATE_GENERIC_READ,
        NULL, // pOptimizedClearValue
        IID_PPV_ARGS(&res)) );

    // JSON dump
    wchar_t* json = nullptr;
    ctx.allocator->BuildStatsString(&json, TRUE);
    ctx.allocator->FreeStatsString(json);
}

static void TestPoolsAndAllocationParameters(const TestContext& ctx)
{
    wprintf(L"Test pools and allocation parameters\n");

    ComPtr<D3D12MA::Pool> pool1, pool2;
    std::vector<ComPtr<D3D12MA::Allocation>> bufs;

    D3D12MA::ALLOCATION_DESC allocDesc = {};

    uint32_t totalNewAllocCount = 0, totalNewBlockCount = 0;
    D3D12MA::TotalStatistics statsBeg, statsEnd;
    ctx.allocator->CalculateStatistics(&statsBeg);

    HRESULT hr;
    ComPtr<D3D12MA::Allocation> alloc;

    // poolTypeI:
    // 0 = default pool
    // 1 = custom pool, default (flexible) block size and block count
    // 2 = custom pool, fixed block size and limited block count
    for(size_t poolTypeI = 0; poolTypeI < 3; ++poolTypeI)
    {
        if(poolTypeI == 0)
        {
            allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
            allocDesc.CustomPool = nullptr;
        }
        else if(poolTypeI == 1)
        {
            D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{};
            poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
            poolDesc.HeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
            hr = ctx.allocator->CreatePool(&poolDesc, &pool1);
            CHECK_HR(hr);
            allocDesc.CustomPool = pool1.Get();
        }
        else if(poolTypeI == 2)
        {
            D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
                D3D12_HEAP_TYPE_DEFAULT,
                D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
                D3D12MA::POOL_FLAG_NONE,
                2 * MEGABYTE + MEGABYTE / 2, // blockSize = 2.5 MB
                0, // minBlockCount
                1 }; // maxBlockCount
            hr = ctx.allocator->CreatePool(&poolDesc, &pool2);
            CHECK_HR(hr);
            allocDesc.CustomPool = pool2.Get();
        }

        uint32_t poolAllocCount = 0, poolBlockCount = 0;
        D3D12_RESOURCE_DESC resDesc;
        FillResourceDescForBuffer(resDesc, MEGABYTE);

        // Default parameters
        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
        hr = ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &alloc, IID_NULL, nullptr);
        CHECK_BOOL(SUCCEEDED(hr) && alloc && alloc->GetResource());
        ID3D12Heap* const defaultAllocHeap = alloc->GetHeap();
        const UINT64 defaultAllocOffset = alloc->GetOffset();
        bufs.push_back(std::move(alloc));
        ++poolAllocCount;

        // COMMITTED. Should not try pool2 as it may assert on invalid call.
        if(poolTypeI != 2)
        {
            allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
            hr = ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &alloc, IID_NULL, nullptr);
            CHECK_BOOL(SUCCEEDED(hr) && alloc && alloc->GetResource());
            CHECK_BOOL(alloc->GetOffset() == 0); // Committed
            CHECK_BOOL(alloc->GetHeap() == nullptr); // Committed
            bufs.push_back(std::move(alloc));
            ++poolAllocCount;
        }

        // NEVER_ALLOCATE #1
        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;
        hr = ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &alloc, IID_NULL, nullptr);
        CHECK_BOOL(SUCCEEDED(hr) && alloc && alloc->GetResource());
        CHECK_BOOL(alloc->GetHeap() == defaultAllocHeap); // Same memory block as default one.
        CHECK_BOOL(alloc->GetOffset() != defaultAllocOffset);
        bufs.push_back(std::move(alloc));
        ++poolAllocCount;

        // NEVER_ALLOCATE #2. Should fail in pool2 as it has no space.
        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;
        hr = ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &alloc, IID_NULL, nullptr);
        if(poolTypeI == 2)
            CHECK_BOOL(FAILED(hr));
        else
        {
            CHECK_BOOL(SUCCEEDED(hr) && alloc && alloc->GetResource());
            bufs.push_back(std::move(alloc));
            ++poolAllocCount;
        }

        // Pool stats
        switch(poolTypeI)
        {
        case 0: poolBlockCount = 1; break; // At least 1 added for dedicated allocation.
        case 1: poolBlockCount = 2; break; // 1 for custom pool block and 1 for dedicated allocation.
        case 2: poolBlockCount = 1; break; // Only custom pool, no dedicated allocation.
        }

        if(poolTypeI > 0)
        {
            D3D12MA::DetailedStatistics poolStats = {};
            (poolTypeI == 2 ? pool2 : pool1)->CalculateStatistics(&poolStats);
            CHECK_BOOL(poolStats.Stats.AllocationCount == poolAllocCount);
            CHECK_BOOL(poolStats.Stats.AllocationBytes == poolAllocCount * MEGABYTE);
            CHECK_BOOL(poolStats.Stats.BlockCount == poolBlockCount);
        }

        totalNewAllocCount += poolAllocCount;
        totalNewBlockCount += poolBlockCount;
    }

    ctx.allocator->CalculateStatistics(&statsEnd);

    CHECK_BOOL(statsEnd.Total.Stats.AllocationCount ==
        statsBeg.Total.Stats.AllocationCount + totalNewAllocCount);
    CHECK_BOOL(statsEnd.Total.Stats.BlockCount >=
        statsBeg.Total.Stats.BlockCount + totalNewBlockCount);
    CHECK_BOOL(statsEnd.Total.Stats.AllocationBytes ==
        statsBeg.Total.Stats.AllocationBytes + totalNewAllocCount * MEGABYTE);
}

static void TestCustomPool_MinAllocationAlignment(const TestContext& ctx)
{
    wprintf(L"Test custom pool MinAllocationAlignment\n");

    const UINT64 BUFFER_SIZE = 32;
    constexpr size_t BUFFER_COUNT = 4;
    const UINT64 MIN_ALIGNMENT = 128 * 1024;

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_UPLOAD,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };
    poolDesc.MinAllocationAlignment = MIN_ALIGNMENT;

    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR( ctx.allocator->CreatePool(&poolDesc, &pool) );

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, BUFFER_SIZE);

    ComPtr<D3D12MA::Allocation> allocs[BUFFER_COUNT];
    for(size_t i = 0; i < BUFFER_COUNT; ++i)
    {
        CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
            D3D12_RESOURCE_STATE_GENERIC_READ,
            NULL, // pOptimizedClearValue
            &allocs[i],
            IID_NULL, NULL) ); // riidResource, ppvResource
        CHECK_BOOL(allocs[i]->GetOffset() % MIN_ALIGNMENT == 0);
    }
}

static void TestCustomPool_Committed(const TestContext& ctx)
{
    wprintf(L"Test custom pool committed\n");

    const UINT64 BUFFER_SIZE = 32;

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR( ctx.allocator->CreatePool(&poolDesc, &pool) );

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        pool.Get(),
        D3D12MA::ALLOCATION_FLAG_COMMITTED };

    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, BUFFER_SIZE);

    ComPtr<D3D12MA::Allocation> alloc;
    CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
        D3D12_RESOURCE_STATE_COMMON,
        NULL, // pOptimizedClearValue
        &alloc,
        IID_NULL, NULL) ); // riidResource, ppvResource
    CHECK_BOOL(alloc->GetHeap() == NULL);
    CHECK_BOOL(alloc->GetResource() != NULL);
    CHECK_BOOL(alloc->GetOffset() == 0);
}

static void TestCustomPool_AlwaysCommitted(const TestContext& ctx)
{
    wprintf(L"Test custom pool always committed\n");

    const UINT64 BUFFER_SIZE = 256;

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        D3D12MA::POOL_FLAG_ALWAYS_COMMITTED };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, BUFFER_SIZE);

    ComPtr<D3D12MA::Allocation> alloc;
    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc,
        D3D12_RESOURCE_STATE_COMMON,
        NULL, // pOptimizedClearValue
        &alloc,
        IID_NULL, NULL)); // riidResource, ppvResource
    CHECK_BOOL(alloc->GetHeap() == NULL);
    CHECK_BOOL(alloc->GetResource() != NULL);
    CHECK_BOOL(alloc->GetOffset() == 0);

    D3D12MA::Statistics stats = {};
    pool->GetStatistics(&stats);
    CHECK_BOOL(stats.AllocationBytes >= BUFFER_SIZE);
    CHECK_BOOL(stats.AllocationCount == 1);
    CHECK_BOOL(stats.BlockBytes >= BUFFER_SIZE);
    CHECK_BOOL(stats.BlockCount == 1);

    D3D12MA::DetailedStatistics detailedStats = {};
    pool->CalculateStatistics(&detailedStats);
    CHECK_BOOL(detailedStats.Stats == stats);
    CHECK_BOOL(detailedStats.AllocationSizeMin == stats.AllocationBytes);
    CHECK_BOOL(detailedStats.AllocationSizeMax == stats.AllocationBytes);
    CHECK_BOOL(detailedStats.UnusedRangeCount == 0);
    CHECK_BOOL(detailedStats.UnusedRangeSizeMax == 0);
}

static HRESULT TestCustomHeap(const TestContext& ctx, const D3D12_HEAP_PROPERTIES& heapProps)
{
    D3D12MA::TotalStatistics globalStatsBeg = {};
    ctx.allocator->CalculateStatistics(&globalStatsBeg);

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        heapProps,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        D3D12MA::POOL_FLAG_NONE,
        10 * MEGABYTE, // blockSize
        1, // minBlockCount
        1 }; // maxBlockCount

    const UINT64 BUFFER_SIZE = 1 * MEGABYTE;

    ComPtr<D3D12MA::Pool> pool;
    HRESULT hr = ctx.allocator->CreatePool(&poolDesc, &pool);
    if(SUCCEEDED(hr))
    {
        D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

        D3D12_RESOURCE_DESC resDesc;
        FillResourceDescForBuffer(resDesc, BUFFER_SIZE);

        // Pool already allocated a block. We don't expect CreatePlacedResource to fail.
        ComPtr<D3D12MA::Allocation> alloc;
        CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
            D3D12_RESOURCE_STATE_COPY_DEST,
            NULL, // pOptimizedClearValue
            &alloc,
            __uuidof(ID3D12Resource), NULL) ); // riidResource, ppvResource

        D3D12MA::TotalStatistics globalStatsCurr = {};
        ctx.allocator->CalculateStatistics(&globalStatsCurr);

        // Make sure it is accounted only in CUSTOM heap not any of the standard heaps.
        CHECK_BOOL(memcmp(&globalStatsCurr.HeapType[0], &globalStatsBeg.HeapType[0], sizeof(D3D12MA::DetailedStatistics)) == 0);
        CHECK_BOOL(memcmp(&globalStatsCurr.HeapType[1], &globalStatsBeg.HeapType[1], sizeof(D3D12MA::DetailedStatistics)) == 0);
        CHECK_BOOL(memcmp(&globalStatsCurr.HeapType[2], &globalStatsBeg.HeapType[2], sizeof(D3D12MA::DetailedStatistics)) == 0);
        CHECK_BOOL( globalStatsCurr.HeapType[3].Stats.AllocationCount == globalStatsBeg.HeapType[3].Stats.AllocationCount + 1 );
        CHECK_BOOL( globalStatsCurr.HeapType[3].Stats.BlockCount == globalStatsBeg.HeapType[3].Stats.BlockCount + 1 );
        CHECK_BOOL( globalStatsCurr.HeapType[3].Stats.AllocationBytes == globalStatsBeg.HeapType[3].Stats.AllocationBytes + BUFFER_SIZE );
        CHECK_BOOL( globalStatsCurr.Total.Stats.AllocationCount == globalStatsBeg.Total.Stats.AllocationCount + 1 );
        CHECK_BOOL( globalStatsCurr.Total.Stats.BlockCount == globalStatsBeg.Total.Stats.BlockCount + 1 );
        CHECK_BOOL( globalStatsCurr.Total.Stats.AllocationBytes == globalStatsBeg.Total.Stats.AllocationBytes + BUFFER_SIZE );

        // Map and write some data.
        if(heapProps.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE ||
            heapProps.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)
        {
            ID3D12Resource* const res = alloc->GetResource();

            UINT* mappedPtr = nullptr;
            const D3D12_RANGE readRange = {0, 0};
            CHECK_HR(res->Map(0, &readRange, (void**)&mappedPtr));
            
            *mappedPtr = 0xDEADC0DE;
            
            res->Unmap(0, nullptr);
        }
    }

    return hr;
}

static void TestCustomHeaps(const TestContext& ctx)
{
    wprintf(L"Test custom heap\n");

    D3D12_HEAP_PROPERTIES heapProps = {};

    // Use custom pool but the same as READBACK, which should be always available.
    heapProps.Type = D3D12_HEAP_TYPE_CUSTOM;
    heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
    heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; // System memory
    HRESULT hr = TestCustomHeap(ctx, heapProps);
    CHECK_HR(hr);
}

static void TestStandardCustomCommittedPlaced(const TestContext& ctx)
{
    wprintf(L"Test standard, custom, committed, placed\n");

    static const D3D12_HEAP_TYPE heapType = D3D12_HEAP_TYPE_DEFAULT;
    static const UINT64 bufferSize = 1024;

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        heapType,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    std::vector<ComPtr<D3D12MA::Allocation>> allocations;
    
    D3D12MA::TotalStatistics statsBeg = {};
    D3D12MA::DetailedStatistics poolStatInfoBeg = {};
    ctx.allocator->CalculateStatistics(&statsBeg);
    pool->CalculateStatistics(&poolStatInfoBeg);

    size_t poolAllocCount = 0;

    D3D12_RESOURCE_DESC resDesc = {};
    FillResourceDescForBuffer(resDesc, bufferSize);

    for(uint32_t standardCustomI = 0; standardCustomI < 2; ++standardCustomI)
    {
        const bool useCustomPool = standardCustomI > 0;
        for(uint32_t flagsI = 0; flagsI < 3; ++flagsI)
        {
            const bool useCommitted = flagsI > 0;
            const bool neverAllocate = flagsI > 1;

            D3D12MA::ALLOCATION_DESC allocDesc = {};
            if(useCustomPool)
            {
                allocDesc.CustomPool = pool.Get();
                allocDesc.HeapType = (D3D12_HEAP_TYPE)0xCDCDCDCD; // Should be ignored.
                allocDesc.ExtraHeapFlags = (D3D12_HEAP_FLAGS)0xCDCDCDCD; // Should be ignored.
            }
            else
                allocDesc.HeapType = heapType;
            if(useCommitted)
                allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_COMMITTED;
            if(neverAllocate)
                allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;

            ComPtr<D3D12MA::Allocation> allocPtr = NULL;
            HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &resDesc,
                D3D12_RESOURCE_STATE_COMMON,
                NULL, // pOptimizedClearValue
                &allocPtr, IID_NULL, NULL);
            CHECK_BOOL(SUCCEEDED(hr) == (allocPtr != NULL));
            if(allocPtr)
            {
                allocations.push_back(allocPtr);
                if(useCustomPool)
                    ++poolAllocCount;
            }

            bool expectSuccess = !neverAllocate; // NEVER_ALLOCATE should always fail with COMMITTED.
            CHECK_BOOL(expectSuccess == SUCCEEDED(hr));
            if(SUCCEEDED(hr) && useCommitted)
            {
                CHECK_BOOL(allocPtr->GetHeap() == NULL); // Committed allocation has implicit heap.
            }
        }
    }

    D3D12MA::TotalStatistics statsEnd = {};
    D3D12MA::DetailedStatistics poolStatInfoEnd = {};
    ctx.allocator->CalculateStatistics(&statsEnd);
    pool->CalculateStatistics(&poolStatInfoEnd);

    CHECK_BOOL(statsEnd.Total.Stats.AllocationCount == statsBeg.Total.Stats.AllocationCount + allocations.size());
    CHECK_BOOL(statsEnd.Total.Stats.AllocationBytes >= statsBeg.Total.Stats.AllocationBytes + allocations.size() * bufferSize);
    CHECK_BOOL(statsEnd.HeapType[0].Stats.AllocationCount == statsBeg.HeapType[0].Stats.AllocationCount + allocations.size());
    CHECK_BOOL(statsEnd.HeapType[0].Stats.AllocationBytes >= statsBeg.HeapType[0].Stats.AllocationBytes + allocations.size() * bufferSize);
    CHECK_BOOL(poolStatInfoEnd.Stats.AllocationCount == poolStatInfoBeg.Stats.AllocationCount + poolAllocCount);
    CHECK_BOOL(poolStatInfoEnd.Stats.AllocationBytes >= poolStatInfoBeg.Stats.AllocationBytes + poolAllocCount * bufferSize);
}

static void TestAliasingMemory(const TestContext& ctx)
{
    wprintf(L"Test aliasing memory\n");

    D3D12_RESOURCE_DESC resDesc1 = {};
    resDesc1.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resDesc1.Alignment = 0;
    resDesc1.Width = 1920;
    resDesc1.Height = 1080;
    resDesc1.DepthOrArraySize = 1;
    resDesc1.MipLevels = 1;
    resDesc1.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resDesc1.SampleDesc.Count = 1;
    resDesc1.SampleDesc.Quality = 0;
    resDesc1.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resDesc1.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;

    D3D12_RESOURCE_DESC resDesc2 = {};
    resDesc2.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resDesc2.Alignment = 0;
    resDesc2.Width = 1024;
    resDesc2.Height = 1024;
    resDesc2.DepthOrArraySize = 1;
    resDesc2.MipLevels = 0;
    resDesc2.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resDesc2.SampleDesc.Count = 1;
    resDesc2.SampleDesc.Quality = 0;
    resDesc2.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resDesc2.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;

    const D3D12_RESOURCE_ALLOCATION_INFO allocInfo1 =
        ctx.device->GetResourceAllocationInfo(0, 1, &resDesc1);
    const D3D12_RESOURCE_ALLOCATION_INFO allocInfo2 =
        ctx.device->GetResourceAllocationInfo(0, 1, &resDesc2);

    D3D12_RESOURCE_ALLOCATION_INFO finalAllocInfo = {};
    finalAllocInfo.Alignment = std::max(allocInfo1.Alignment, allocInfo2.Alignment);
    finalAllocInfo.SizeInBytes = std::max(allocInfo1.SizeInBytes, allocInfo2.SizeInBytes);

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12MA::ALLOCATION_FLAG_NONE,
        NULL, // privateData
        D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES };

    ComPtr<D3D12MA::Allocation> alloc;
    CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &finalAllocInfo, &alloc) );
    CHECK_BOOL(alloc != NULL && alloc->GetHeap() != NULL);

    ComPtr<ID3D12Resource> res1;
    CHECK_HR( ctx.allocator->CreateAliasingResource(
        alloc.Get(),
        0, // AllocationLocalOffset
        &resDesc1,
        D3D12_RESOURCE_STATE_COMMON,
        NULL, // pOptimizedClearValue
        IID_PPV_ARGS(&res1)) );
    CHECK_BOOL(res1 != NULL);

    ComPtr<ID3D12Resource> res2;
    CHECK_HR( ctx.allocator->CreateAliasingResource(
        alloc.Get(),
        0, // AllocationLocalOffset
        &resDesc2,
        D3D12_RESOURCE_STATE_COMMON,
        NULL, // pOptimizedClearValue
        IID_PPV_ARGS(&res2)) );
    CHECK_BOOL(res2 != NULL);

    // You can use res1 and res2, but not at the same time!
}

static void TestAliasingImplicitCommitted(const TestContext& ctx)
{
    wprintf(L"Test aliasing implicit dedicated\n");

    // The buffer will be large enough to be allocated as committed.
    // We still need it to have an explicit heap to be able to alias.

    D3D12_RESOURCE_DESC resDesc = {};
    FillResourceDescForBuffer(resDesc, 300 * MEGABYTE);

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_UPLOAD,
        D3D12MA::ALLOCATION_FLAG_CAN_ALIAS };

    ComPtr<D3D12MA::Allocation> alloc;
    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc,
        D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
        &alloc, IID_NULL, NULL));
    CHECK_BOOL(alloc != NULL && alloc->GetHeap() != NULL);

    resDesc.Width = 200 * MEGABYTE;
    ComPtr<ID3D12Resource> aliasingRes;
    CHECK_HR(ctx.allocator->CreateAliasingResource(alloc.Get(),
        0, // AllocationLocalOffset
        &resDesc,
        D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&aliasingRes)));
    CHECK_BOOL(aliasingRes != NULL);
}

static void TestPoolMsaaTextureAsCommitted(const TestContext& ctx)
{
    wprintf(L"Test MSAA texture always as committed in pool\n");

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES,
        D3D12MA::POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    D3D12_RESOURCE_DESC resDesc = {};
    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resDesc.Width = 1024;
    resDesc.Height = 512;
    resDesc.DepthOrArraySize = 1;
    resDesc.MipLevels = 1;
    resDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resDesc.SampleDesc.Count = 2;
    resDesc.SampleDesc.Quality = 0;
    resDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;

    ComPtr<D3D12MA::Allocation> alloc;
    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_RENDER_TARGET, nullptr, &alloc, IID_NULL, nullptr));
    // Committed allocation should not have explicit heap
    CHECK_BOOL(alloc->GetHeap() == nullptr);
}

static void TestMapping(const TestContext& ctx)
{
    wprintf(L"Test mapping\n");

    const UINT count = 10;
    const UINT64 bufSize = 32ull * 1024;
    ResourceWithAllocation resources[count];

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_UPLOAD };

    D3D12_RESOURCE_DESC resourceDesc;
    FillResourceDescForBuffer(resourceDesc, bufSize);

    for(UINT i = 0; i < count; ++i)
    {
        CHECK_HR( ctx.allocator->CreateResource(
            &allocDesc,
            &resourceDesc,
            D3D12_RESOURCE_STATE_GENERIC_READ,
            NULL,
            &resources[i].allocation,
            IID_PPV_ARGS(&resources[i].resource)) );

        void* mappedPtr = NULL;
        CHECK_HR( resources[i].resource->Map(0, &EMPTY_RANGE, &mappedPtr) );

        FillData(mappedPtr, bufSize, i);

        // Unmap every other buffer. Leave others mapped.
        if((i % 2) != 0)
        {
            resources[i].resource->Unmap(0, NULL);
        }
    }
}

static inline bool StatisticsEqual(const D3D12MA::DetailedStatistics& lhs, const D3D12MA::DetailedStatistics& rhs)
{
    return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
}

static inline bool StatisticsEqual(const D3D12MA::Statistics& lhs, const D3D12MA::Statistics& rhs)
{
    return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
}

static void CheckStatistics(const D3D12MA::DetailedStatistics& stats)
{
    CHECK_BOOL(stats.Stats.AllocationBytes <= stats.Stats.BlockBytes);
    if(stats.Stats.AllocationBytes > 0)
    {
        CHECK_BOOL(stats.Stats.AllocationCount > 0);
        CHECK_BOOL(stats.AllocationSizeMin <= stats.AllocationSizeMax);
    }
    if(stats.UnusedRangeCount > 0)
    {
        CHECK_BOOL(stats.UnusedRangeSizeMax > 0);
        CHECK_BOOL(stats.UnusedRangeSizeMin <= stats.UnusedRangeSizeMax);
    }
}

static void CheckBudgetBasics(const TestContext& ctx,
    const D3D12MA::Budget& localBudget, const D3D12MA::Budget& nonLocalBudget)
{
    CHECK_BOOL(localBudget.BudgetBytes > 0);
    CHECK_BOOL(localBudget.BudgetBytes <= ctx.allocator->GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_LOCAL));
    CHECK_BOOL(localBudget.Stats.AllocationBytes <= localBudget.Stats.BlockBytes);

    // Discrete graphics card with separate video memory.
    if (!ctx.allocator->IsUMA())
    {
        CHECK_BOOL(nonLocalBudget.BudgetBytes > 0);
        CHECK_BOOL(nonLocalBudget.BudgetBytes <= ctx.allocator->GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL));
        CHECK_BOOL(nonLocalBudget.Stats.AllocationBytes <= nonLocalBudget.Stats.BlockBytes);
    }
}

static D3D12MA::DetailedStatistics GetEmptyDetailedStatistics()
{
    D3D12MA::DetailedStatistics out = {};
    out.AllocationSizeMin = UINT64_MAX;
    out.UnusedRangeSizeMin = UINT64_MAX;
    return out;
}

static void AddDetailedStatistics(D3D12MA::DetailedStatistics& inoutSum, const D3D12MA::DetailedStatistics& stats)
{
    inoutSum.Stats.AllocationBytes += stats.Stats.AllocationBytes;
    inoutSum.Stats.AllocationCount += stats.Stats.AllocationCount;
    inoutSum.Stats.BlockBytes += stats.Stats.BlockBytes;
    inoutSum.Stats.BlockCount += stats.Stats.BlockCount;
    inoutSum.UnusedRangeCount += stats.UnusedRangeCount;
    inoutSum.AllocationSizeMax = std::max(inoutSum.AllocationSizeMax, stats.AllocationSizeMax);
    inoutSum.AllocationSizeMin = std::min(inoutSum.AllocationSizeMin, stats.AllocationSizeMin);
    inoutSum.UnusedRangeSizeMax = std::max(inoutSum.UnusedRangeSizeMax, stats.UnusedRangeSizeMax);
    inoutSum.UnusedRangeSizeMin = std::min(inoutSum.UnusedRangeSizeMin, stats.UnusedRangeSizeMin);
}

static void CheckTotalStatistics(const D3D12MA::TotalStatistics& stats)
{
    D3D12MA::DetailedStatistics sum = GetEmptyDetailedStatistics();
    for (size_t i = 0; i < _countof(stats.HeapType); ++i)
    {
        AddDetailedStatistics(sum, stats.HeapType[i]);
    }
    CHECK_BOOL(StatisticsEqual(sum, stats.Total));

    sum = GetEmptyDetailedStatistics();
    for (size_t i = 0; i < _countof(stats.MemorySegmentGroup); ++i)
    {
        AddDetailedStatistics(sum, stats.MemorySegmentGroup[i]);
    }
    CHECK_BOOL(StatisticsEqual(sum, stats.Total));
}

static void TestStats(const TestContext& ctx)
{
    using namespace D3D12MA;

    wprintf(L"Test stats\n");

    constexpr UINT64 BUF_SIZE = 10 * MEGABYTE;
    constexpr UINT32 BUF_COUNT = 4;
    constexpr UINT64 PREALLOCATED_BLOCK_SIZE = BUF_SIZE * (BUF_COUNT + 1);

    /*
    Test 0: ALLOCATION_FLAG_COMMITTED.
    Test 1: normal allocations.
    Test 2: allocations in a custom pool.
    Test 3: allocations in a custom pool, COMMITTED.
    Test 4: allocations in a custom pool with preallocated memory.
    */
    for (uint32_t testIndex = 0; testIndex < 5; ++testIndex)
    {
        const bool usePool = testIndex >= 2;
        const bool useCommitted = testIndex == 0 || testIndex == 3;
        const bool usePreallocated = testIndex == 4;

        // Get stats "Beg".
        Budget localBudgetBeg = {};
        Budget nonLocalBudgetBeg = {};
        ctx.allocator->GetBudget(&localBudgetBeg, &nonLocalBudgetBeg);
        CheckBudgetBasics(ctx, localBudgetBeg, nonLocalBudgetBeg);

        TotalStatistics statsBeg = {};
        ctx.allocator->CalculateStatistics(&statsBeg);
        CheckTotalStatistics(statsBeg);

        // Create pool.
        ComPtr<Pool> pool;
        if (usePool)
        {
            POOL_DESC poolDesc = CPOOL_DESC(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
            if (usePreallocated)
            {
                poolDesc.BlockSize = PREALLOCATED_BLOCK_SIZE;
                poolDesc.MinBlockCount = 1;
                poolDesc.MaxBlockCount = 1;
            }
            CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));
        }

        // Get pool stats "Beg".
        Statistics poolStatsBeg = {};
        DetailedStatistics detailedPoolStatsBeg = {};
        if (usePool)
        {
            pool->GetStatistics(&poolStatsBeg);
            pool->CalculateStatistics(&detailedPoolStatsBeg);
            CheckStatistics(detailedPoolStatsBeg);
        }

        // Create buffers.
        D3D12_RESOURCE_DESC resDesc;
        FillResourceDescForBuffer(resDesc, BUF_SIZE);

        ALLOCATION_DESC allocDesc = {};
        if (usePool)
            allocDesc = CALLOCATION_DESC(pool.Get());
        else
            allocDesc = CALLOCATION_DESC(D3D12_HEAP_TYPE_DEFAULT);
        if (useCommitted)
            allocDesc.Flags |= ALLOCATION_FLAG_COMMITTED;

        ComPtr<Allocation> allocs[BUF_COUNT];
        for (UINT i = 0; i < BUF_COUNT; ++i)
        {
            CHECK_HR(ctx.allocator->CreateResource(
                &allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,
                NULL, &allocs[i], IID_NULL, NULL));
        }

        // Get stats "WithBufs".
        Budget localBudgetWithBufs = {};
        Budget nonLocalBudgetWithBufs = {};
        ctx.allocator->GetBudget(&localBudgetWithBufs, &nonLocalBudgetWithBufs);
        CheckBudgetBasics(ctx, localBudgetWithBufs, nonLocalBudgetWithBufs);

        TotalStatistics statsWithBufs = {};
        ctx.allocator->CalculateStatistics(&statsWithBufs);
        CheckTotalStatistics(statsWithBufs);

        Statistics poolStatsWithBufs = {};
        DetailedStatistics detailedPoolStatsWithBufs = {};
        if (usePool)
        {
            pool->GetStatistics(&poolStatsWithBufs);
            pool->CalculateStatistics(&detailedPoolStatsWithBufs);
            CheckStatistics(detailedPoolStatsWithBufs);
        }

        // Destroy buffers.
        for (size_t i = BUF_COUNT; i--; )
        {
            allocs[i].Reset();
        }

        // Get pool stats "End".
        Statistics poolStatsEnd = {};
        DetailedStatistics detailedPoolStatsEnd = {};
        if (usePool)
        {
            pool->GetStatistics(&poolStatsEnd);
            pool->CalculateStatistics(&detailedPoolStatsEnd);
            CheckStatistics(detailedPoolStatsEnd);
        }

        // Destroy the pool.
        pool.Reset();

        // Get stats "End".
        Budget localBudgetEnd = {};
        Budget nonLocalBudgetEnd = {};
        ctx.allocator->GetBudget(&localBudgetEnd, &nonLocalBudgetEnd);
        CheckBudgetBasics(ctx, localBudgetEnd, nonLocalBudgetEnd);

        TotalStatistics statsEnd = {};
        ctx.allocator->CalculateStatistics(&statsEnd);
        CheckTotalStatistics(statsEnd);

        // CHECK THE STATS: Local.
        {
            CHECK_BOOL(localBudgetBeg.Stats.AllocationBytes <= localBudgetEnd.Stats.AllocationBytes);

            // Budget::UsageBytes.
            CHECK_BOOL(localBudgetWithBufs.UsageBytes >= localBudgetBeg.UsageBytes);
            CHECK_BOOL(localBudgetEnd.UsageBytes <= localBudgetWithBufs.UsageBytes);

            // Budget - Statistics::AllocationBytes.
            CHECK_BOOL(localBudgetEnd.Stats.AllocationBytes == localBudgetBeg.Stats.AllocationBytes);
            CHECK_BOOL(localBudgetWithBufs.Stats.AllocationBytes == localBudgetBeg.Stats.AllocationBytes + BUF_SIZE * BUF_COUNT);

            // Budget - Statistics::BlockBytes.
            if (usePool)
            {
                CHECK_BOOL(localBudgetEnd.Stats.BlockBytes == localBudgetBeg.Stats.BlockBytes);
                CHECK_BOOL(localBudgetWithBufs.Stats.BlockBytes > localBudgetBeg.Stats.BlockBytes);
            }
            else
            {
                CHECK_BOOL(localBudgetWithBufs.Stats.BlockBytes >= localBudgetBeg.Stats.BlockBytes);
            }

            // Budget - Statistics::AllocationCount.
            CHECK_BOOL(localBudgetEnd.Stats.AllocationCount == localBudgetBeg.Stats.AllocationCount);
            CHECK_BOOL(localBudgetWithBufs.Stats.AllocationCount == localBudgetBeg.Stats.AllocationCount + BUF_COUNT);

            // Budget - Statistics::BlockCount.
            if (useCommitted)
            {
                CHECK_BOOL(localBudgetEnd.Stats.BlockCount == localBudgetBeg.Stats.BlockCount);
                CHECK_BOOL(localBudgetWithBufs.Stats.BlockCount == localBudgetBeg.Stats.BlockCount + BUF_COUNT);
            }
            else if (usePool)
            {
                CHECK_BOOL(localBudgetEnd.Stats.BlockCount == localBudgetBeg.Stats.BlockCount);
                if (usePreallocated)
                {
                    CHECK_BOOL(localBudgetWithBufs.Stats.BlockCount == localBudgetBeg.Stats.BlockCount + 1);
                }
                else
                {
                    CHECK_BOOL(localBudgetWithBufs.Stats.BlockCount > localBudgetBeg.Stats.BlockCount);
                }
            }

            // Compare CalculateStatistics per memory segment group with GetBudget.
            CHECK_BOOL(StatisticsEqual(statsBeg.MemorySegmentGroup[0].Stats, localBudgetBeg.Stats));
            CHECK_BOOL(StatisticsEqual(statsWithBufs.MemorySegmentGroup[0].Stats, localBudgetWithBufs.Stats));
            CHECK_BOOL(StatisticsEqual(statsEnd.MemorySegmentGroup[0].Stats, localBudgetEnd.Stats));
        }

        // CHECK THE STATS: Non-local.
        {
            CHECK_BOOL(nonLocalBudgetEnd.Stats.AllocationBytes == nonLocalBudgetBeg.Stats.AllocationBytes &&
                nonLocalBudgetEnd.Stats.AllocationBytes == nonLocalBudgetWithBufs.Stats.AllocationBytes);
            CHECK_BOOL(nonLocalBudgetEnd.Stats.BlockBytes == nonLocalBudgetBeg.Stats.BlockBytes &&
                nonLocalBudgetEnd.Stats.BlockBytes == nonLocalBudgetWithBufs.Stats.BlockBytes);
            CHECK_BOOL(nonLocalBudgetEnd.Stats.AllocationCount == nonLocalBudgetBeg.Stats.AllocationCount &&
                nonLocalBudgetEnd.Stats.AllocationCount == nonLocalBudgetWithBufs.Stats.AllocationCount);
            CHECK_BOOL(nonLocalBudgetEnd.Stats.BlockCount == nonLocalBudgetBeg.Stats.BlockCount &&
                nonLocalBudgetEnd.Stats.BlockCount == nonLocalBudgetWithBufs.Stats.BlockCount);

            // Compare CalculateStatistics per memory segment group with GetBudget.
            CHECK_BOOL(StatisticsEqual(statsBeg.MemorySegmentGroup[1].Stats, nonLocalBudgetBeg.Stats));
            CHECK_BOOL(StatisticsEqual(statsWithBufs.MemorySegmentGroup[1].Stats, nonLocalBudgetWithBufs.Stats));
            CHECK_BOOL(StatisticsEqual(statsEnd.MemorySegmentGroup[1].Stats, nonLocalBudgetEnd.Stats));
        }

        if (usePool)
        {
            // Compare simple stats with calculated stats to make sure they are identical.
            CHECK_BOOL(StatisticsEqual(poolStatsBeg, detailedPoolStatsBeg.Stats));
            CHECK_BOOL(StatisticsEqual(poolStatsWithBufs, detailedPoolStatsWithBufs.Stats));
            CHECK_BOOL(StatisticsEqual(poolStatsEnd, detailedPoolStatsEnd.Stats));

            // Validate stats of an empty pool.
            CHECK_BOOL(detailedPoolStatsBeg.AllocationSizeMax == 0);
            CHECK_BOOL(detailedPoolStatsEnd.AllocationSizeMax == 0);
            CHECK_BOOL(detailedPoolStatsBeg.AllocationSizeMin == UINT64_MAX);
            CHECK_BOOL(detailedPoolStatsEnd.AllocationSizeMin == UINT64_MAX);
            CHECK_BOOL(poolStatsBeg.AllocationCount == 0);
            CHECK_BOOL(poolStatsBeg.AllocationBytes == 0);
            CHECK_BOOL(poolStatsEnd.AllocationCount == 0);
            CHECK_BOOL(poolStatsEnd.AllocationBytes == 0);
            if (usePreallocated)
            {
                CHECK_BOOL(poolStatsBeg.BlockCount == 1);
                CHECK_BOOL(poolStatsEnd.BlockCount == 1);
                CHECK_BOOL(poolStatsBeg.BlockBytes == PREALLOCATED_BLOCK_SIZE);
                CHECK_BOOL(poolStatsEnd.BlockBytes == PREALLOCATED_BLOCK_SIZE);
            }
            else
            {
                CHECK_BOOL(poolStatsBeg.BlockCount == 0);
                CHECK_BOOL(poolStatsBeg.BlockBytes == 0);
                // Not checking poolStatsEnd.blockCount, blockBytes, because an empty block may stay allocated.
            }

            // Validate stats of a pool with buffers.
            CHECK_BOOL(detailedPoolStatsWithBufs.AllocationSizeMin == BUF_SIZE);
            CHECK_BOOL(detailedPoolStatsWithBufs.AllocationSizeMax == BUF_SIZE);
            CHECK_BOOL(poolStatsWithBufs.AllocationCount == BUF_COUNT);
            CHECK_BOOL(poolStatsWithBufs.AllocationBytes == BUF_COUNT * BUF_SIZE);
            if (usePreallocated)
            {
                CHECK_BOOL(poolStatsWithBufs.BlockCount == 1);
                CHECK_BOOL(poolStatsWithBufs.BlockBytes == PREALLOCATED_BLOCK_SIZE);
            }
            else
            {
                CHECK_BOOL(poolStatsWithBufs.BlockCount > 0);
                CHECK_BOOL(poolStatsWithBufs.BlockBytes >= poolStatsWithBufs.AllocationBytes);
            }
        }

        // No allocation from D3D12_HEAP_TYPE_CUSTOM or GPU_UPLOAD in this test.
        CHECK_BOOL(statsEnd.HeapType[3].Stats.BlockCount == 0);
        CHECK_BOOL(statsEnd.HeapType[4].Stats.BlockCount == 0);
    }
}

static void TestTransfer(const TestContext& ctx)
{
    wprintf(L"Test mapping\n");

    const UINT count = 10;
    const UINT64 bufSize = 32ull * 1024;
    
    ResourceWithAllocation resourcesUpload[count];
    ResourceWithAllocation resourcesDefault[count];
    ResourceWithAllocation resourcesReadback[count];

    D3D12MA::CALLOCATION_DESC allocDescUpload = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_UPLOAD };
    D3D12MA::CALLOCATION_DESC allocDescDefault = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_DEFAULT };
    D3D12MA::CALLOCATION_DESC allocDescReadback = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_READBACK };

    D3D12_RESOURCE_DESC resourceDesc;
    FillResourceDescForBuffer(resourceDesc, bufSize);

    // Create 3 sets of resources.
    for(UINT i = 0; i < count; ++i)
    {
        CHECK_HR( ctx.allocator->CreateResource(
            &allocDescUpload,
            &resourceDesc,
            D3D12_RESOURCE_STATE_GENERIC_READ,
            NULL,
            &resourcesUpload[i].allocation,
            IID_PPV_ARGS(&resourcesUpload[i].resource)) );

        CHECK_HR( ctx.allocator->CreateResource(
            &allocDescDefault,
            &resourceDesc,
            D3D12_RESOURCE_STATE_COPY_DEST,
            NULL,
            &resourcesDefault[i].allocation,
            IID_PPV_ARGS(&resourcesDefault[i].resource)) );

        CHECK_HR( ctx.allocator->CreateResource(
            &allocDescReadback,
            &resourceDesc,
            D3D12_RESOURCE_STATE_COPY_DEST,
            NULL,
            &resourcesReadback[i].allocation,
            IID_PPV_ARGS(&resourcesReadback[i].resource)) );
    }

    // Map and fill data in UPLOAD.
    for(UINT i = 0; i < count; ++i)
    {
        void* mappedPtr = nullptr;
        CHECK_HR( resourcesUpload[i].resource->Map(0, &EMPTY_RANGE, &mappedPtr) );

        FillData(mappedPtr, bufSize, i);

        // Unmap every other resource, leave others mapped.
        if((i % 2) != 0)
        {
            resourcesUpload[i].resource->Unmap(0, NULL);
        }
    }

    // Transfer from UPLOAD to DEFAULT, from there to READBACK.
    ID3D12GraphicsCommandList* cmdList = BeginCommandList();
    for(UINT i = 0; i < count; ++i)
    {
        cmdList->CopyBufferRegion(resourcesDefault[i].resource.Get(), 0, resourcesUpload[i].resource.Get(), 0, bufSize);
    }
    D3D12_RESOURCE_BARRIER barriers[count] = {};
    for(UINT i = 0; i < count; ++i)
    {
        barriers[i].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
        barriers[i].Transition.pResource = resourcesDefault[i].resource.Get();
        barriers[i].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
        barriers[i].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
        barriers[i].Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    }
    cmdList->ResourceBarrier(count, barriers);
    for(UINT i = 0; i < count; ++i)
    {
        cmdList->CopyBufferRegion(resourcesReadback[i].resource.Get(), 0, resourcesDefault[i].resource.Get(), 0, bufSize);
    }
    EndCommandList(cmdList);

    // Validate READBACK buffers.
    for(UINT i = count; i--; )
    {
        const D3D12_RANGE mapRange = {0, bufSize};
        void* mappedPtr = nullptr;
        CHECK_HR( resourcesReadback[i].resource->Map(0, &mapRange, &mappedPtr) );

        CHECK_BOOL( ValidateData(mappedPtr, bufSize, i) );

        // Unmap every 3rd resource, leave others mapped.
        if((i % 3) != 0)
        {
            resourcesReadback[i].resource->Unmap(0, &EMPTY_RANGE);
        }
    }
}

static void TestMultithreading(const TestContext& ctx)
{
    wprintf(L"Test multithreading\n");

    const UINT threadCount = 32;
    const UINT bufSizeMin = 1024ull;
    const UINT bufSizeMax = 1024ull * 1024;

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_UPLOAD };

    // Launch threads.
    std::thread threads[threadCount];
    for(UINT threadIndex = 0; threadIndex < threadCount; ++threadIndex)
    {
        auto threadFunc = [&, threadIndex]()
        {
            RandomNumberGenerator rand(threadIndex);

            std::vector<ResourceWithAllocation> resources;
            resources.reserve(256);

            // Create starting number of buffers.
            const UINT bufToCreateCount = 32;
            for(UINT bufIndex = 0; bufIndex < bufToCreateCount; ++bufIndex)
            {
                ResourceWithAllocation res = {};
                res.dataSeed = (threadIndex << 16) | bufIndex;
                res.size = AlignUp<UINT>(rand.Generate() % (bufSizeMax - bufSizeMin) + bufSizeMin, 16);

                D3D12_RESOURCE_DESC resourceDesc;
                FillResourceDescForBuffer(resourceDesc, res.size);

                CHECK_HR( ctx.allocator->CreateResource(
                    &allocDesc,
                    &resourceDesc,
                    D3D12_RESOURCE_STATE_GENERIC_READ,
                    NULL,
                    &res.allocation,
                    IID_PPV_ARGS(&res.resource)) );
                
                void* mappedPtr = nullptr;
                CHECK_HR( res.resource->Map(0, &EMPTY_RANGE, &mappedPtr) );

                FillData(mappedPtr, res.size, res.dataSeed);

                // Unmap some of them, leave others mapped.
                if(rand.GenerateBool())
                {
                    res.resource->Unmap(0, NULL);
                }

                resources.push_back(std::move(res));
            }
            
            Sleep(20);

            // Make a number of random allocate and free operations.
            const UINT operationCount = 128;
            for(UINT operationIndex = 0; operationIndex < operationCount; ++operationIndex)
            {
                const bool removePossible = !resources.empty();
                const bool remove = removePossible && rand.GenerateBool();
                if(remove)
                {
                    const UINT indexToRemove = rand.Generate() % resources.size();
                    resources.erase(resources.begin() + indexToRemove);
                }
                else // Create new buffer.
                {
                    ResourceWithAllocation res = {};
                    res.dataSeed = (threadIndex << 16) | operationIndex;
                    res.size = AlignUp<UINT>(rand.Generate() % (bufSizeMax - bufSizeMin) + bufSizeMin, 16);
                    D3D12_RESOURCE_DESC resourceDesc;
                    FillResourceDescForBuffer(resourceDesc, res.size);

                    CHECK_HR( ctx.allocator->CreateResource(
                        &allocDesc,
                        &resourceDesc,
                        D3D12_RESOURCE_STATE_GENERIC_READ,
                        NULL,
                        &res.allocation,
                        IID_PPV_ARGS(&res.resource)) );

                    void* mappedPtr = nullptr;
                    CHECK_HR( res.resource->Map(0, NULL, &mappedPtr) );

                    FillData(mappedPtr, res.size, res.dataSeed);

                    // Unmap some of them, leave others mapped.
                    if(rand.GenerateBool())
                    {
                        res.resource->Unmap(0, NULL);
                    }

                    resources.push_back(std::move(res));
                }
            }

            Sleep(20);

            // Validate data in all remaining buffers while deleting them.
            for(size_t resIndex = resources.size(); resIndex--; )
            {
                void* mappedPtr = nullptr;
                CHECK_HR( resources[resIndex].resource->Map(0, NULL, &mappedPtr) );

                ValidateData(mappedPtr, resources[resIndex].size, resources[resIndex].dataSeed);

                // Unmap some of them, leave others mapped.
                if((resIndex % 3) == 1)
                {
                    resources[resIndex].resource->Unmap(0, &EMPTY_RANGE);
                } 

                resources.pop_back();
            }
        };
        threads[threadIndex] = std::thread(threadFunc);
    }

    // Wait for threads to finish.
    for(UINT threadIndex = threadCount; threadIndex--; )
    {
        threads[threadIndex].join();
    }
}

static bool IsProtectedResourceSessionSupported(const TestContext& ctx)
{
    D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT support = {};
    CHECK_HR(ctx.device->CheckFeatureSupport(
        D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_SUPPORT, &support, sizeof support));
    return support.Support > D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE;
}

static void TestLinearAllocator(const TestContext& ctx)
{
    wprintf(L"Test linear allocator\n");

    RandomNumberGenerator rand{ 645332 };

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        D3D12MA::POOL_FLAG_ALGORITHM_LINEAR,
        64 * KILOBYTE * 300, // blockSize; alignment of buffers is always 64 KB.
        1, // minBlockCount
        1 }; // maxBlockCount
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12_RESOURCE_DESC buffDesc = {};
    FillResourceDescForBuffer(buffDesc, 0);

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    constexpr size_t maxBufCount = 100;
    struct BufferInfo
    {
        ComPtr<ID3D12Resource> Buffer;
        ComPtr<D3D12MA::Allocation> Allocation;
    };
    std::vector<BufferInfo> buffInfo;

    constexpr UINT64 bufSizeMin = 16;
    constexpr UINT64 bufSizeMax = 1024;
    UINT64 prevOffset = 0;

    // Test one-time free.
    for (size_t i = 0; i < 2; ++i)
    {
        // Allocate number of buffers of varying size that surely fit into this block.
        UINT64 bufSumSize = 0;
        UINT64 allocSumSize = 0;
        for (size_t i = 0; i < maxBufCount; ++i)
        {
            buffDesc.Width = AlignUp<UINT64>(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16);
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            const UINT64 offset = newBuffInfo.Allocation->GetOffset();
            CHECK_BOOL(i == 0 || offset > prevOffset);
            prevOffset = offset;
            bufSumSize += buffDesc.Width;
            allocSumSize += newBuffInfo.Allocation->GetSize();
            buffInfo.push_back(std::move(newBuffInfo));
        }

        // Validate pool stats.
        D3D12MA::DetailedStatistics stats;
        pool->CalculateStatistics(&stats);
        CHECK_BOOL(stats.Stats.BlockBytes - stats.Stats.AllocationBytes == poolDesc.BlockSize - allocSumSize);
        CHECK_BOOL(allocSumSize >= bufSumSize);
        CHECK_BOOL(stats.Stats.AllocationCount == buffInfo.size());

        // Destroy the buffers in random order.
        while (!buffInfo.empty())
        {
            const size_t indexToDestroy = rand.Generate() % buffInfo.size();
            buffInfo.erase(buffInfo.begin() + indexToDestroy);
        }
    }

    // Test stack.
    {
        // Allocate number of buffers of varying size that surely fit into this block.
        for (size_t i = 0; i < maxBufCount; ++i)
        {
            buffDesc.Width = AlignUp<UINT64>(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16);
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            const UINT64 offset = newBuffInfo.Allocation->GetOffset();
            CHECK_BOOL(i == 0 || offset > prevOffset);
            buffInfo.push_back(std::move(newBuffInfo));
            prevOffset = offset;
        }

        // Destroy few buffers from top of the stack.
        for (size_t i = 0; i < maxBufCount / 5; ++i)
            buffInfo.pop_back();

        // Create some more
        for (size_t i = 0; i < maxBufCount / 5; ++i)
        {
            buffDesc.Width = AlignUp<UINT64>(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16);
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            const UINT64 offset = newBuffInfo.Allocation->GetOffset();
            CHECK_BOOL(i == 0 || offset > prevOffset);
            buffInfo.push_back(std::move(newBuffInfo));
            prevOffset = offset;
        }

        // Destroy the buffers in reverse order.
        while (!buffInfo.empty())
            buffInfo.pop_back();
    }

    // Test ring buffer.
    {
        // Allocate number of buffers that surely fit into this block.
        buffDesc.Width = bufSizeMax;
        for (size_t i = 0; i < maxBufCount; ++i)
        {
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            const UINT64 offset = newBuffInfo.Allocation->GetOffset();
            CHECK_BOOL(i == 0 || offset > prevOffset);
            buffInfo.push_back(std::move(newBuffInfo));
            prevOffset = offset;
        }

        // Free and allocate new buffers so many times that we make sure we wrap-around at least once.
        const size_t buffersPerIter = maxBufCount / 10 - 1;
        const size_t iterCount = poolDesc.BlockSize / buffDesc.Width / buffersPerIter * 2;
        for (size_t iter = 0; iter < iterCount; ++iter)
        {
            buffInfo.erase(buffInfo.begin(), buffInfo.begin() + buffersPerIter);

            for (size_t bufPerIter = 0; bufPerIter < buffersPerIter; ++bufPerIter)
            {
                BufferInfo newBuffInfo;
                CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                    nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
                buffInfo.push_back(std::move(newBuffInfo));
            }
        }

        // Allocate buffers until we reach out-of-memory.
        UINT32 debugIndex = 0;
        while (true)
        {
            BufferInfo newBuffInfo;
            HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer));
            ++debugIndex;
            if (SUCCEEDED(hr))
            {
                buffInfo.push_back(std::move(newBuffInfo));
            }
            else
            {
                CHECK_BOOL(hr == E_OUTOFMEMORY);
                break;
            }
        }

        // Destroy the buffers in random order.
        while (!buffInfo.empty())
        {
            const size_t indexToDestroy = rand.Generate() % buffInfo.size();
            buffInfo.erase(buffInfo.begin() + indexToDestroy);
        }
    }

    // Test double stack.
    {
        // Allocate number of buffers of varying size that surely fit into this block, alternate from bottom/top.
        UINT64 prevOffsetLower = 0;
        UINT64 prevOffsetUpper = poolDesc.BlockSize;
        for (size_t i = 0; i < maxBufCount; ++i)
        {
            const bool upperAddress = (i % 2) != 0;
            if (upperAddress)
                allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_UPPER_ADDRESS;
            else
                allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
            buffDesc.Width = AlignUp<UINT64>(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16);
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            const UINT64 offset = newBuffInfo.Allocation->GetOffset();
            if (upperAddress)
            {
                CHECK_BOOL(offset < prevOffsetUpper);
                prevOffsetUpper = offset;
            }
            else
            {
                CHECK_BOOL(offset >= prevOffsetLower);
                prevOffsetLower = offset;
            }
            CHECK_BOOL(prevOffsetLower < prevOffsetUpper);
            buffInfo.push_back(std::move(newBuffInfo));
        }

        // Destroy few buffers from top of the stack.
        for (size_t i = 0; i < maxBufCount / 5; ++i)
            buffInfo.pop_back();

        // Create some more
        for (size_t i = 0; i < maxBufCount / 5; ++i)
        {
            const bool upperAddress = (i % 2) != 0;
            if (upperAddress)
                allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_UPPER_ADDRESS;
            else
                allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
            buffDesc.Width = AlignUp<UINT64>(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16);
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            buffInfo.push_back(std::move(newBuffInfo));
        }

        // Destroy the buffers in reverse order.
        while (!buffInfo.empty())
            buffInfo.pop_back();

        // Create buffers on both sides until we reach out of memory.
        prevOffsetLower = 0;
        prevOffsetUpper = poolDesc.BlockSize;
        for (size_t i = 0; true; ++i)
        {
            const bool upperAddress = (i % 2) != 0;
            if (upperAddress)
                allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_UPPER_ADDRESS;
            else
                allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
            buffDesc.Width = AlignUp<UINT64>(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16);
            BufferInfo newBuffInfo;
            HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer));
            if (SUCCEEDED(hr))
            {
                const UINT64 offset = newBuffInfo.Allocation->GetOffset();
                if (upperAddress)
                {
                    CHECK_BOOL(offset < prevOffsetUpper);
                    prevOffsetUpper = offset;
                }
                else
                {
                    CHECK_BOOL(offset >= prevOffsetLower);
                    prevOffsetLower = offset;
                }
                CHECK_BOOL(prevOffsetLower < prevOffsetUpper);
                buffInfo.push_back(std::move(newBuffInfo));
            }
            else
                break;
        }

        // Destroy the buffers in random order.
        while (!buffInfo.empty())
        {
            const size_t indexToDestroy = rand.Generate() % buffInfo.size();
            buffInfo.erase(buffInfo.begin() + indexToDestroy);
        }

        // Create buffers on upper side only, constant size, until we reach out of memory.
        prevOffsetUpper = poolDesc.BlockSize;
        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_UPPER_ADDRESS;
        buffDesc.Width = bufSizeMax;
        while (true)
        {
            BufferInfo newBuffInfo;
            HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer));
            if (SUCCEEDED(hr))
            {
                const UINT64 offset = newBuffInfo.Allocation->GetOffset();
                CHECK_BOOL(offset < prevOffsetUpper);
                prevOffsetUpper = offset;
                buffInfo.push_back(std::move(newBuffInfo));
            }
            else
                break;
        }

        // Destroy the buffers in reverse order.
        while (!buffInfo.empty())
        {
            const BufferInfo& currBufInfo = buffInfo.back();
            buffInfo.pop_back();
        }
    }
}

static void TestLinearAllocatorMultiBlock(const TestContext& ctx)
{
    wprintf(L"Test linear allocator multi block\n");

    RandomNumberGenerator rand{ 345673 };

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        D3D12MA::POOL_FLAG_ALGORITHM_LINEAR };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12_RESOURCE_DESC buffDesc = {};
    FillResourceDescForBuffer(buffDesc, 1024 * 1024);

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    struct BufferInfo
    {
        ComPtr<ID3D12Resource> Buffer;
        ComPtr<D3D12MA::Allocation> Allocation;
    };
    std::vector<BufferInfo> buffInfo;

    // Test one-time free.
    {
        // Allocate buffers until we move to a second block.
        ID3D12Heap* lastHeap = nullptr;
        while (true)
        {
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            ID3D12Heap* heap = newBuffInfo.Allocation->GetHeap();
            buffInfo.push_back(std::move(newBuffInfo));
            if (lastHeap && heap != lastHeap)
            {
                break;
            }
            lastHeap = heap;
        }
        CHECK_BOOL(buffInfo.size() > 2);

        // Make sure that pool has now two blocks.
        D3D12MA::DetailedStatistics poolStats = {};
        pool->CalculateStatistics(&poolStats);
        CHECK_BOOL(poolStats.Stats.BlockCount == 2);

        // Destroy all the buffers in random order.
        while (!buffInfo.empty())
        {
            const size_t indexToDestroy = rand.Generate() % buffInfo.size();
            buffInfo.erase(buffInfo.begin() + indexToDestroy);
        }

        // Make sure that pool has now at most one block.
        pool->CalculateStatistics(&poolStats);
        CHECK_BOOL(poolStats.Stats.BlockCount <= 1);
    }

    // Test stack.
    {
        // Allocate buffers until we move to a second block.
        ID3D12Heap* lastHeap = nullptr;
        while (true)
        {
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            ID3D12Heap* heap = newBuffInfo.Allocation->GetHeap();
            buffInfo.push_back(std::move(newBuffInfo));
            if (lastHeap && heap != lastHeap)
            {
                break;
            }
            lastHeap = heap;
        }
        CHECK_BOOL(buffInfo.size() > 2);

        // Add few more buffers.
        for (UINT32 i = 0; i < 5; ++i)
        {
            BufferInfo newBuffInfo;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
            buffInfo.push_back(std::move(newBuffInfo));
        }

        // Make sure that pool has now two blocks.
        D3D12MA::DetailedStatistics poolStats = {};
        pool->CalculateStatistics(&poolStats);
        CHECK_BOOL(poolStats.Stats.BlockCount == 2);

        // Delete half of buffers, LIFO.
        for (size_t i = 0, countToDelete = buffInfo.size() / 2; i < countToDelete; ++i)
            buffInfo.pop_back();

        // Add one more buffer.
        BufferInfo newBuffInfo;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
            nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
        buffInfo.push_back(std::move(newBuffInfo));

        // Make sure that pool has now one block.
        pool->CalculateStatistics(&poolStats);
        CHECK_BOOL(poolStats.Stats.BlockCount == 1);

        // Delete all the remaining buffers, LIFO.
        while (!buffInfo.empty())
            buffInfo.pop_back();
    }
}

static void ManuallyTestLinearAllocator(const TestContext& ctx)
{
    wprintf(L"Manually test linear allocator\n");

    RandomNumberGenerator rand{ 645332 };

    D3D12MA::TotalStatistics origStats;
    ctx.allocator->CalculateStatistics(&origStats);

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        D3D12MA::POOL_FLAG_ALGORITHM_LINEAR,
        6 * 64 * KILOBYTE, // blockSize
        1, // minBlockCount
        1 }; // maxBlockCount
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12_RESOURCE_DESC buffDesc = {};
    FillResourceDescForBuffer(buffDesc, 0);

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    struct BufferInfo
    {
        ComPtr<ID3D12Resource> Buffer;
        ComPtr<D3D12MA::Allocation> Allocation;
    };
    std::vector<BufferInfo> buffInfo;
    BufferInfo newBuffInfo;

    // Test double stack.
    {
        /*
        Lower: Buffer 32 B, Buffer 1024 B, Buffer 32 B
        Upper: Buffer 16 B, Buffer 1024 B, Buffer 128 B

        Totally:
        1 block allocated
        393216 DirectX 12 bytes
        6 new allocations
        2256 bytes in allocations (384 KB according to alignment)
        */

        buffDesc.Width = 32;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
            nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
        buffInfo.push_back(std::move(newBuffInfo));

        buffDesc.Width = 1024;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
            nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
        buffInfo.push_back(std::move(newBuffInfo));

        buffDesc.Width = 32;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
            nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
        buffInfo.push_back(std::move(newBuffInfo));

        allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_UPPER_ADDRESS;

        buffDesc.Width = 128;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
            nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
        buffInfo.push_back(std::move(newBuffInfo));

        buffDesc.Width = 1024;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
            nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
        buffInfo.push_back(std::move(newBuffInfo));

        buffDesc.Width = 16;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &buffDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
            nullptr, &newBuffInfo.Allocation, IID_PPV_ARGS(&newBuffInfo.Buffer)));
        buffInfo.push_back(std::move(newBuffInfo));

        D3D12MA::TotalStatistics currStats;
        ctx.allocator->CalculateStatistics(&currStats);
        D3D12MA::DetailedStatistics poolStats;
        pool->CalculateStatistics(&poolStats);

        WCHAR* statsStr = nullptr;
        ctx.allocator->BuildStatsString(&statsStr, FALSE);

        // PUT BREAKPOINT HERE TO CHECK.
        // Inspect: currStats versus origStats, poolStats, statsStr.
        int I = 0;

        ctx.allocator->FreeStatsString(statsStr);

        // Destroy the buffers in reverse order.
        while (!buffInfo.empty())
            buffInfo.pop_back();
    }
}

static void BenchmarkAlgorithmsCase(const TestContext& ctx,
    FILE* file,
    D3D12MA::POOL_FLAGS algorithm,
    bool empty,
    FREE_ORDER freeOrder)
{
    RandomNumberGenerator rand{ 16223 };

    const UINT64 bufSize = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
    const size_t maxBufCapacity = 10000;
    const UINT32 iterationCount = 10;

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        algorithm, // flags
        bufSize * maxBufCapacity, // blockSize
        1, // minBlockCount
        1 }; // maxBlockCount
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12_RESOURCE_ALLOCATION_INFO allocInfo = {};
    allocInfo.SizeInBytes = bufSize;

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    std::vector<ComPtr<D3D12MA::Allocation>> baseAllocations;
    const size_t allocCount = maxBufCapacity / 3;
    if (!empty)
    {
        // Make allocations up to 1/3 of pool size.
        for (UINT64 i = 0; i < allocCount; ++i)
        {
            ComPtr<D3D12MA::Allocation> alloc;
            CHECK_HR(ctx.allocator->AllocateMemory(&allocDesc, &allocInfo, &alloc));
            baseAllocations.push_back(std::move(alloc));
        }

        // Delete half of them, choose randomly.
        size_t allocsToDelete = baseAllocations.size() / 2;
        for (size_t i = 0; i < allocsToDelete; ++i)
        {
            const size_t index = (size_t)rand.Generate() % baseAllocations.size();
            baseAllocations.erase(baseAllocations.begin() + index);
        }
    }

    // BENCHMARK
    std::vector<ComPtr<D3D12MA::Allocation>> testAllocations;
    duration allocTotalDuration = duration::zero();
    duration freeTotalDuration = duration::zero();
    for (uint32_t iterationIndex = 0; iterationIndex < iterationCount; ++iterationIndex)
    {
        testAllocations.reserve(allocCount);
        // Allocations
        time_point allocTimeBeg = std::chrono::high_resolution_clock::now();
        for (size_t i = 0; i < allocCount; ++i)
        {
            ComPtr<D3D12MA::Allocation> alloc;
            CHECK_HR(ctx.allocator->AllocateMemory(&allocDesc, &allocInfo, &alloc));
            testAllocations.push_back(std::move(alloc));
        }
        allocTotalDuration += std::chrono::high_resolution_clock::now() - allocTimeBeg;

        // Deallocations
        switch (freeOrder)
        {
        case FREE_ORDER::FORWARD:
            // Leave testAllocations unchanged.
            break;
        case FREE_ORDER::BACKWARD:
            std::reverse(testAllocations.begin(), testAllocations.end());
            break;
        case FREE_ORDER::RANDOM:
            std::shuffle(testAllocations.begin(), testAllocations.end(), MyUniformRandomNumberGenerator(rand));
            break;
        default: assert(0);
        }

        time_point freeTimeBeg = std::chrono::high_resolution_clock::now();
        testAllocations.clear();
        freeTotalDuration += std::chrono::high_resolution_clock::now() - freeTimeBeg;

    }

    // Delete baseAllocations
    baseAllocations.clear();

    const float allocTotalSeconds = ToFloatSeconds(allocTotalDuration);
    const float freeTotalSeconds = ToFloatSeconds(freeTotalDuration);

    printf("    Algorithm=%s %s FreeOrder=%s: allocations %g s, free %g s\n",
        AlgorithmToStr(algorithm),
        empty ? "Empty" : "Not empty",
        FREE_ORDER_NAMES[(size_t)freeOrder],
        allocTotalSeconds,
        freeTotalSeconds);

    if (file)
    {
        std::string currTime;
        CurrentTimeToStr(currTime);

        fprintf(file, "%s,%s,%s,%u,%s,%g,%g\n",
            CODE_DESCRIPTION, currTime.c_str(),
            AlgorithmToStr(algorithm),
            empty ? 1 : 0,
            FREE_ORDER_NAMES[(uint32_t)freeOrder],
            allocTotalSeconds,
            freeTotalSeconds);
    }
}

static void BenchmarkAlgorithms(const TestContext& ctx, FILE* file)
{
    wprintf(L"Benchmark algorithms\n");

    if (file)
    {
        fprintf(file,
            "Code,Time,"
            "Algorithm,Empty,Free order,"
            "Allocation time (s),Deallocation time (s)\n");
    }

    UINT32 freeOrderCount = 1;
    if (ConfigType >= CONFIG_TYPE::CONFIG_TYPE_LARGE)
        freeOrderCount = 3;
    else if (ConfigType >= CONFIG_TYPE::CONFIG_TYPE_SMALL)
        freeOrderCount = 2;

    const UINT32 emptyCount = ConfigType >= CONFIG_TYPE::CONFIG_TYPE_SMALL ? 2 : 1;

    for (UINT32 freeOrderIndex = 0; freeOrderIndex < freeOrderCount; ++freeOrderIndex)
    {
        FREE_ORDER freeOrder = FREE_ORDER::COUNT;
        switch (freeOrderIndex)
        {
        case 0: freeOrder = FREE_ORDER::BACKWARD; break;
        case 1: freeOrder = FREE_ORDER::FORWARD; break;
        case 2: freeOrder = FREE_ORDER::RANDOM; break;
        default: assert(0);
        }

        for (UINT32 emptyIndex = 0; emptyIndex < emptyCount; ++emptyIndex)
        {
            for (UINT32 algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
            {
                D3D12MA::POOL_FLAGS algorithm;
                switch (algorithmIndex)
                {
                case 0:
                    algorithm = D3D12MA::POOL_FLAG_NONE;
                    break;
                case 1:
                    algorithm = D3D12MA::POOL_FLAG_ALGORITHM_LINEAR;
                    break;
                default:
                    assert(0);
                }

                BenchmarkAlgorithmsCase(ctx,
                    file,
                    algorithm,
                    (emptyIndex == 0), // empty
                    freeOrder);
            }
        }
    }
}

#ifdef __ID3D12Device4_INTERFACE_DEFINED__
static void TestDevice4(const TestContext& ctx)
{
    wprintf(L"Test ID3D12Device4\n");

    if(!IsProtectedResourceSessionSupported(ctx))
    {
        wprintf(L"D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_SUPPORT returned no support for protected resource session.\n");
        return;
    }

    ComPtr<ID3D12Device4> dev4;
    HRESULT hr = ctx.device->QueryInterface(IID_PPV_ARGS(&dev4));
    if(FAILED(hr))
    {
        wprintf(L"QueryInterface for ID3D12Device4 FAILED.\n");
        return;
    }

    D3D12_PROTECTED_RESOURCE_SESSION_DESC sessionDesc = {};
    ComPtr<ID3D12ProtectedResourceSession> session;
    // This fails on the SOFTWARE adapter.
    hr = dev4->CreateProtectedResourceSession(&sessionDesc, IID_PPV_ARGS(&session));
    if(FAILED(hr))
    {
        wprintf(L"ID3D12Device4::CreateProtectedResourceSession FAILED.\n");
        return;
    }

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };
    poolDesc.pProtectedSession = session.Get();

    ComPtr<D3D12MA::Pool> pool;
    hr = ctx.allocator->CreatePool(&poolDesc, &pool);
    if(FAILED(hr))
    {
        wprintf(L"Failed to create custom pool.\n");
        return;
    }

    D3D12_RESOURCE_DESC resourceDesc;
    FillResourceDescForBuffer(resourceDesc, 64 * KILOBYTE);

    for(UINT testIndex = 0; testIndex < 2; ++testIndex)
    {
        // Create a buffer
        D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };
        if(testIndex == 0)
            allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
        ComPtr<D3D12MA::Allocation> bufAlloc;
        ComPtr<ID3D12Resource> bufRes;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resourceDesc,
            D3D12_RESOURCE_STATE_COMMON, NULL,
            &bufAlloc, IID_PPV_ARGS(&bufRes)));
        CHECK_BOOL(bufAlloc && bufAlloc->GetResource() == bufRes.Get());
        // Make sure it's (not) committed.
        CHECK_BOOL((bufAlloc->GetHeap() == NULL) == (testIndex == 0));

        // Allocate memory/heap
        // Temporarily disabled on NVIDIA as it causes BSOD on RTX2080Ti driver 461.40.
        if(g_AdapterDesc.VendorId != VENDOR_ID_NVIDIA)
        {
            D3D12_RESOURCE_ALLOCATION_INFO heapAllocInfo = {
                D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * 2, // SizeInBytes
                D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, // Alignment
            };
            ComPtr<D3D12MA::Allocation> memAlloc;
            CHECK_HR(ctx.allocator->AllocateMemory(&allocDesc, &heapAllocInfo, &memAlloc));
            CHECK_BOOL(memAlloc->GetHeap());
        }
    }
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__

#ifdef __ID3D12Device8_INTERFACE_DEFINED__
static void TestDevice8(const TestContext& ctx)
{
    wprintf(L"Test ID3D12Device8\n");

    ComPtr<ID3D12Device8> dev8;
    CHECK_HR(ctx.device->QueryInterface(IID_PPV_ARGS(&dev8)));

    D3D12_RESOURCE_DESC1 resourceDesc;
    FillResourceDescForBuffer(resourceDesc, 1024 * 1024);

    // Create a committed buffer

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12MA::ALLOCATION_FLAG_COMMITTED };

    ComPtr<D3D12MA::Allocation> allocPtr0;
    ComPtr<ID3D12Resource> res0;
    CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
        D3D12_RESOURCE_STATE_COMMON, NULL,
        &allocPtr0, IID_PPV_ARGS(&res0)));
    CHECK_BOOL(allocPtr0->GetHeap() == NULL);

    // Create a heap and placed buffer in it

    allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_CAN_ALIAS;

    ComPtr<D3D12MA::Allocation> allocPtr1;
    ComPtr<ID3D12Resource> res1;
    CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
        D3D12_RESOURCE_STATE_COMMON, NULL,
        &allocPtr1, IID_PPV_ARGS(&res1)));
    CHECK_BOOL(allocPtr1->GetHeap() != NULL);

    // Create a placed buffer

    allocDesc.Flags &= ~D3D12MA::ALLOCATION_FLAG_COMMITTED;

    ComPtr<D3D12MA::Allocation> allocPtr2;
    ComPtr<ID3D12Resource> res2;
    CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
        D3D12_RESOURCE_STATE_COMMON, NULL,
        &allocPtr2, IID_PPV_ARGS(&res2)));
    CHECK_BOOL(allocPtr2->GetHeap()!= NULL);

    // Create an aliasing buffer
    ComPtr<ID3D12Resource> res3;
    CHECK_HR(ctx.allocator->CreateAliasingResource1(allocPtr2.Get(), 0, &resourceDesc,
        D3D12_RESOURCE_STATE_COMMON, NULL,
        IID_PPV_ARGS(&res3)));
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__

#ifdef __ID3D12Device10_INTERFACE_DEFINED__
static void TestDevice10(const TestContext& ctx)
{
    wprintf(L"Test ID3D12Device10\n");

    ComPtr<ID3D12Device10> dev10;
    if(FAILED(ctx.device->QueryInterface(IID_PPV_ARGS(&dev10))))
    {
        wprintf(L"QueryInterface for ID3D12Device10 failed!\n");
        return;
    }

    D3D12_RESOURCE_DESC1 resourceDesc = {};
    resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resourceDesc.Alignment = 0;
    resourceDesc.Width = 1920;
    resourceDesc.Height = 1080;
    resourceDesc.DepthOrArraySize = 1;
    resourceDesc.MipLevels = 1;
    resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resourceDesc.SampleDesc.Count = 1;
    resourceDesc.SampleDesc.Quality = 0;
    resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;

    // Create a committed texture

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12MA::ALLOCATION_FLAG_COMMITTED };

    ComPtr<D3D12MA::Allocation> allocPtr0;
    ComPtr<ID3D12Resource> res0;
    CHECK_HR(ctx.allocator->CreateResource3(&allocDesc, &resourceDesc,
        D3D12_BARRIER_LAYOUT_UNDEFINED, NULL, 0, NULL,
        &allocPtr0, IID_PPV_ARGS(&res0)));
    CHECK_BOOL(allocPtr0->GetHeap() == NULL);

    // Create a heap and placed texture in it

    allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_CAN_ALIAS;

    ComPtr<D3D12MA::Allocation> allocPtr1;
    ComPtr<ID3D12Resource> res1;
    CHECK_HR(ctx.allocator->CreateResource3(&allocDesc, &resourceDesc,
        D3D12_BARRIER_LAYOUT_UNDEFINED, NULL, 0, NULL,
        &allocPtr1, IID_PPV_ARGS(&res1)));
    CHECK_BOOL(allocPtr1->GetHeap() != NULL);

    // Create a placed texture

    allocDesc.Flags &= ~D3D12MA::ALLOCATION_FLAG_COMMITTED;

    ComPtr<D3D12MA::Allocation> allocPtr2;
    ComPtr<ID3D12Resource> res2;
    CHECK_HR(ctx.allocator->CreateResource3(&allocDesc, &resourceDesc,
        D3D12_BARRIER_LAYOUT_UNDEFINED, NULL, 0, NULL,
        &allocPtr2, IID_PPV_ARGS(&res2)));
    CHECK_BOOL(allocPtr2->GetHeap() != NULL);

    // Create an aliasing texture
    ComPtr<ID3D12Resource> res3;
    CHECK_HR(ctx.allocator->CreateAliasingResource2(allocPtr2.Get(), 0, &resourceDesc,
        D3D12_BARRIER_LAYOUT_UNDEFINED, NULL, 0, NULL,
        IID_PPV_ARGS(&res3)));
}
#endif // #ifdef __ID3D12Device10_INTERFACE_DEFINED__

#ifdef __ID3D12Device12_INTERFACE_DEFINED__
static void TestDevice12(const TestContext& ctx)
{
    wprintf(L"Test ID3D12Device12\n");

    ComPtr<ID3D12Device12> dev12;
    if (FAILED(ctx.device->QueryInterface(IID_PPV_ARGS(&dev12))))
    {
        wprintf(L"QueryInterface for ID3D12Device12 failed!\n");
        return;
    }

    // Texture based on Issue #62.
    D3D12_RESOURCE_DESC1 resourceDesc = {};
    resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resourceDesc.Width = 1920;
    resourceDesc.Height = 1080;
    resourceDesc.DepthOrArraySize = 1;
    resourceDesc.MipLevels = 1;
    resourceDesc.Format = DXGI_FORMAT_BC3_UNORM;
    resourceDesc.SampleDesc.Count = 1;
    resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;

    const DXGI_FORMAT castableFormats[] = { DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_BC3_UNORM_SRGB };

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_DEFAULT };

    ComPtr<D3D12MA::Allocation> alloc0;
    ComPtr<ID3D12Resource> res0;
    HRESULT hr = ctx.allocator->CreateResource3(&allocDesc, &resourceDesc,
        D3D12_BARRIER_LAYOUT_UNDEFINED, NULL,
        _countof(castableFormats), castableFormats,
        &alloc0, IID_PPV_ARGS(&res0));
    
    if (hr == E_INVALIDARG)
    {
        wprintf(L"Allocator::CreateResource3 failed with E_INVALIDARG!\n");
        return;
    }

    CHECK_HR(hr);
    CHECK_BOOL(alloc0 && res0);
}
#endif // #ifdef __ID3D12Device12_INTERFACE_DEFINED__

static void TestGPUUploadHeap(const TestContext& ctx)
{
#if D3D12_SDK_VERSION >= 610
    using namespace D3D12MA;

    wprintf(L"Test GPU Upload Heap\n");

    const bool supported = ctx.allocator->IsGPUUploadHeapSupported();

    Budget begLocalBudget = {};
    ctx.allocator->GetBudget(&begLocalBudget, NULL);
    TotalStatistics begStats = {};
    ctx.allocator->CalculateStatistics(&begStats);

    // Create a buffer, likely placed.
    CALLOCATION_DESC allocDesc = CALLOCATION_DESC{ D3D12_HEAP_TYPE_GPU_UPLOAD };
    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, 64 * KILOBYTE);

    ComPtr<Allocation> alloc;
    HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &resDesc,
        D3D12_RESOURCE_STATE_COMMON, NULL, &alloc, IID_NULL, NULL);
    if (!supported)
    {
        // Skip further tests. Just wanted to test that the respource creation fails with the right error code.
        CHECK_BOOL(hr == E_NOTIMPL);
        return;
    }
    CHECK_HR(hr);
    CHECK_BOOL(alloc && alloc->GetResource());
    CHECK_BOOL(alloc->GetResource()->GetGPUVirtualAddress() != 0);
    
    {
        D3D12_HEAP_PROPERTIES heapProps = {};
        D3D12_HEAP_FLAGS heapFlags = {};
        CHECK_HR(alloc->GetResource()->GetHeapProperties(&heapProps, &heapFlags));
        CHECK_BOOL(heapProps.Type == D3D12_HEAP_TYPE_GPU_UPLOAD);
    }

    // Create a committed one.
    CALLOCATION_DESC committedAllocDesc = allocDesc;
    committedAllocDesc.Flags |= ALLOCATION_FLAG_COMMITTED;
    ComPtr<Allocation> committedAlloc;
    CHECK_HR(ctx.allocator->CreateResource(&committedAllocDesc, &resDesc,
        D3D12_RESOURCE_STATE_COMMON, NULL, &committedAlloc, IID_NULL, NULL));
    CHECK_BOOL(committedAlloc && committedAlloc->GetResource());
    CHECK_BOOL(committedAlloc->GetHeap() == NULL); // Committed, heap is implicit and inaccessible.

    // Create a custom pool and a buffer inside of it.
    CPOOL_DESC poolDesc = CPOOL_DESC{ D3D12_HEAP_TYPE_GPU_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };
    ComPtr<Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));
    
    CALLOCATION_DESC poolAllocDesc = CALLOCATION_DESC{ pool.Get() };
    ComPtr<Allocation> poolAlloc;
    CHECK_HR(ctx.allocator->CreateResource(&poolAllocDesc, &resDesc,
        D3D12_RESOURCE_STATE_COMMON, NULL, &poolAlloc, IID_NULL, NULL));
    CHECK_BOOL(poolAlloc && poolAlloc->GetResource());

    // Map the original buffer, write, then read
    {
        const auto res = alloc->GetResource();

        UINT* mappedData = NULL;
        CHECK_HR(res->Map(0, &EMPTY_RANGE, (void**)&mappedData)); // {0, 0} - not reading anything.
        for(UINT i = 0; i < resDesc.Width / sizeof(UINT); ++i)
        {
            mappedData[i] = i * 3;
        }
        res->Unmap(0, NULL); // NULL - written everything.

        CHECK_HR(res->Map(0, NULL, (void**)&mappedData)); // NULL - reading everything.
        CHECK_BOOL(mappedData[100] == 300);
        res->Unmap(0, &EMPTY_RANGE); // {0, 0} - not written anything.

    }

    // Create two big buffers.
    D3D12_RESOURCE_DESC bigResDesc = resDesc;
    bigResDesc.Width = 128 * MEGABYTE;

    ComPtr<Allocation> bigAllocs[2];
    for(UINT i = 0; i < 2; ++i)
    {
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &bigResDesc,
            D3D12_RESOURCE_STATE_COMMON, NULL, &bigAllocs[i], IID_NULL, NULL));
        CHECK_BOOL(bigAllocs[i] && bigAllocs[i]->GetResource());
    }

    // Create a texture.
    constexpr UINT texSize = 256;
    D3D12_RESOURCE_DESC texDesc = {};
    texDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    texDesc.Alignment = 0;
    texDesc.Width = texSize;
    texDesc.Height = texSize;
    texDesc.DepthOrArraySize = 1;
    texDesc.MipLevels = 1;
    texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    texDesc.SampleDesc.Count = 1;
    texDesc.SampleDesc.Quality = 0;
    texDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    texDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
    ComPtr<Allocation> texAlloc;
    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &texDesc,
        D3D12_RESOURCE_STATE_COMMON, NULL, &texAlloc, IID_NULL, NULL));
    CHECK_BOOL(texAlloc && texAlloc->GetResource());

    {
        std::vector<UINT> texPixels(texSize * texSize);
        // Contents of texPixels[i] doesn't matter.
        const auto texRes = texAlloc->GetResource();
        // Need to pass ppData == NULL for Map() to be used with a texture having D3D12_TEXTURE_LAYOUT_UNKNOWN.
        CHECK_HR(texRes->Map(0, &EMPTY_RANGE, NULL)); // {0, 0} - not reading anything.
        CHECK_HR(texRes->WriteToSubresource(
            0, // DstSubresource
            NULL, // pDstBox
            texPixels.data(), // pSrcData
            texSize * sizeof(DWORD), // SrcRowPitch
            texSize * texSize * sizeof(DWORD))); // SrcDepthPitch
        texRes->Unmap(0, NULL); // NULL - written everything.
    }

    // Check budget and stats
    constexpr UINT totalAllocCount = 6;
    Budget endLocalBudget = {};
    ctx.allocator->GetBudget(&endLocalBudget, NULL);
    TotalStatistics endStats = {};
    ctx.allocator->CalculateStatistics(&endStats);
    CHECK_BOOL(endLocalBudget.UsageBytes >= begLocalBudget.UsageBytes
        + 2 * bigResDesc.Width
        && "This can fail if GPU_UPLOAD falls back to system RAM e.g. when under PIX?");
    auto validateStats = [totalAllocCount, &bigResDesc](const Statistics& begStats, const Statistics& endStats)
    {
        CHECK_BOOL(endStats.BlockCount >= begStats.BlockCount);
        CHECK_BOOL(endStats.BlockBytes >= begStats.BlockBytes);
        CHECK_BOOL(endStats.AllocationCount == begStats.AllocationCount + totalAllocCount);
        CHECK_BOOL(endStats.AllocationBytes > begStats.AllocationBytes + 2 * bigResDesc.Width);
    };
    validateStats(begLocalBudget.Stats, endLocalBudget.Stats);
    validateStats(begStats.Total.Stats, endStats.Total.Stats);
    validateStats(begStats.MemorySegmentGroup[0].Stats, endStats.MemorySegmentGroup[0].Stats); // DXGI_MEMORY_SEGMENT_GROUP_LOCAL
    validateStats(begStats.HeapType[4].Stats, endStats.HeapType[4].Stats); // D3D12_HEAP_TYPE_GPU_UPLOAD
#endif
}

static void TestVirtualBlocks(const TestContext& ctx)
{
    wprintf(L"Test virtual blocks\n");

    using namespace D3D12MA;

    const UINT64 blockSize = 16 * MEGABYTE;
    const UINT64 alignment = 256;

    // # Create block 16 MB

    ComPtr<D3D12MA::VirtualBlock> block;
    CVIRTUAL_BLOCK_DESC blockDesc = CVIRTUAL_BLOCK_DESC{
        blockSize,
        VIRTUAL_BLOCK_FLAG_NONE,
        ctx.allocationCallbacks };
    CHECK_HR(CreateVirtualBlock(&blockDesc, &block));
    CHECK_BOOL(block);

    // # Allocate 8 MB

    CVIRTUAL_ALLOCATION_DESC allocDesc = CVIRTUAL_ALLOCATION_DESC{
        8 * MEGABYTE, // size
        alignment,
        D3D12MA::VIRTUAL_ALLOCATION_FLAG_NONE,
        (void*)(uintptr_t)1 }; // privateData
    VirtualAllocation alloc0;
    CHECK_HR(block->Allocate(&allocDesc, &alloc0, nullptr));

    // # Validate the allocation

    VIRTUAL_ALLOCATION_INFO alloc0Info = {};
    block->GetAllocationInfo(alloc0, &alloc0Info);
    CHECK_BOOL(alloc0Info.Offset < blockSize);
    CHECK_BOOL(alloc0Info.Size == allocDesc.Size);
    CHECK_BOOL(alloc0Info.pPrivateData == allocDesc.pPrivateData);

    // # Check SetUserData

    block->SetAllocationPrivateData(alloc0, (void*)(uintptr_t)2);
    block->GetAllocationInfo(alloc0, &alloc0Info);
    CHECK_BOOL(alloc0Info.pPrivateData == (void*)(uintptr_t)2);

    // # Allocate 4 MB

    allocDesc.Size = 4 * MEGABYTE;
    allocDesc.Alignment = alignment;
    VirtualAllocation alloc1;
    CHECK_HR(block->Allocate(&allocDesc, &alloc1, nullptr));

    VIRTUAL_ALLOCATION_INFO alloc1Info = {};
    block->GetAllocationInfo(alloc1, &alloc1Info);
    CHECK_BOOL(alloc1Info.Offset < blockSize);
    CHECK_BOOL(alloc1Info.Offset + 4 * MEGABYTE <= alloc0Info.Offset || alloc0Info.Offset + 8 * MEGABYTE <= alloc1Info.Offset); // Check if they don't overlap.

    // # Allocate another 8 MB - it should fail

    allocDesc.Size = 8 * MEGABYTE;
    allocDesc.Alignment = alignment;
    VirtualAllocation alloc2;
    CHECK_BOOL(FAILED(block->Allocate(&allocDesc, &alloc2, nullptr)));
    CHECK_BOOL(alloc2.AllocHandle == (AllocHandle)0);

    // # Free the 4 MB block. Now allocation of 8 MB should succeed.

    block->FreeAllocation(alloc1);
    UINT64 alloc2Offset;
    CHECK_HR(block->Allocate(&allocDesc, &alloc2, &alloc2Offset));
    CHECK_BOOL(alloc2Offset < blockSize);
    CHECK_BOOL(alloc2Offset + 4 * MEGABYTE <= alloc0Info.Offset || alloc0Info.Offset + 8 * MEGABYTE <= alloc2Offset); // Check if they don't overlap.

    // # Calculate statistics

    DetailedStatistics statInfo = {};
    block->CalculateStatistics(&statInfo);
    CHECK_BOOL(statInfo.Stats.AllocationCount == 2);
    CHECK_BOOL(statInfo.Stats.BlockCount == 1);
    CHECK_BOOL(statInfo.Stats.AllocationBytes == blockSize);
    CHECK_BOOL(statInfo.Stats.BlockBytes == blockSize);

    // # Generate JSON dump

    WCHAR* json = nullptr;
    block->BuildStatsString(&json);
    {
        std::wstring str(json);
        CHECK_BOOL(str.find(L"\"CustomData\": 1") != std::wstring::npos);
        CHECK_BOOL(str.find(L"\"CustomData\": 2") != std::wstring::npos);
    }
    block->FreeStatsString(json);

    // # Free alloc0, leave alloc2 unfreed.

    block->FreeAllocation(alloc0);

    // # Test alignment

    {
        constexpr size_t allocCount = 10;
        VirtualAllocation allocs[allocCount] = {};
        for (size_t i = 0; i < allocCount; ++i)
        {
            const bool alignment0 = i == allocCount - 1;
            allocDesc.Size = i * 3 + 15;
            allocDesc.Alignment = alignment0 ? 0 : 8;
            UINT64 offset;
            CHECK_HR(block->Allocate(&allocDesc, &allocs[i], &offset));
            if (!alignment0)
            {
                CHECK_BOOL(offset % allocDesc.Alignment == 0);
            }
        }

        for (size_t i = allocCount; i--; )
        {
            block->FreeAllocation(allocs[i]);
        }
    }

    // # Final cleanup

    block->FreeAllocation(alloc2);
}

static void TestVirtualBlocksAlgorithms(const TestContext& ctx)
{
    wprintf(L"Test virtual blocks algorithms\n");

    RandomNumberGenerator rand{ 3454335 };
    auto calcRandomAllocSize = [&rand]() -> UINT64 { return rand.Generate() % 20 + 5; };

    for (size_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
    {
        // Create the block
        D3D12MA::CVIRTUAL_BLOCK_DESC blockDesc = D3D12MA::CVIRTUAL_BLOCK_DESC{
            10'000,
            D3D12MA::VIRTUAL_BLOCK_FLAG_NONE,
            ctx.allocationCallbacks };
        switch (algorithmIndex)
        {
        case 0: blockDesc.Flags = D3D12MA::VIRTUAL_BLOCK_FLAG_NONE; break;
        case 1: blockDesc.Flags = D3D12MA::VIRTUAL_BLOCK_FLAG_ALGORITHM_LINEAR; break;
        }
        ComPtr<D3D12MA::VirtualBlock> block;
        CHECK_HR(D3D12MA::CreateVirtualBlock(&blockDesc, &block));

        struct AllocData
        {
            D3D12MA::VirtualAllocation allocation;
            UINT64 allocOffset, requestedSize, allocationSize;
        };
        std::vector<AllocData> allocations;

        // Make some allocations
        for (size_t i = 0; i < 20; ++i)
        {
            const UINT64 size = calcRandomAllocSize();
            D3D12MA::CVIRTUAL_ALLOCATION_DESC allocDesc = D3D12MA::CVIRTUAL_ALLOCATION_DESC{
                size,
                0, // alignment
                D3D12MA::VIRTUAL_ALLOCATION_FLAG_NONE,
                (void*)(uintptr_t)(size * 10) }; // privateData
            if (i < 10) {}
            else if (i < 20 && algorithmIndex == 1) allocDesc.Flags = D3D12MA::VIRTUAL_ALLOCATION_FLAG_UPPER_ADDRESS;

            AllocData alloc = {};
            alloc.requestedSize = allocDesc.Size;
            CHECK_HR(block->Allocate(&allocDesc, &alloc.allocation, nullptr));

            D3D12MA::VIRTUAL_ALLOCATION_INFO allocInfo;
            block->GetAllocationInfo(alloc.allocation, &allocInfo);
            CHECK_BOOL(allocInfo.Size >= allocDesc.Size);
            alloc.allocOffset = allocInfo.Offset;
            alloc.allocationSize = allocInfo.Size;

            allocations.push_back(alloc);
        }

        // Free some of the allocations
        for (size_t i = 0; i < 5; ++i)
        {
            const size_t index = rand.Generate() % allocations.size();
            block->FreeAllocation(allocations[index].allocation);
            allocations.erase(allocations.begin() + index);
        }

        // Allocate some more
        for (size_t i = 0; i < 6; ++i)
        {
            const UINT64 size = calcRandomAllocSize();
            D3D12MA::CVIRTUAL_ALLOCATION_DESC allocDesc = D3D12MA::CVIRTUAL_ALLOCATION_DESC{
                size,
                0, // alignment
                D3D12MA::VIRTUAL_ALLOCATION_FLAG_NONE,
                (void*)(uintptr_t)(size * 10) }; // privateData

            AllocData alloc = {};
            alloc.requestedSize = allocDesc.Size;
            CHECK_HR(block->Allocate(&allocDesc, &alloc.allocation, nullptr));

            D3D12MA::VIRTUAL_ALLOCATION_INFO allocInfo;
            block->GetAllocationInfo(alloc.allocation, &allocInfo);
            CHECK_BOOL(allocInfo.Size >= allocDesc.Size);
            alloc.allocOffset = allocInfo.Offset;
            alloc.allocationSize = allocInfo.Size;

            allocations.push_back(alloc);
        }

        // Allocate some with extra alignment
        for (size_t i = 0; i < 3; ++i)
        {
            const UINT64 size = calcRandomAllocSize();
            D3D12MA::CVIRTUAL_ALLOCATION_DESC allocDesc = D3D12MA::CVIRTUAL_ALLOCATION_DESC{
                size,
                16, // alignment
                D3D12MA::VIRTUAL_ALLOCATION_FLAG_NONE,
                (void*)(uintptr_t)(size * 10) }; // privateData

            AllocData alloc = {};
            alloc.requestedSize = allocDesc.Size;
            CHECK_HR(block->Allocate(&allocDesc, &alloc.allocation, nullptr));

            D3D12MA::VIRTUAL_ALLOCATION_INFO allocInfo;
            block->GetAllocationInfo(alloc.allocation, &allocInfo);
            CHECK_BOOL(allocInfo.Offset % 16 == 0);
            CHECK_BOOL(allocInfo.Size >= allocDesc.Size);
            alloc.allocOffset = allocInfo.Offset;
            alloc.allocationSize = allocInfo.Size;

            allocations.push_back(alloc);
        }

        // Check if the allocations don't overlap
        std::sort(allocations.begin(), allocations.end(), [](const AllocData& lhs, const AllocData& rhs) {
            return lhs.allocOffset < rhs.allocOffset; });
        for (size_t i = 0; i < allocations.size() - 1; ++i)
        {
            CHECK_BOOL(allocations[i + 1].allocOffset >= allocations[i].allocOffset + allocations[i].allocationSize);
        }

        // Check pPrivateData
        {
            const AllocData& alloc = allocations.back();
            D3D12MA::VIRTUAL_ALLOCATION_INFO allocInfo;
            block->GetAllocationInfo(alloc.allocation, &allocInfo);
            CHECK_BOOL((uintptr_t)allocInfo.pPrivateData == alloc.requestedSize * 10);

            block->SetAllocationPrivateData(alloc.allocation, (void*)(uintptr_t)666);
            block->GetAllocationInfo(alloc.allocation, &allocInfo);
            CHECK_BOOL((uintptr_t)allocInfo.pPrivateData == 666);
        }

        // Calculate statistics
        {
            UINT64 actualAllocSizeMin = UINT64_MAX, actualAllocSizeMax = 0, actualAllocSizeSum = 0;
            std::for_each(allocations.begin(), allocations.end(), [&](const AllocData& a) {
                actualAllocSizeMin = std::min(actualAllocSizeMin, a.allocationSize);
                actualAllocSizeMax = std::max(actualAllocSizeMax, a.allocationSize);
                actualAllocSizeSum += a.allocationSize;
                });

            D3D12MA::DetailedStatistics statInfo = {};
            block->CalculateStatistics(&statInfo);
            CHECK_BOOL(statInfo.Stats.AllocationCount == allocations.size());
            CHECK_BOOL(statInfo.Stats.BlockCount == 1);
            CHECK_BOOL(statInfo.Stats.BlockBytes == blockDesc.Size);
            CHECK_BOOL(statInfo.AllocationSizeMax == actualAllocSizeMax);
            CHECK_BOOL(statInfo.AllocationSizeMin == actualAllocSizeMin);
            CHECK_BOOL(statInfo.Stats.AllocationBytes >= actualAllocSizeSum);
        }

        // Build JSON dump string
        {
            WCHAR* json = nullptr;
            block->BuildStatsString(&json);
            int I = 0; // put a breakpoint here to debug
            block->FreeStatsString(json);
        }

        // Final cleanup
        block->Clear();
    }
}

static void TestVirtualBlocksAlgorithmsBenchmark(const TestContext& ctx)
{
    wprintf(L"Benchmark virtual blocks algorithms\n");

    const size_t ALLOCATION_COUNT = 7200;
    const UINT32 MAX_ALLOC_SIZE = 2056;

    D3D12MA::CVIRTUAL_BLOCK_DESC blockDesc = D3D12MA::CVIRTUAL_BLOCK_DESC{
        0,
        D3D12MA::VIRTUAL_BLOCK_FLAG_NONE,
        ctx.allocationCallbacks };

    RandomNumberGenerator rand{ 20092010 };

    std::vector<UINT32> allocSizes(ALLOCATION_COUNT);
    for (size_t i = 0; i < ALLOCATION_COUNT; ++i)
    {
        allocSizes[i] = rand.Generate() % MAX_ALLOC_SIZE + 1;
        blockDesc.Size += allocSizes[i];
    }
    blockDesc.Size = static_cast<UINT64>(blockDesc.Size * 1.5); // 50% size margin in case of alignment

    for (UINT8 alignmentIndex = 0; alignmentIndex < 4; ++alignmentIndex)
    {
        UINT64 alignment;
        switch (alignmentIndex)
        {
        case 0: alignment = 1; break;
        case 1: alignment = 16; break;
        case 2: alignment = 64; break;
        case 3: alignment = 256; break;
        default: assert(0); break;
        }
        printf("    Alignment=%llu\n", alignment);

        for (UINT8 algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
        {
            switch (algorithmIndex)
            {
            case 0:
                blockDesc.Flags = D3D12MA::VIRTUAL_BLOCK_FLAG_NONE;
                break;
            case 1:
                blockDesc.Flags = D3D12MA::VIRTUAL_BLOCK_FLAG_ALGORITHM_LINEAR;
                break;
            default:
                assert(0);
            }

            std::vector <D3D12MA::VirtualAllocation> allocs(ALLOCATION_COUNT);
            ComPtr<D3D12MA::VirtualBlock> block;
            CHECK_HR(D3D12MA::CreateVirtualBlock(&blockDesc, &block));
            duration allocDuration = duration::zero();
            duration freeDuration = duration::zero();

            // Alloc
            time_point timeBegin = std::chrono::high_resolution_clock::now();
            for (size_t i = 0; i < ALLOCATION_COUNT; ++i)
            {
                D3D12MA::CVIRTUAL_ALLOCATION_DESC allocCreateInfo = D3D12MA::CVIRTUAL_ALLOCATION_DESC{
                    allocSizes[i],
                    alignment };

                CHECK_HR(block->Allocate(&allocCreateInfo, &allocs[i], nullptr));
            }
            allocDuration += std::chrono::high_resolution_clock::now() - timeBegin;

            // Free
            timeBegin = std::chrono::high_resolution_clock::now();
            for (size_t i = ALLOCATION_COUNT; i;)
                block->FreeAllocation(allocs[--i]);
            freeDuration += std::chrono::high_resolution_clock::now() - timeBegin;

            printf("        Algorithm=%s  \tallocations %g s,   \tfree %g s\n",
                VirtualAlgorithmToStr(blockDesc.Flags),
                ToFloatSeconds(allocDuration),
                ToFloatSeconds(freeDuration));
        }
        printf("\n");
    }
}

static void ProcessDefragmentationPass(const TestContext& ctx, D3D12MA::DEFRAGMENTATION_PASS_MOVE_INFO& stepInfo)
{
    std::vector<D3D12_RESOURCE_BARRIER> startBarriers;
    std::vector<D3D12_RESOURCE_BARRIER> finalBarriers;

    bool defaultHeap = false;
    for (UINT32 i = 0; i < stepInfo.MoveCount; ++i)
    {
        if (stepInfo.pMoves[i].Operation == D3D12MA::DEFRAGMENTATION_MOVE_OPERATION_COPY)
        {
            const bool isDefaultHeap = stepInfo.pMoves[i].pSrcAllocation->GetHeap()->GetDesc().Properties.Type == D3D12_HEAP_TYPE_DEFAULT;
            // Create new resource
            D3D12_RESOURCE_DESC desc = stepInfo.pMoves[i].pSrcAllocation->GetResource()->GetDesc();
            ComPtr<ID3D12Resource> dstRes;
            CHECK_HR(ctx.device->CreatePlacedResource(stepInfo.pMoves[i].pDstTmpAllocation->GetHeap(),
                stepInfo.pMoves[i].pDstTmpAllocation->GetOffset(), &desc,
                isDefaultHeap ? D3D12_RESOURCE_STATE_COPY_DEST : D3D12_RESOURCE_STATE_GENERIC_READ,
                nullptr, IID_PPV_ARGS(&dstRes)));
            stepInfo.pMoves[i].pDstTmpAllocation->SetResource(dstRes.Get());

            // Perform barriers only if not in right state
            if (isDefaultHeap)
            {
                defaultHeap = true;
                // Move new resource into previous state
                D3D12_RESOURCE_BARRIER barrier = {};
                barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
                barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
                barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
                barrier.Transition.pResource = dstRes.Get();
                barrier.Transition.StateAfter = (D3D12_RESOURCE_STATES)(uintptr_t)stepInfo.pMoves[i].pSrcAllocation->GetPrivateData();
                barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
                finalBarriers.emplace_back(barrier);

                // Move resource into right state
                barrier.Transition.pResource = stepInfo.pMoves[i].pSrcAllocation->GetResource();
                barrier.Transition.StateBefore = barrier.Transition.StateAfter;
                barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
                startBarriers.emplace_back(barrier);
            }
        }
    }

    if (defaultHeap)
    {
        ID3D12GraphicsCommandList* cl = BeginCommandList();
        cl->ResourceBarrier(static_cast<UINT>(startBarriers.size()), startBarriers.data());

        // Copy resources
        for (UINT32 i = 0; i < stepInfo.MoveCount; ++i)
        {
            if (stepInfo.pMoves[i].Operation == D3D12MA::DEFRAGMENTATION_MOVE_OPERATION_COPY)
            {
                ID3D12Resource* dstRes = stepInfo.pMoves[i].pDstTmpAllocation->GetResource();
                ID3D12Resource* srcRes = stepInfo.pMoves[i].pSrcAllocation->GetResource();

                if (stepInfo.pMoves[i].pDstTmpAllocation->GetHeap()->GetDesc().Properties.Type == D3D12_HEAP_TYPE_DEFAULT)
                {
                    cl->CopyResource(dstRes, srcRes);
                }
                else
                {
                    D3D12_RANGE range = {};
                    void* dst;
                    CHECK_HR(dstRes->Map(0, &range, &dst));
                    void* src;
                    CHECK_HR(srcRes->Map(0, &range, &src));
                    memcpy(dst, src, stepInfo.pMoves[i].pSrcAllocation->GetSize());
                    dstRes->Unmap(0, nullptr);
                    srcRes->Unmap(0, nullptr);
                }
            }
        }

        cl->ResourceBarrier(static_cast<UINT>(finalBarriers.size()), finalBarriers.data());
        EndCommandList(cl);
    }
    else
    {
        // Copy only CPU-side
        for (UINT32 i = 0; i < stepInfo.MoveCount; ++i)
        {
            if (stepInfo.pMoves[i].Operation == D3D12MA::DEFRAGMENTATION_MOVE_OPERATION_COPY)
            {
                D3D12_RANGE range = {};

                void* dst;
                ID3D12Resource* dstRes = stepInfo.pMoves[i].pDstTmpAllocation->GetResource();
                CHECK_HR(dstRes->Map(0, &range, &dst));

                void* src;
                ID3D12Resource* srcRes = stepInfo.pMoves[i].pSrcAllocation->GetResource();
                CHECK_HR(srcRes->Map(0, &range, &src));

                memcpy(dst, src, stepInfo.pMoves[i].pSrcAllocation->GetSize());
                dstRes->Unmap(0, nullptr);
                srcRes->Unmap(0, nullptr);
            }
        }
    }
}

static void Defragment(const TestContext& ctx,
    D3D12MA::DEFRAGMENTATION_DESC& defragDesc,
    D3D12MA::Pool* pool,
    D3D12MA::DEFRAGMENTATION_STATS* defragStats = nullptr)
{
    ComPtr<D3D12MA::DefragmentationContext> defragCtx;
    if (pool != nullptr)
    {
        CHECK_HR(pool->BeginDefragmentation(&defragDesc, &defragCtx));
    }
    else
        ctx.allocator->BeginDefragmentation(&defragDesc, &defragCtx);

    HRESULT hr = S_OK;
    D3D12MA::DEFRAGMENTATION_PASS_MOVE_INFO pass = {};
    while ((hr = defragCtx->BeginPass(&pass)) == S_FALSE)
    {
        ProcessDefragmentationPass(ctx, pass);

        if ((hr = defragCtx->EndPass(&pass)) == S_OK)
            break;
        CHECK_BOOL(hr == S_FALSE);
    }
    CHECK_HR(hr);
    if (defragStats != nullptr)
        defragCtx->GetStats(defragStats);
}

static void TestDefragmentationSimple(const TestContext& ctx)
{
    wprintf(L"Test defragmentation simple\n");

    RandomNumberGenerator rand(667);

    const UINT ALLOC_SEED = 20220310;
    const UINT64 BUF_SIZE = 0x10000;
    const UINT64 BLOCK_SIZE = BUF_SIZE * 8;

    const UINT64 MIN_BUF_SIZE = 32;
    const UINT64 MAX_BUF_SIZE = BUF_SIZE * 4;
    auto RandomBufSize = [&]() -> UINT64
    {
        return AlignUp<UINT64>(rand.Generate() % (MAX_BUF_SIZE - MIN_BUF_SIZE + 1) + MIN_BUF_SIZE, 64);
    };

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_UPLOAD,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        D3D12MA::POOL_FLAG_NONE,
        BLOCK_SIZE };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    D3D12_RESOURCE_DESC resDesc = {};
    FillResourceDescForBuffer(resDesc, BUF_SIZE);

    D3D12MA::DEFRAGMENTATION_DESC defragDesc = {};
    defragDesc.Flags = D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_FAST;

    // Defragmentation of empty pool.
    {
        ComPtr<D3D12MA::DefragmentationContext> defragCtx = nullptr;
        CHECK_HR(pool->BeginDefragmentation(&defragDesc, &defragCtx));

        D3D12MA::DEFRAGMENTATION_PASS_MOVE_INFO pass = {};
        CHECK_BOOL(defragCtx->BeginPass(&pass) == S_OK);

        D3D12MA::DEFRAGMENTATION_STATS defragStats = {};
        defragCtx->GetStats(&defragStats);
        CHECK_BOOL(defragStats.AllocationsMoved == 0 && defragStats.BytesFreed == 0 &&
            defragStats.BytesMoved == 0 && defragStats.HeapsFreed == 0);
    }

    D3D12_RANGE mapRange = {};
    void* mapPtr;
    std::vector<ComPtr<D3D12MA::Allocation>> allocations;

    // persistentlyMappedOption = 0 - not persistently mapped.
    // persistentlyMappedOption = 1 - persistently mapped.
    for (UINT8 persistentlyMappedOption = 0; persistentlyMappedOption < 2; ++persistentlyMappedOption)
    {
        wprintf(L"  Persistently mapped option = %u\n", persistentlyMappedOption);
        const bool persistentlyMapped = persistentlyMappedOption != 0;

        // # Test 1
        // Buffers of fixed size.
        // Fill 2 blocks. Remove odd buffers. Defragment everything.
        // Expected result: at least 1 block freed.
        {
            for (size_t i = 0; i < BLOCK_SIZE / BUF_SIZE * 2; ++i)
            {
                ComPtr<D3D12MA::Allocation> alloc;
                CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
                    nullptr, &alloc, IID_NULL, nullptr));
                if (persistentlyMapped)
                {
                    CHECK_HR(alloc->GetResource()->Map(0, &mapRange, &mapPtr));
                }

                allocations.emplace_back(std::move(alloc));
            }

            for (size_t i = 1; i < allocations.size(); ++i)
                allocations.erase(allocations.begin() + i);
            FillAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);

            // Set data for defragmentation retrieval
            for (auto& alloc : allocations)
                alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_GENERIC_READ);

            D3D12MA::DEFRAGMENTATION_STATS defragStats;
            Defragment(ctx, defragDesc, pool.Get(), & defragStats);
            CHECK_BOOL(defragStats.AllocationsMoved == 4 && defragStats.BytesMoved == 4 * BUF_SIZE);

            ValidateAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);
            allocations.clear();
        }

        // # Test 2
        // Buffers of fixed size.
        // Fill 2 blocks. Remove odd buffers. Defragment one buffer at time.
        // Expected result: Each of 4 interations makes some progress.
        {
            for (size_t i = 0; i < BLOCK_SIZE / BUF_SIZE * 2; ++i)
            {
                ComPtr<D3D12MA::Allocation> alloc;
                CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
                    nullptr, &alloc, IID_NULL, nullptr));
                if (persistentlyMapped)
                {
                    CHECK_HR(alloc->GetResource()->Map(0, &mapRange, &mapPtr));
                }

                allocations.emplace_back(std::move(alloc));
            }

            for (size_t i = 1; i < allocations.size(); ++i)
                allocations.erase(allocations.begin() + i);
            FillAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);

            // Set data for defragmentation retrieval
            for (auto& alloc : allocations)
                alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_GENERIC_READ);

            defragDesc.MaxAllocationsPerPass = 1;
            defragDesc.MaxBytesPerPass = BUF_SIZE;

            ComPtr<D3D12MA::DefragmentationContext> defragCtx;
            CHECK_HR(pool->BeginDefragmentation(&defragDesc, &defragCtx));

            for (size_t i = 0; i < BLOCK_SIZE / BUF_SIZE / 2; ++i)
            {
                D3D12MA::DEFRAGMENTATION_PASS_MOVE_INFO pass = {};
                CHECK_BOOL(defragCtx->BeginPass(&pass) == S_FALSE);

                ProcessDefragmentationPass(ctx, pass);

                CHECK_BOOL(defragCtx->EndPass(&pass) == S_FALSE);
            }

            D3D12MA::DEFRAGMENTATION_STATS defragStats = {};
            defragCtx->GetStats(&defragStats);
            CHECK_BOOL(defragStats.AllocationsMoved == 4 && defragStats.BytesMoved == 4 * BUF_SIZE);

            ValidateAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);
            allocations.clear();
        }

        // # Test 3
        // Buffers of variable size.
        // Create a number of buffers. Remove some percent of them.
        // Defragment while having some percent of them unmovable.
        // Expected result: Just simple validation.
        {
            for (size_t i = 0; i < 100; ++i)
            {
                D3D12_RESOURCE_DESC localResDesc = resDesc;
                localResDesc.Width = RandomBufSize();

                ComPtr<D3D12MA::Allocation> alloc;
                CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &localResDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
                    nullptr, &alloc, IID_NULL, nullptr));
                if (persistentlyMapped)
                {
                    CHECK_HR(alloc->GetResource()->Map(0, &mapRange, &mapPtr));
                }

                allocations.emplace_back(std::move(alloc));
            }

            const UINT32 percentToDelete = 60;
            const size_t numberToDelete = allocations.size() * percentToDelete / 100;
            for (size_t i = 0; i < numberToDelete; ++i)
            {
                size_t indexToDelete = rand.Generate() % (UINT32)allocations.size();
                allocations.erase(allocations.begin() + indexToDelete);
            }
            FillAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);

            // Non-movable allocations will be at the beginning of allocations array.
            const UINT32 percentNonMovable = 20;
            const size_t numberNonMovable = allocations.size() * percentNonMovable / 100;
            for (size_t i = 0; i < numberNonMovable; ++i)
            {
                size_t indexNonMovable = i + rand.Generate() % (UINT32)(allocations.size() - i);
                if (indexNonMovable != i)
                    std::swap(allocations[i], allocations[indexNonMovable]);
            }

            // Set data for defragmentation retrieval
            for (auto& alloc : allocations)
                alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_GENERIC_READ);

            defragDesc.MaxAllocationsPerPass = 0;
            defragDesc.MaxBytesPerPass = 0;

            ComPtr<D3D12MA::DefragmentationContext> defragCtx;
            CHECK_HR(pool->BeginDefragmentation(&defragDesc, &defragCtx));

            HRESULT hr = S_OK;
            D3D12MA::DEFRAGMENTATION_PASS_MOVE_INFO pass = {};
            while ((hr = defragCtx->BeginPass(&pass)) == S_FALSE)
            {
                D3D12MA::DEFRAGMENTATION_MOVE* end = pass.pMoves + pass.MoveCount;
                for (UINT32 i = 0; i < numberNonMovable; ++i)
                {
                    D3D12MA::DEFRAGMENTATION_MOVE* move = std::find_if(pass.pMoves, end, [&](D3D12MA::DEFRAGMENTATION_MOVE& move) { return move.pSrcAllocation == allocations[i].Get(); });
                    if (move != end)
                        move->Operation = D3D12MA::DEFRAGMENTATION_MOVE_OPERATION_IGNORE;
                }

                ProcessDefragmentationPass(ctx, pass);

                if ((hr = defragCtx->EndPass(&pass)) == S_OK)
                    break;
                CHECK_BOOL(hr == S_FALSE);
            }
            CHECK_BOOL(hr == S_OK);

            ValidateAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);
            allocations.clear();
        }
    }
}

static void TestDefragmentationAlgorithms(const TestContext& ctx)
{
    wprintf(L"Test defragmentation algorithms\n");

    RandomNumberGenerator rand(669);

    const UINT ALLOC_SEED = 20091225;
    const UINT64 BUF_SIZE = 0x10000;
    const UINT64 BLOCK_SIZE = BUF_SIZE * 400;

    const UINT64 MIN_BUF_SIZE = 32;
    const UINT64 MAX_BUF_SIZE = BUF_SIZE * 4;
    auto RandomBufSize = [&]() -> UINT64
    {
        return AlignUp<UINT64>(rand.Generate() % (MAX_BUF_SIZE - MIN_BUF_SIZE + 1) + MIN_BUF_SIZE, 64);
    };

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_UPLOAD,
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
        D3D12MA::POOL_FLAG_NONE,
        BLOCK_SIZE };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    D3D12_RESOURCE_DESC resDesc = {};
    FillResourceDescForBuffer(resDesc, BUF_SIZE);

    D3D12MA::DEFRAGMENTATION_DESC defragDesc = {};

    std::vector<ComPtr<D3D12MA::Allocation>> allocations;

    for (UINT8 i = 0; i < 3; ++i)
    {
        switch (i)
        {
        case 0:
            defragDesc.Flags = D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_FAST;
            break;
        case 1:
            defragDesc.Flags = D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED;
            break;
        case 2:
            defragDesc.Flags = D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_FULL;
            break;
        }
        wprintf(L"  Algorithm = %s\n", DefragmentationAlgorithmToStr(defragDesc.Flags));

        // 0 - Without immovable allocations
        // 1 - With immovable allocations
        for (uint8_t j = 0; j < 2; ++j)
        {
            for (size_t i = 0; i < 800; ++i)
            {
                resDesc.Width = RandomBufSize();

                ComPtr<D3D12MA::Allocation> alloc;
                CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
                    nullptr, &alloc, IID_NULL, nullptr));
                allocations.emplace_back(std::move(alloc));
            }

            const UINT32 percentToDelete = 55;
            const size_t numberToDelete = allocations.size() * percentToDelete / 100;
            for (size_t i = 0; i < numberToDelete; ++i)
            {
                size_t indexToDelete = rand.Generate() % (uint32_t)allocations.size();
                allocations.erase(allocations.begin() + indexToDelete);
            }
            FillAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);

            // Non-movable allocations will be at the beginning of allocations array.
            const UINT32 percentNonMovable = 20;
            const size_t numberNonMovable = j == 0 ? 0 : (allocations.size() * percentNonMovable / 100);
            for (size_t i = 0; i < numberNonMovable; ++i)
            {
                size_t indexNonMovable = i + rand.Generate() % (UINT32)(allocations.size() - i);
                if (indexNonMovable != i)
                    std::swap(allocations[i], allocations[indexNonMovable]);
            }

            // Set data for defragmentation retrieval
            for (auto& alloc : allocations)
                alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_GENERIC_READ);

            std::wstring output = DefragmentationAlgorithmToStr(defragDesc.Flags);
            if (j == 0)
                output += L"_NoMove";
            else
                output += L"_Move";
            SaveStatsStringToFile(ctx, (output + L"_Before.json").c_str());

            ComPtr<D3D12MA::DefragmentationContext> defragCtx;
            CHECK_HR(pool->BeginDefragmentation(&defragDesc, &defragCtx));

            HRESULT hr = S_OK;
            D3D12MA::DEFRAGMENTATION_PASS_MOVE_INFO pass = {};
            while ((hr = defragCtx->BeginPass(&pass)) == S_FALSE)
            {
                D3D12MA::DEFRAGMENTATION_MOVE* end = pass.pMoves + pass.MoveCount;
                for (UINT32 i = 0; i < numberNonMovable; ++i)
                {
                    D3D12MA::DEFRAGMENTATION_MOVE* move = std::find_if(pass.pMoves, end, [&](D3D12MA::DEFRAGMENTATION_MOVE& move) { return move.pSrcAllocation == allocations[i].Get(); });
                    if (move != end)
                        move->Operation = D3D12MA::DEFRAGMENTATION_MOVE_OPERATION_IGNORE;
                }
                for (UINT32 i = 0; i < pass.MoveCount; ++i)
                {
                    auto it = std::find_if(allocations.begin(), allocations.end(), [&](const ComPtr<D3D12MA::Allocation>& alloc) { return pass.pMoves[i].pSrcAllocation == alloc.Get(); });
                    assert(it != allocations.end());
                }

                ProcessDefragmentationPass(ctx, pass);

                if ((hr = defragCtx->EndPass(&pass)) == S_OK)
                    break;
                CHECK_BOOL(hr == S_FALSE);
            }
            CHECK_BOOL(hr == S_OK);

            SaveStatsStringToFile(ctx, (output + L"_After.json").c_str());
            ValidateAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);
            allocations.clear();
        }
    }
}

static void TestDefragmentationFull(const TestContext& ctx)
{
    const UINT ALLOC_SEED = 20101220;
    std::vector<ComPtr<D3D12MA::Allocation>> allocations;

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_UPLOAD,
        D3D12MA::ALLOCATION_FLAG_NONE,
        NULL, // privateData
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };

    D3D12_RESOURCE_DESC resDesc = {};
    FillResourceDescForBuffer(resDesc, 0x10000);

    // Create initial allocations.
    for (size_t i = 0; i < 400; ++i)
    {
        ComPtr<D3D12MA::Allocation> alloc;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
            nullptr, &alloc, IID_NULL, nullptr));
        allocations.emplace_back(std::move(alloc));
    }
    FillAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);

    // Delete random allocations
    const size_t allocationsToDeletePercent = 80;
    size_t allocationsToDelete = allocations.size() * allocationsToDeletePercent / 100;
    for (size_t i = 0; i < allocationsToDelete; ++i)
    {
        size_t index = (size_t)rand() % allocations.size();
        allocations.erase(allocations.begin() + index);
    }
    SaveStatsStringToFile(ctx, L"FullBefore.json");

    {
        // Set data for defragmentation retrieval
        for (auto& alloc : allocations)
            alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_GENERIC_READ);

        const UINT32 defragCount = 1;
        for (UINT32 defragIndex = 0; defragIndex < defragCount; ++defragIndex)
        {
            D3D12MA::DEFRAGMENTATION_DESC defragDesc = {};
            defragDesc.Flags = D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_FULL;

            wprintf(L"Test defragmentation full #%u\n", defragIndex);

            time_point begTime = std::chrono::high_resolution_clock::now();

            D3D12MA::DEFRAGMENTATION_STATS stats;
            Defragment(ctx, defragDesc, nullptr, &stats);

            float defragmentDuration = ToFloatSeconds(std::chrono::high_resolution_clock::now() - begTime);

            wprintf(L"Moved allocations %u, bytes %llu\n", stats.AllocationsMoved, stats.BytesMoved);
            wprintf(L"Freed blocks %u, bytes %llu\n", stats.HeapsFreed, stats.BytesFreed);
            wprintf(L"Time: %.2f s\n", defragmentDuration);

            SaveStatsStringToFile(ctx, (L"FullAfter_" + std::to_wstring(defragIndex) + L".json").c_str());
        }
    }

    ValidateAllocationsData(allocations.data(), allocations.size(), ALLOC_SEED);
}

static void TestDefragmentationGpu(const TestContext& ctx)
{
    wprintf(L"Test defragmentation GPU\n");

    const UINT ALLOC_SEED = 20180314;
    std::vector<ComPtr<D3D12MA::Allocation>> allocations;

    // Create that many allocations to surely fill 3 new blocks of 256 MB.
    const UINT64 bufSizeMin = 5ull * 1024 * 1024;
    const UINT64 bufSizeMax = 10ull * 1024 * 1024;
    const UINT64 totalSize = 3ull * 256 * 1024 * 1024;
    const size_t bufCount = (size_t)(totalSize / bufSizeMin);
    const size_t percentToLeave = 30;
    const size_t percentNonMovable = 3;
    RandomNumberGenerator rand = { 234522 };

    D3D12_RESOURCE_DESC resDesc = {};
    FillResourceDescForBuffer(resDesc, 0x10000);

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12MA::ALLOCATION_FLAG_NONE,
        NULL, // privateData
        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };

    // Create all intended buffers.
    for (size_t i = 0; i < bufCount; ++i)
    {
        resDesc.Width = AlignUp(rand.Generate() % (bufSizeMax - bufSizeMin) + bufSizeMin, 32ull);

        ComPtr<D3D12MA::Allocation> alloc;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST,
            nullptr, &alloc, IID_NULL, nullptr));
        allocations.emplace_back(std::move(alloc));
    }

    // Destroy some percentage of them.
    {
        const size_t buffersToDestroy = RoundDiv<size_t>(bufCount * (100 - percentToLeave), 100);
        for (size_t i = 0; i < buffersToDestroy; ++i)
        {
            const size_t index = rand.Generate() % allocations.size();
            allocations.erase(allocations.begin() + index);
        }
    }

    // Set data for defragmentation retrieval
    for (auto& alloc : allocations)
        alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);

    // Fill them with meaningful data.
    FillAllocationsDataGPU(ctx, allocations.data(), allocations.size(), ALLOC_SEED);

    SaveStatsStringToFile(ctx, L"GPU_defragmentation_A_before.json");
    // Defragment using GPU only.
    {
        const size_t numberNonMovable = allocations.size() * percentNonMovable / 100;
        for (size_t i = 0; i < numberNonMovable; ++i)
        {
            size_t indexNonMovable = i + rand.Generate() % (UINT32)(allocations.size() - i);
            if (indexNonMovable != i)
                std::swap(allocations[i], allocations[indexNonMovable]);
        }

        D3D12MA::DEFRAGMENTATION_DESC defragDesc = {};
        D3D12MA::DEFRAGMENTATION_STATS stats;
        Defragment(ctx, defragDesc, nullptr, &stats);

        CHECK_BOOL(stats.AllocationsMoved > 0 && stats.BytesMoved > 0);
        CHECK_BOOL(stats.HeapsFreed > 0 && stats.BytesFreed > 0);
    }

    SaveStatsStringToFile(ctx, L"GPU_defragmentation_B_after.json");
    ValidateAllocationsDataGPU(ctx, allocations.data(), allocations.size(), ALLOC_SEED);
}

static void TestDefragmentationIncrementalBasic(const TestContext& ctx)
{
    wprintf(L"Test defragmentation incremental basic\n");

    const UINT ALLOC_SEED = 20210918;
    std::vector<ComPtr<D3D12MA::Allocation>> allocations;

    // Create that many allocations to surely fill 3 new blocks of 256 MB.
    const std::array<UINT32, 3> imageSizes = { 256, 512, 1024 };
    const UINT64 bufSizeMin = 5ull * 1024 * 1024;
    const UINT64 bufSizeMax = 10ull * 1024 * 1024;
    const UINT64 totalSize = 3ull * 256 * 1024 * 1024;
    const size_t imageCount = totalSize / ((size_t)imageSizes[0] * imageSizes[0] * 4) / 2;
    const size_t bufCount = (size_t)(totalSize / bufSizeMin) / 2;
    const size_t percentToLeave = 30;
    RandomNumberGenerator rand = { 234522 };

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_DEFAULT };

    D3D12_RESOURCE_DESC resDesc = {};
    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resDesc.Alignment = 0;
    resDesc.DepthOrArraySize = 1;
    resDesc.MipLevels = 1;
    resDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resDesc.SampleDesc.Count = 1;
    resDesc.SampleDesc.Quality = 0;
    resDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resDesc.Flags = D3D12_RESOURCE_FLAG_NONE;

    // Create all intended images.
    for (size_t i = 0; i < imageCount; ++i)
    {
        const UINT32 size = imageSizes[rand.Generate() % 3];
        resDesc.Width = size;
        resDesc.Height = size;

        ComPtr<D3D12MA::Allocation> alloc;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST,
            nullptr, &alloc, IID_NULL, nullptr));

        alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
        allocations.emplace_back(std::move(alloc));
    }

    // And all buffers
    FillResourceDescForBuffer(resDesc, 0x10000);
    for (size_t i = 0; i < bufCount; ++i)
    {
        resDesc.Width = AlignUp(rand.Generate() % (bufSizeMax - bufSizeMin) + bufSizeMin, 32ull);

        ComPtr<D3D12MA::Allocation> alloc;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST,
            nullptr, &alloc, IID_NULL, nullptr));

        alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
        allocations.emplace_back(std::move(alloc));
    }

    // Destroy some percentage of them.
    {
        const size_t allocationsToDestroy = RoundDiv<size_t>((imageCount + bufCount) * (100 - percentToLeave), 100);
        for (size_t i = 0; i < allocationsToDestroy; ++i)
        {
            const size_t index = rand.Generate() % allocations.size();
            allocations.erase(allocations.begin() + index);
        }
    }

    // Fill them with meaningful data.
    FillAllocationsDataGPU(ctx, allocations.data(), allocations.size(), ALLOC_SEED);

    SaveStatsStringToFile(ctx, L"GPU_defragmentation_incremental_basic_A_before.json");
    // Defragment using GPU only.
    {
        D3D12MA::DEFRAGMENTATION_DESC defragDesc = {};
        ComPtr<D3D12MA::DefragmentationContext> defragCtx;
        ctx.allocator->BeginDefragmentation(&defragDesc, &defragCtx);

        HRESULT hr = S_OK;
        D3D12MA::DEFRAGMENTATION_PASS_MOVE_INFO pass = {};
        while ((hr = defragCtx->BeginPass(&pass)) == S_FALSE)
        {
            // Ignore data outside of test
            for (UINT32 i = 0; i < pass.MoveCount; ++i)
            {
                auto it = std::find_if(allocations.begin(), allocations.end(), [&](const ComPtr<D3D12MA::Allocation>& alloc) { return pass.pMoves[i].pSrcAllocation == alloc.Get(); });
                if (it == allocations.end())
                    pass.pMoves[i].Operation = D3D12MA::DEFRAGMENTATION_MOVE_OPERATION_IGNORE;
            }

            ProcessDefragmentationPass(ctx, pass);

            if ((hr = defragCtx->EndPass(&pass)) == S_OK)
                break;
            CHECK_BOOL(hr == S_FALSE);
        }
        CHECK_BOOL(hr == S_OK);

        D3D12MA::DEFRAGMENTATION_STATS stats = {};
        defragCtx->GetStats(&stats);
        CHECK_BOOL(stats.AllocationsMoved > 0 && stats.BytesMoved > 0);
        CHECK_BOOL(stats.HeapsFreed > 0 && stats.BytesFreed > 0);
    }

    SaveStatsStringToFile(ctx, L"GPU_defragmentation_incremental_basic_B_after.json");
    ValidateAllocationsDataGPU(ctx, allocations.data(), allocations.size(), ALLOC_SEED);
}

void TestDefragmentationIncrementalComplex(const TestContext& ctx)
{
    wprintf(L"Test defragmentation incremental complex\n");

    const UINT ALLOC_SEED = 20180112;
    std::vector<ComPtr<D3D12MA::Allocation>> allocations;

    // Create that many allocations to surely fill 3 new blocks of 256 MB.
    const std::array<UINT32, 3> imageSizes = { 256, 512, 1024 };
    const UINT64 bufSizeMin = 5ull * 1024 * 1024;
    const UINT64 bufSizeMax = 10ull * 1024 * 1024;
    const UINT64 totalSize = 3ull * 256 * 1024 * 1024;
    const size_t imageCount = (size_t)(totalSize / (imageSizes[0] * imageSizes[0] * 4)) / 2;
    const size_t bufCount = (size_t)(totalSize / bufSizeMin) / 2;
    const size_t percentToLeave = 30;
    RandomNumberGenerator rand = { 234522 };

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_DEFAULT };

    D3D12_RESOURCE_DESC resDesc = {};
    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resDesc.Alignment = 0;
    resDesc.DepthOrArraySize = 1;
    resDesc.MipLevels = 1;
    resDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resDesc.SampleDesc.Count = 1;
    resDesc.SampleDesc.Quality = 0;
    resDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resDesc.Flags = D3D12_RESOURCE_FLAG_NONE;

    // Create all intended images.
    for (size_t i = 0; i < imageCount; ++i)
    {
        const UINT32 size = imageSizes[rand.Generate() % 3];
        resDesc.Width = size;
        resDesc.Height = size;

        ComPtr<D3D12MA::Allocation> alloc;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST,
            nullptr, &alloc, IID_NULL, nullptr));

        alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
        allocations.emplace_back(std::move(alloc));
    }

    // And all buffers
    FillResourceDescForBuffer(resDesc, 0x10000);
    for (size_t i = 0; i < bufCount; ++i)
    {
        resDesc.Width = AlignUp(rand.Generate() % (bufSizeMax - bufSizeMin) + bufSizeMin, 32ull);

        ComPtr<D3D12MA::Allocation> alloc;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST,
            nullptr, &alloc, IID_NULL, nullptr));

        alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
        allocations.emplace_back(std::move(alloc));
    }

    // Destroy some percentage of them.
    {
        const size_t allocationsToDestroy = RoundDiv<size_t>((imageCount + bufCount) * (100 - percentToLeave), 100);
        for (size_t i = 0; i < allocationsToDestroy; ++i)
        {
            const size_t index = rand.Generate() % allocations.size();
            allocations.erase(allocations.begin() + index);
        }
    }

    // Fill them with meaningful data.
    FillAllocationsDataGPU(ctx, allocations.data(), allocations.size(), ALLOC_SEED);

    SaveStatsStringToFile(ctx, L"GPU_defragmentation_incremental_complex_A_before.json");

    const size_t maxAdditionalAllocations = 100;
    std::vector<ComPtr<D3D12MA::Allocation>> additionalAllocations;
    additionalAllocations.reserve(maxAdditionalAllocations);

    const auto makeAdditionalAllocation = [&]()
    {
        if (additionalAllocations.size() < maxAdditionalAllocations)
        {
            resDesc.Width = AlignUp(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16ull);
            ComPtr<D3D12MA::Allocation> alloc;
            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
                nullptr, &alloc, IID_NULL, nullptr));
            alloc->SetPrivateData((void*)D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
            additionalAllocations.emplace_back(std::move(alloc));
        }
    };

    // Defragment using GPU only.
    {
        D3D12MA::DEFRAGMENTATION_DESC defragDesc = {};
        defragDesc.Flags = D3D12MA::DEFRAGMENTATION_FLAG_ALGORITHM_FULL;

        ComPtr<D3D12MA::DefragmentationContext> defragCtx;
        ctx.allocator->BeginDefragmentation(&defragDesc, &defragCtx);

        makeAdditionalAllocation();

        HRESULT hr = S_OK;
        D3D12MA::DEFRAGMENTATION_PASS_MOVE_INFO pass = {};
        while ((hr = defragCtx->BeginPass(&pass)) == S_FALSE)
        {
            makeAdditionalAllocation();

            // Ignore data outside of test
            for (UINT32 i = 0; i < pass.MoveCount; ++i)
            {
                auto it = std::find_if(allocations.begin(), allocations.end(), [&](const ComPtr<D3D12MA::Allocation>& alloc) { return pass.pMoves[i].pSrcAllocation == alloc.Get(); });
                if (it == allocations.end())
                {
                    auto it = std::find_if(additionalAllocations.begin(), additionalAllocations.end(), [&](const ComPtr<D3D12MA::Allocation>& alloc) { return pass.pMoves[i].pSrcAllocation == alloc.Get(); });
                    if (it == additionalAllocations.end())
                        pass.pMoves[i].Operation = D3D12MA::DEFRAGMENTATION_MOVE_OPERATION_IGNORE;
                }
            }

            ProcessDefragmentationPass(ctx, pass);

            makeAdditionalAllocation();

            if ((hr = defragCtx->EndPass(&pass)) == S_OK)
                break;
            CHECK_BOOL(hr == S_FALSE);
        }
        CHECK_BOOL(hr == S_OK);

        D3D12MA::DEFRAGMENTATION_STATS stats = {};
        defragCtx->GetStats(&stats);

        CHECK_BOOL(stats.AllocationsMoved > 0 && stats.BytesMoved > 0);
        CHECK_BOOL(stats.HeapsFreed > 0 && stats.BytesFreed > 0);
    }

    SaveStatsStringToFile(ctx, L"GPU_defragmentation_incremental_complex_B_after.json");
    ValidateAllocationsDataGPU(ctx, allocations.data(), allocations.size(), ALLOC_SEED);
}

static void TestGroupVirtual(const TestContext& ctx)
{
    TestVirtualBlocks(ctx);
    TestVirtualBlocksAlgorithms(ctx);
    TestVirtualBlocksAlgorithmsBenchmark(ctx);
}

static void TestGroupBasics(const TestContext& ctx)
{
#if D3D12MA_DEBUG_MARGIN
    TestDebugMargin(ctx);
    TestDebugMarginNotInVirtualAllocator(ctx);
#else
    TestJson(ctx);
    TestCommittedResourcesAndJson(ctx);
    TestSmallBuffers(ctx);
    TestCustomHeapFlags(ctx);
    TestPlacedResources(ctx);
    TestOtherComInterface(ctx);
    TestCustomPools(ctx);
    TestCustomPool_MinAllocationAlignment(ctx);
    TestCustomPool_Committed(ctx);
    TestCustomPool_AlwaysCommitted(ctx);
    TestPoolsAndAllocationParameters(ctx);
    TestCustomHeaps(ctx);
    TestStandardCustomCommittedPlaced(ctx);
    TestAliasingMemory(ctx);
    TestAliasingImplicitCommitted(ctx);
    TestPoolMsaaTextureAsCommitted(ctx);
    TestMapping(ctx);
    TestStats(ctx);
    TestTransfer(ctx);
    TestMultithreading(ctx);
    TestLinearAllocator(ctx);
    TestLinearAllocatorMultiBlock(ctx);
    ManuallyTestLinearAllocator(ctx);
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
    TestDevice4(ctx);
#endif
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
    TestDevice8(ctx);
#endif
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
    TestDevice10(ctx);
#endif
#ifdef __ID3D12Device12_INTERFACE_DEFINED__
    TestDevice12(ctx);
#endif

    TestGPUUploadHeap(ctx);

    FILE* file;
    fopen_s(&file, "Results.csv", "w");
    assert(file != NULL);
    BenchmarkAlgorithms(ctx, file);
    fclose(file);
#endif // #if D3D12_DEBUG_MARGIN
}

static void TestGroupDefragmentation(const TestContext& ctx)
{
    TestDefragmentationSimple(ctx);
    TestDefragmentationAlgorithms(ctx);
    TestDefragmentationFull(ctx);
    TestDefragmentationGpu(ctx);
    TestDefragmentationIncrementalBasic(ctx);
    TestDefragmentationIncrementalComplex(ctx);
}

void Test(const TestContext& ctx)
{
    wprintf(L"TESTS BEGIN\n");

    if(false)
    {
        ////////////////////////////////////////////////////////////////////////////////
        // Temporarily insert custom tests here:
        return;
    }

    TestGroupVirtual(ctx);
    TestGroupBasics(ctx);
    TestGroupDefragmentation(ctx);

    wprintf(L"TESTS END\n");
}
