//
// Copyright (c) 2019-2026 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", };

constexpr D3D12_RESOURCE_FLAGS D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT_COPY = (D3D12_RESOURCE_FLAGS)0x400;

// 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 FillResourceDescForSmallMsaaRenderTarget(D3D12_RESOURCE_DESC& outResourceDesc)
{
    outResourceDesc = {};
    outResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    outResourceDesc.Alignment = 0;
    outResourceDesc.Width = 64;
    outResourceDesc.Height = 64;
    outResourceDesc.DepthOrArraySize = 1;
    outResourceDesc.MipLevels = 1;
    outResourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    outResourceDesc.SampleDesc.Count = 2;
    outResourceDesc.SampleDesc.Quality = 0;
    outResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    outResourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
}

static void ValidatePlacedTextureAlignmentAgainstRuntime(
    const TestContext& ctx,
    const D3D12MA::Allocation* alloc,
    const D3D12_RESOURCE_DESC& resourceDesc)
{
    CHECK_BOOL(alloc != nullptr);
    CHECK_BOOL(alloc->GetHeap() != nullptr);

    D3D12_RESOURCE_DESC alignedDesc = resourceDesc;
    alignedDesc.Alignment = D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT;
    const D3D12_RESOURCE_ALLOCATION_INFO expectedInfo =
        ctx.device->GetResourceAllocationInfo(0, 1, &alignedDesc);

    CHECK_BOOL(expectedInfo.SizeInBytes != UINT64_MAX);
    CHECK_BOOL(alloc->GetAlignment() == expectedInfo.Alignment);
    CHECK_BOOL(alloc->GetOffset() % expectedInfo.Alignment == 0);
    CHECK_BOOL(alloc->GetSize() == expectedInfo.SizeInBytes);
}

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)
            {
                // Fix for D3D12 ERROR: ID3D12Device::CreatePlacedResource: D3D12_RESOURCE_DESC::Alignment is invalid. The value is 8. When D3D12_RESOURCE_DESC::Flag bit for D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT is set, Alignment must be 0. [ STATE_CREATION ERROR #721: CREATERESOURCE_INVALIDALIGNMENT]
                if ((resDesc.Flags & D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT_COPY) != 0)
                    resDesc.Alignment = 0;

                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)
            {
                // Fix for D3D12 ERROR: ID3D12Device::CreatePlacedResource: D3D12_RESOURCE_DESC::Alignment is invalid. The value is 8. When D3D12_RESOURCE_DESC::Flag bit for D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT is set, Alignment must be 0. [ STATE_CREATION ERROR #721: CREATERESOURCE_INVALIDALIGNMENT]
                if ((resDesc.Flags & D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT_COPY) != 0)
                    resDesc.Alignment = 0;

                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 bool QueryMsaa64KBAlignedTextureSupported(const TestContext& ctx)
{
    D3D12_FEATURE_DATA_D3D12_OPTIONS4 options4 = {};
    CHECK_HR(ctx.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &options4, sizeof(options4)));
    return options4.MSAA64KBAlignedTextureSupported != FALSE;
}

static UINT64 ExpectedMsaaTexturePlacementAlignment(bool msaa64KBAlignedTextureSupported)
{
    return msaa64KBAlignedTextureSupported ?
        D3D12_SMALL_MSAA_RESOURCE_PLACEMENT_ALIGNMENT :
        D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT;
}

static void ValidatePlacedSmallMsaaTextureAllocation(const D3D12MA::Allocation* alloc, UINT64 expectedAlignment)
{
    CHECK_BOOL(alloc != nullptr);
    CHECK_BOOL(alloc->GetResource() != nullptr);
    CHECK_BOOL(alloc->GetHeap() != nullptr);
    CHECK_BOOL(alloc->GetAlignment() == expectedAlignment);
    CHECK_BOOL(alloc->GetOffset() % expectedAlignment == 0);
    CHECK_BOOL(alloc->GetHeap()->GetDesc().Alignment == D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
}


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_RESOURCE_STATE_COMMON;
            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;
                break;
            case 1:
                allocDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD;
                break;
            case 2:
                allocDesc.HeapType = D3D12_HEAP_TYPE_READBACK;
                break;
            case 3:
                allocDesc.HeapType = D3D12_HEAP_TYPE_CUSTOM;
                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;
                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_COMMON,
            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");

    const bool isTightAlignmentEnabled = ctx.allocator->IsTightAlignmentSupported() &&
        (ctx.allocatorFlags & D3D12MA::ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT) == 0;
    const bool allowSmallBuffersCommitted =
        (ctx.allocatorFlags & D3D12MA::ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED) == 0;
    const bool expectSmallBuffersCommitted = !isTightAlignmentEnabled &&
        allowSmallBuffersCommitted;

    const auto testPool = [&](D3D12MA::POOL_FLAGS poolFlags, bool expectDefaultCommitted)
    {
        D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
            D3D12_HEAP_TYPE_DEFAULT,
            D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
            poolFlags };
        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());
            const bool isCommitted = resWithAlloc.allocation->GetHeap() == NULL;
            CHECK_BOOL(isCommitted == expectDefaultCommitted);
        }

        // 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.
        }
    };

    testPool(D3D12MA::POOL_FLAG_NONE, expectSmallBuffersCommitted);
    testPool(D3D12MA::POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT, allowSmallBuffersCommitted);
}

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_COMMON, 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_COMMON, 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_COMMON, 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_COMMON, 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);
    CHECK_BOOL(alloc->GetOffset() == 0);
}

