//
// 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 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 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 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 TestCustomHeaps(const TestContext& ctx)
{
    using namespace D3D12MA;

    wprintf(L"Test custom heap\n");

    // Use custom pool but the same as READBACK, which should be always available.
    D3D12_HEAP_PROPERTIES heapProps = {};
    heapProps.Type = D3D12_HEAP_TYPE_CUSTOM;
    heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
    heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; // System memory

    const UINT64 BUFFER_SIZE = 1 * MEGABYTE;
    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, BUFFER_SIZE);

    Budget localBudgetBeg = {}, nonLocalBudgetBeg = {};
    ctx.allocator->GetBudget(&localBudgetBeg, &nonLocalBudgetBeg);
    CheckBudgetBasics(ctx, localBudgetBeg, nonLocalBudgetBeg);

    TotalStatistics globalStatsBeg = {};
    ctx.allocator->CalculateStatistics(&globalStatsBeg);
    CheckTotalStatistics(globalStatsBeg);

    // Test 0: Custom pool with fixed block size (it must end up as placed).
    // Test 1: Custom pool, requested committed.

    for (size_t testIndex = 0; testIndex < 2; ++testIndex)
    {
        const bool requestCommitted = testIndex == 1;

        POOL_DESC poolDesc = CPOOL_DESC{ heapProps, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };
        if (testIndex == 0)
        {
            poolDesc.BlockSize = 10 * MEGABYTE;
            poolDesc.MinBlockCount = 1;
            poolDesc.MaxBlockCount = 1;
        }
        ComPtr<Pool> pool;
        CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

        ALLOCATION_DESC allocDesc = CALLOCATION_DESC{ pool.Get() };
        if (requestCommitted)
        {
            allocDesc.Flags = ALLOCATION_FLAG_COMMITTED;
        }

        ComPtr<Allocation> alloc;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc,
            D3D12_RESOURCE_STATE_COMMON, NULL, &alloc, IID_NULL, NULL));

        const bool isCommitted = alloc->GetHeap() == NULL;
        CHECK_BOOL(isCommitted == requestCommitted);

        Budget localBudgetEnd = {}, nonLocalBudgetEnd = {};
        ctx.allocator->GetBudget(&localBudgetEnd, &nonLocalBudgetEnd);
        CheckBudgetBasics(ctx, localBudgetEnd, nonLocalBudgetEnd);

        D3D12MA::TotalStatistics globalStatsEnd = {};
        ctx.allocator->CalculateStatistics(&globalStatsEnd);
        CheckTotalStatistics(globalStatsEnd);

        // Make sure it is accounted only in CUSTOM heap not any of the standard heaps.
        
        const UINT thisMemSegmentGroupIndex = ctx.allocator->IsUMA() ? 0 : 1;
        const UINT otherMemSegmentGroupIndex = 1 - thisMemSegmentGroupIndex;

        CHECK_BOOL(globalStatsEnd.Total.Stats.AllocationCount == globalStatsBeg.Total.Stats.AllocationCount + 1);
        CHECK_BOOL(globalStatsEnd.Total.Stats.BlockCount == globalStatsBeg.Total.Stats.BlockCount + 1);
        CHECK_BOOL(globalStatsEnd.Total.Stats.AllocationBytes == globalStatsBeg.Total.Stats.AllocationBytes + BUFFER_SIZE);

        CHECK_BOOL(memcmp(&globalStatsEnd.HeapType[0], &globalStatsBeg.HeapType[0], sizeof(D3D12MA::DetailedStatistics)) == 0);
        CHECK_BOOL(memcmp(&globalStatsEnd.HeapType[1], &globalStatsBeg.HeapType[1], sizeof(D3D12MA::DetailedStatistics)) == 0);
        CHECK_BOOL(memcmp(&globalStatsEnd.HeapType[2], &globalStatsBeg.HeapType[2], sizeof(D3D12MA::DetailedStatistics)) == 0);
        CHECK_BOOL(memcmp(&globalStatsEnd.HeapType[4], &globalStatsBeg.HeapType[4], sizeof(D3D12MA::DetailedStatistics)) == 0);
        
        CHECK_BOOL(globalStatsEnd.HeapType[3].Stats.AllocationCount == globalStatsBeg.HeapType[3].Stats.AllocationCount + 1);
        CHECK_BOOL(globalStatsEnd.HeapType[3].Stats.BlockCount == globalStatsBeg.HeapType[3].Stats.BlockCount + 1);
        CHECK_BOOL(globalStatsEnd.HeapType[3].Stats.AllocationBytes == globalStatsBeg.HeapType[3].Stats.AllocationBytes + BUFFER_SIZE);
        
        CHECK_BOOL(globalStatsEnd.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.AllocationCount ==
            globalStatsBeg.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.AllocationCount + 1);
        CHECK_BOOL(globalStatsEnd.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.BlockCount ==
            globalStatsBeg.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.BlockCount + 1);
        CHECK_BOOL(globalStatsEnd.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.AllocationBytes ==
            globalStatsBeg.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.AllocationBytes + BUFFER_SIZE);

        CHECK_BOOL(memcmp(&globalStatsEnd.MemorySegmentGroup[otherMemSegmentGroupIndex],
            &globalStatsBeg.MemorySegmentGroup[otherMemSegmentGroupIndex], sizeof(D3D12MA::DetailedStatistics)) == 0);

        const Budget& thisBudgetBeg = ctx.allocator->IsUMA() ? localBudgetBeg : nonLocalBudgetBeg;
        const Budget& thisBudgetEnd = ctx.allocator->IsUMA() ? localBudgetEnd : nonLocalBudgetEnd;

        CHECK_BOOL(thisBudgetEnd.Stats.AllocationCount == thisBudgetBeg.Stats.AllocationCount + 1);
        CHECK_BOOL(thisBudgetEnd.Stats.BlockCount == thisBudgetBeg.Stats.BlockCount + 1);
        CHECK_BOOL(thisBudgetEnd.Stats.AllocationBytes == thisBudgetBeg.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;
            CHECK_HR(res->Map(0, &EMPTY_RANGE, (void**)&mappedPtr));
            *mappedPtr = 0xDEADC0DE;
            res->Unmap(0, nullptr);
        }
    }
}

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 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");
}