static void TestMsaa64KBAlignedTextureSupported_DefaultPool(const TestContext& ctx)
{
    wprintf(L"Test MSAA 64 KB alignment in default pool\n");

    CHECK_BOOL((ctx.allocatorFlags & D3D12MA::ALLOCATOR_FLAG_ALWAYS_COMMITTED) == 0);
    CHECK_BOOL((ctx.allocatorFlags & D3D12MA::ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED) == 0);

    const UINT64 expectedAlignment =
        ExpectedMsaaTexturePlacementAlignment(QueryMsaa64KBAlignedTextureSupported(ctx));

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ D3D12_HEAP_TYPE_DEFAULT };

    D3D12_RESOURCE_DESC resDesc = {};
    FillResourceDescForSmallMsaaRenderTarget(resDesc);

    ComPtr<D3D12MA::Allocation> alloc;
    ComPtr<ID3D12Resource> resource;
    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_RENDER_TARGET,
        nullptr, &alloc, IID_PPV_ARGS(&resource)));

    ValidatePlacedSmallMsaaTextureAllocation(alloc.Get(), expectedAlignment);
}

static void TestMsaa64KBAlignedTextureSupported_CustomPool(const TestContext& ctx)
{
    wprintf(L"Test MSAA 64 KB alignment in custom pool\n");

    const UINT64 expectedAlignment =
        ExpectedMsaaTexturePlacementAlignment(QueryMsaa64KBAlignedTextureSupported(ctx));

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES,
        D3D12MA::POOL_FLAG_NONE };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    D3D12_RESOURCE_DESC resDesc = {};
    FillResourceDescForSmallMsaaRenderTarget(resDesc);

    ComPtr<D3D12MA::Allocation> alloc;
    ComPtr<ID3D12Resource> resource;
    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_RENDER_TARGET,
        nullptr, &alloc, IID_PPV_ARGS(&resource)));

    ValidatePlacedSmallMsaaTextureAllocation(alloc.Get(), expectedAlignment);
}

static void TestSmallTextureAlignmentAcrossDimensions(const TestContext& ctx)
{
    wprintf(L"Test small texture alignment across dimensions\n");

    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
        D3D12_HEAP_TYPE_DEFAULT,
        D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES,
        D3D12MA::POOL_FLAG_NONE };
    ComPtr<D3D12MA::Pool> pool;
    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

    auto createAndValidate = [&](const D3D12_RESOURCE_DESC& resourceDesc)
    {
        ComPtr<D3D12MA::Allocation> alloc;
        ComPtr<ID3D12Resource> resource;
        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resourceDesc, D3D12_RESOURCE_STATE_COPY_DEST,
            nullptr, &alloc, IID_PPV_ARGS(&resource)));
        ValidatePlacedTextureAlignmentAgainstRuntime(ctx, alloc.Get(), resourceDesc);
    };

    D3D12_RESOURCE_DESC resDesc = {};
    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE1D;
    resDesc.Alignment = 0;
    resDesc.Width = 1024;
    resDesc.Height = 1;
    resDesc.DepthOrArraySize = 7;
    resDesc.MipLevels = 4;
    resDesc.Format = DXGI_FORMAT_R8_UNORM;
    resDesc.SampleDesc.Count = 1;
    resDesc.SampleDesc.Quality = 0;
    resDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
    createAndValidate(resDesc);

    resDesc = {};
    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resDesc.Alignment = 0;
    resDesc.Width = 64;
    resDesc.Height = 64;
    resDesc.DepthOrArraySize = 8;
    resDesc.MipLevels = 4;
    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;
    createAndValidate(resDesc);

    resDesc = {};
    resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D;
    resDesc.Alignment = 0;
    resDesc.Width = 8;
    resDesc.Height = 8;
    resDesc.DepthOrArraySize = 8;
    resDesc.MipLevels = 4;
    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;
    createAndValidate(resDesc);
}

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_COMMON,
            NULL,
            &resourcesUpload[i].allocation,
            IID_PPV_ARGS(&resourcesUpload[i].resource)) );

        CHECK_HR( ctx.allocator->CreateResource(
            &allocDescDefault,
            &resourceDesc,
            D3D12_RESOURCE_STATE_COMMON,
            NULL,
            &resourcesDefault[i].allocation,
            IID_PPV_ARGS(&resourcesDefault[i].resource)) );

        CHECK_HR( ctx.allocator->CreateResource(
            &allocDescReadback,
            &resourceDesc,
            D3D12_RESOURCE_STATE_COMMON,
            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 TestTightAlignment(const TestContext& ctx)
{
    using namespace D3D12MA;

    wprintf(L"Test resource tight alignment\n");

    const bool isTightAlignmentEnabled = ctx.allocator->IsTightAlignmentSupported() &&
        (ctx.allocatorFlags & ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT) == 0;

    // Use a custom pool to make sure our small buffers are not created as committed.
    POOL_DESC poolDesc = {};
    poolDesc.BlockSize = MEGABYTE;
    poolDesc.MinBlockCount = poolDesc.MaxBlockCount = 1;

    D3D12_RESOURCE_DESC resDesc;
    FillResourceDescForBuffer(resDesc, 4);

    const D3D12_HEAP_TYPE heapTypes[] = { D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD };
    for (auto heapType : heapTypes)
    {
        poolDesc.HeapProperties.Type = heapType;
        for (uint32_t poolFlagsIndex = 0; poolFlagsIndex < 2; ++poolFlagsIndex)
        {
            poolDesc.Flags = poolFlagsIndex == 0 ? POOL_FLAG_NONE : POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT;
            const bool isPoolTightAlignmentEnabled = isTightAlignmentEnabled && poolDesc.Flags == POOL_FLAG_NONE;
            for (uint32_t minAlignmentTestIndex = 0; minAlignmentTestIndex < 2; ++minAlignmentTestIndex)
            {
                // MinAllocationAlignment == 0 - default alignment.
                // MinAllocationAlignment == 1 - minimum possible alignment.
                poolDesc.MinAllocationAlignment = minAlignmentTestIndex;

                ComPtr<Pool> pool;
                CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

                ALLOCATION_DESC allocDesc = {};
                allocDesc.CustomPool = pool.Get();

                ComPtr<Allocation> allocs[2] = {};

                for (size_t i = 0; i < _countof(allocs); ++i)
                {
                    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc,
                        D3D12_RESOURCE_STATE_COMMON, NULL, &allocs[i], IID_NULL, NULL));
                    CHECK_BOOL(allocs[i] && allocs[i]->GetResource());
                }

                const UINT64 secondAllocOffset = allocs[1]->GetOffset();

                // Print the offset of the 2nd buffer.
                wprintf(L"    In D3D12_HEAP_TYPE_%s, with Flags=0x%X, MinAllocationAlignment=%llu, a %llu B buffer was aligned to %llu B.\n",
                    HEAP_TYPE_NAMES[(size_t)heapType],
                    poolDesc.Flags,
                    poolDesc.MinAllocationAlignment,
                    resDesc.Width,
                    secondAllocOffset);

                UINT64 expectedMinAlignment = 1;
                if (isPoolTightAlignmentEnabled)
                {
                    if (minAlignmentTestIndex == 0)
                        expectedMinAlignment = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;
                }
                else
                    expectedMinAlignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
                CHECK_BOOL(secondAllocOffset % expectedMinAlignment == 0);
            }
        }
    }
}

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();

            // Fix for D3D12 ERROR: ID3D12Device::CreatePlacedResource: D3D12_RESOURCE_DESC::Alignment is invalid. The value is 8. When D3D12_RESOURCE_DESC::Flag bit for D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT is set, Alignment must be 0. [ STATE_CREATION ERROR #721: CREATERESOURCE_INVALIDALIGNMENT]
            if ((desc.Flags & D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT_COPY) != 0)
                desc.Alignment = 0;

            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);
    TestMsaa64KBAlignedTextureSupported_DefaultPool(ctx);
    TestMsaa64KBAlignedTextureSupported_CustomPool(ctx);
    TestSmallTextureAlignmentAcrossDimensions(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);
    TestTightAlignment(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");
}
