/*
 * Copyright 2025 Rive
 */
#include "rive/renderer/d3d12/d3d12_utils.hpp"

namespace rive::gpu
{
void print_sig_descriptor(LPCVOID data, SIZE_T size)
{
    ComPtr<ID3D12RootSignatureDeserializer> descS;
    D3D12CreateRootSignatureDeserializer(data, size, IID_PPV_ARGS(&descS));
    auto desc = descS->GetRootSignatureDesc();
    printf("desc {\n");
    for (size_t i = 0; i < desc->NumParameters; ++i)
    {
        const char* type;
        switch (desc->pParameters[i].ParameterType)
        {
            case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
                type = "table";
                break;
            case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
                type = "constant";
                break;
            case D3D12_ROOT_PARAMETER_TYPE_CBV:
                type = "cbv";
                break;
            case D3D12_ROOT_PARAMETER_TYPE_SRV:
                type = "srv";
                break;
            case D3D12_ROOT_PARAMETER_TYPE_UAV:
                type = "uav";
                break;
            default:
                type = "unkown";
        }

        printf("root desc name %s\n", type);
    }
    printf("}\n");
}
#if defined(DEBUG)
void SetName(D3D12Resource* pObject, LPCWSTR name) { pObject->SetName(name); }
#else
void printDescriptor(LPCVOID data, SIZE_T size) {}
void SetName(ID3D12Object*, LPCWSTR) {}
#endif

D3D12DescriptorHeap::D3D12DescriptorHeap(rcp<GPUResourceManager> manager,
                                         ID3D12Device* device,
                                         UINT numDescriptors,
                                         D3D12_DESCRIPTOR_HEAP_TYPE type,
                                         D3D12_DESCRIPTOR_HEAP_FLAGS flags) :
    GPUResource(std::move(manager)),
#ifndef NDEBUG
    m_type(type),
    m_flags(flags),
#endif
    m_heapDescriptorSize(device->GetDescriptorHandleIncrementSize(type))
{
    D3D12_DESCRIPTOR_HEAP_DESC desc = {};
    desc.Type = type;
    desc.NumDescriptors = numDescriptors;
    desc.Flags = flags;

    VERIFY_OK(device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_heap)));
}

void D3D12DescriptorHeap::markSamplerToIndex(ID3D12Device* device,
                                             const D3D12_SAMPLER_DESC& desc,
                                             UINT index)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);

    CD3DX12_CPU_DESCRIPTOR_HANDLE samplerHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);

    device->CreateSampler(&desc, samplerHandle);
}

void D3D12DescriptorHeap::markCbvToIndex(ID3D12Device* device,
                                         D3D12Buffer* resource,
                                         UINT index,
                                         UINT sizeInBytes,
                                         SIZE_T offset)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

    D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
    cbvDesc.SizeInBytes = sizeInBytes;
    cbvDesc.BufferLocation =
        resource->resource()->GetGPUVirtualAddress() + offset;

    CD3DX12_CPU_DESCRIPTOR_HANDLE cbvHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);

    device->CreateConstantBufferView(&cbvDesc, cbvHandle);
}

void D3D12DescriptorHeap::markSrvToIndex(ID3D12Device* device,
                                         D3D12Buffer* resource,
                                         UINT index,
                                         UINT numElements,
                                         UINT elementByteStride,
                                         UINT64 firstElement)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};

    srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
    srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
    srvDesc.Buffer.FirstElement = firstElement;
    srvDesc.Buffer.NumElements = numElements;
    srvDesc.Buffer.StructureByteStride = elementByteStride;
    srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
    srvDesc.Format = resource->desc().Format;

    CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);

    device->CreateShaderResourceView(resource->resource(), &srvDesc, srvHandle);
}

void D3D12DescriptorHeap::markSrvToIndex(ID3D12Device* device,
                                         D3D12Buffer* resource,
                                         UINT index,
                                         UINT numElements,
                                         UINT elementByteStride,
                                         UINT gpuByteStride,
                                         UINT64 firstElement)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
    assert(elementByteStride % gpuByteStride == 0);

    const UINT cpuScale = elementByteStride / gpuByteStride;

    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};

    srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
    srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
    srvDesc.Buffer.FirstElement = firstElement * cpuScale;
    srvDesc.Buffer.NumElements = numElements * cpuScale;
    srvDesc.Buffer.StructureByteStride = gpuByteStride;
    srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
    srvDesc.Format = resource->desc().Format;

    CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);

    device->CreateShaderResourceView(resource->resource(), &srvDesc, srvHandle);
}

void D3D12DescriptorHeap::markUavToIndex(ID3D12Device* device,
                                         D3D12Buffer* resource,
                                         DXGI_FORMAT format,
                                         UINT index,
                                         UINT numElements,
                                         UINT elementByteStride)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

    D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};

    uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
    uavDesc.Buffer.CounterOffsetInBytes = 0;
    uavDesc.Buffer.FirstElement = 0;
    uavDesc.Buffer.NumElements = numElements;
    uavDesc.Buffer.StructureByteStride = elementByteStride;
    uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
    uavDesc.Format = format;

    CD3DX12_CPU_DESCRIPTOR_HANDLE uavHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);

    device->CreateUnorderedAccessView(resource->resource(),
                                      nullptr,
                                      &uavDesc,
                                      uavHandle);
}

void D3D12DescriptorHeap::markSrvToIndex(ID3D12Device* device,
                                         D3D12Texture* resource,
                                         UINT index)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};

    srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
    srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
    srvDesc.Texture2D.MipLevels = resource->desc().MipLevels;
    srvDesc.Texture2D.PlaneSlice = 0;
    srvDesc.Format = resource->desc().Format;

    CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);

    device->CreateShaderResourceView(resource->resource(), &srvDesc, srvHandle);
}

void D3D12DescriptorHeap::markSrvToIndex(ID3D12Device* device,
                                         D3D12TextureArray* resource,
                                         UINT index)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};

    srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
    srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1DARRAY;
    srvDesc.Texture1DArray.MipLevels = resource->desc().MipLevels;
    srvDesc.Texture1DArray.ArraySize = resource->length();
    srvDesc.Texture1DArray.FirstArraySlice = 0;
    srvDesc.Format = resource->desc().Format;

    CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);

    device->CreateShaderResourceView(resource->resource(), &srvDesc, srvHandle);
}

void D3D12DescriptorHeap::markUavToIndex(ID3D12Device* device,
                                         D3D12Texture* resource,
                                         DXGI_FORMAT format,
                                         UINT index)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

    D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};

    uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
    uavDesc.Texture2D.MipSlice = 0;
    uavDesc.Texture2D.PlaneSlice = 0;
    uavDesc.Format = format;

    CD3DX12_CPU_DESCRIPTOR_HANDLE uavHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);

    device->CreateUnorderedAccessView(resource->resource(),
                                      nullptr,
                                      &uavDesc,
                                      uavHandle);
}

void D3D12DescriptorHeap::markRtvToIndex(ID3D12Device* device,
                                         D3D12Texture* resource,
                                         UINT index)
{
    assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

    D3D12_RENDER_TARGET_VIEW_DESC RTVDesc = {};
    RTVDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
    RTVDesc.Format = resource->desc().Format;
    if (DXGI_FORMAT_R8G8B8A8_TYPELESS == RTVDesc.Format)
    {
        RTVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    }
    RTVDesc.Texture2D.MipSlice = 0;

    CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(
        m_heap->GetCPUDescriptorHandleForHeapStart(),
        index,
        m_heapDescriptorSize);
    device->CreateRenderTargetView(resource->resource(), &RTVDesc, rtvHandle);
}

D3D12Resource::D3D12Resource(rcp<GPUResourceManager> manager,
                             ComPtr<ID3D12Resource> resource,
                             D3D12_RESOURCE_STATES initialState) :
    GPUResource(std::move(manager)),
    m_resource(resource),
    m_lastState(initialState),
    m_desc(m_resource->GetDesc()),
    m_heapPropeties(D3D12_HEAP_TYPE_DEFAULT),
    m_heapFlags(D3D12_HEAP_FLAG_NONE)
{}

D3D12Resource::D3D12Resource(rcp<GPUResourceManager> manager,
                             ID3D12Device* device,
                             D3D12_RESOURCE_STATES initialState,
                             D3D12_HEAP_FLAGS heapFlags,
                             const D3D12_RESOURCE_DESC& resourceDesc,
                             const D3D12_CLEAR_VALUE* clearValue) :
    GPUResource(std::move(manager)),
    m_lastState(initialState),
    m_desc(std::move(resourceDesc)),
    m_heapFlags(heapFlags)
{
    m_heapPropeties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
    VERIFY_OK(device->CreateCommittedResource(&m_heapPropeties,
                                              heapFlags,
                                              &m_desc,
                                              m_lastState,
                                              clearValue,
                                              IID_PPV_ARGS(&m_resource)));
}

D3D12Resource::D3D12Resource(rcp<GPUResourceManager> manager,
                             ID3D12Device* device,
                             D3D12_RESOURCE_STATES initialState,
                             D3D12_HEAP_FLAGS heapFlags,
                             CD3DX12_HEAP_PROPERTIES heapPropeties,
                             const D3D12_RESOURCE_DESC& desc,
                             const D3D12_CLEAR_VALUE* clearValue) :
    GPUResource(std::move(manager)),
    m_lastState(initialState),
    m_desc(std::move(desc)),
    m_heapPropeties(heapPropeties),
    m_heapFlags(heapFlags)
{
    VERIFY_OK(device->CreateCommittedResource(&m_heapPropeties,
                                              heapFlags,
                                              &m_desc,
                                              m_lastState,
                                              clearValue,
                                              IID_PPV_ARGS(&m_resource)));
}

void* D3D12Buffer::map()
{
    assert(m_sizeInBytes);
    assert(!m_isMapped);
    assert(m_heapPropeties.IsCPUAccessible());
    void* data = nullptr;
    VERIFY_OK(m_resource->Map(0, nullptr, &data));
#ifndef NDEBUG
    m_isMapped = true;
#endif
    return data;
}

void D3D12Buffer::unmap()
{
    assert(m_isMapped);
    assert(m_heapPropeties.IsCPUAccessible());
    m_resource->Unmap(0, nullptr);
#ifndef NDEBUG
    m_isMapped = false;
#endif
}

D3D12VolatileBuffer::D3D12VolatileBuffer(rcp<D3D12ResourceManager> manager,
                                         UINT initialSize,
                                         D3D12_RESOURCE_FLAGS bindFlags,
                                         D3D12_HEAP_FLAGS heapFlags) :
    GPUResource(std::move(manager)),
    m_bindFlags(bindFlags),
    m_heapFlags(heapFlags)
{
    assert(initialSize > 0);
    resizeBuffers(initialSize);
}

D3D12ResourceManager* D3D12VolatileBuffer::d3d() const
{
    return static_cast<D3D12ResourceManager*>(m_manager.get());
}

void D3D12VolatileBuffer::sync(ID3D12GraphicsCommandList* cmdList,
                               UINT64 offsetBytes)
{
    assert(m_uploadBuffer->sizeInBytes() == m_gpuBuffer->sizeInBytes());
    sync(cmdList, offsetBytes, m_uploadBuffer->sizeInBytes());
}

void D3D12VolatileBuffer::sync(ID3D12GraphicsCommandList* cmdList,
                               UINT64 offsetBytes,
                               UINT64 bytesToSync)
{
    assert(bytesToSync);
    d3d()->transition(cmdList,
                      m_gpuBuffer.get(),
                      D3D12_RESOURCE_STATE_COPY_DEST);

    cmdList->CopyBufferRegion(m_gpuBuffer->resource(),
                              0,
                              m_uploadBuffer->resource(),
                              offsetBytes,
                              bytesToSync);
    d3d()->transition(cmdList, m_gpuBuffer.get(), D3D12_RESOURCE_STATE_COMMON);
}

void D3D12VolatileBuffer::syncToBuffer(ID3D12GraphicsCommandList* cmdList,
                                       D3D12Buffer* buffer,
                                       UINT64 offsetBytes,
                                       UINT64 bytesToSync) const
{
    assert(buffer->sizeInBytes() >= bytesToSync);

    cmdList->CopyBufferRegion(buffer->resource(),
                              0,
                              m_uploadBuffer->resource(),
                              offsetBytes,
                              bytesToSync);
}

void D3D12VolatileBuffer::resizeBuffers(UINT newSize)
{
    m_uploadBuffer = d3d()->makeUploadBuffer(newSize,
                                             D3D12_RESOURCE_FLAG_NONE,
                                             D3D12_RESOURCE_STATE_COPY_SOURCE);
    m_gpuBuffer = d3d()->makeBuffer(newSize,
                                    m_bindFlags,
                                    D3D12_RESOURCE_STATE_COMMON,
                                    m_heapFlags);
}

rcp<D3D12Buffer> D3D12ResourceManager::makeBuffer(
    UINT size,
    D3D12_RESOURCE_FLAGS bindFlags,
    D3D12_RESOURCE_STATES initialState,
    D3D12_HEAP_FLAGS heapFlags)
{
    auto desc = CD3DX12_RESOURCE_DESC::Buffer(size);
    return make_rcp<D3D12Buffer>(ref_rcp(this),
                                 m_device.Get(),
                                 initialState,
                                 heapFlags,
                                 size,
                                 desc);
}

rcp<D3D12Buffer> D3D12ResourceManager::makeUploadBuffer(
    UINT size,
    D3D12_RESOURCE_FLAGS bindFlags,
    D3D12_RESOURCE_STATES initialState,
    D3D12_HEAP_FLAGS heapFlags)
{
    auto desc = CD3DX12_RESOURCE_DESC::Buffer(size);

    return make_rcp<D3D12Buffer>(
        ref_rcp(this),
        m_device.Get(),
        initialState,
        heapFlags,
        CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
        size,
        desc);
}

rcp<D3D12VolatileBuffer> D3D12ResourceManager::makeVolatileBuffer(
    UINT size,
    D3D12_RESOURCE_FLAGS bindFlags,
    D3D12_HEAP_FLAGS heapFlags)
{
    return make_rcp<D3D12VolatileBuffer>(ref_rcp(this),
                                         size,
                                         bindFlags,
                                         heapFlags);
}

rcp<D3D12DescriptorHeap> D3D12ResourceManager::makeHeap(
    UINT numDescriptors,
    D3D12_DESCRIPTOR_HEAP_TYPE type,
    D3D12_DESCRIPTOR_HEAP_FLAGS flags)
{
    return make_rcp<D3D12DescriptorHeap>(ref_rcp(this),
                                         m_device.Get(),
                                         numDescriptors,
                                         type,
                                         flags);
}

rcp<D3D12TextureArray> D3D12ResourceManager::make1DTextureArray(
    UINT width,
    UINT16 length,
    UINT mipLevelCount,
    DXGI_FORMAT format,
    D3D12_RESOURCE_FLAGS bindFlags,
    D3D12_RESOURCE_STATES initialState,
    D3D12_HEAP_FLAGS heapFlags)
{
    D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex1D(format,
                                                            width,
                                                            length,
                                                            mipLevelCount,
                                                            bindFlags);
    return make_rcp<D3D12TextureArray>(ref_rcp(this),
                                       m_device.Get(),
                                       initialState,
                                       heapFlags,
                                       desc);
}

rcp<D3D12Texture> D3D12ResourceManager::make2DTexture(
    UINT width,
    UINT height,
    UINT mipLevelCount,
    DXGI_FORMAT format,
    D3D12_RESOURCE_FLAGS bindFlags,
    D3D12_RESOURCE_STATES initialState,
    D3D12_HEAP_FLAGS heapFlags,
    const D3D12_CLEAR_VALUE* clearValue)
{
    D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex2D(format,
                                                            width,
                                                            height,
                                                            1,
                                                            mipLevelCount,
                                                            1,
                                                            0,
                                                            bindFlags);

    return make_rcp<D3D12Texture>(ref_rcp(this),
                                  m_device.Get(),
                                  initialState,
                                  heapFlags,
                                  desc,
                                  clearValue);
}

rcp<D3D12Texture> D3D12ResourceManager::makeExternalTexture(
    ComPtr<ID3D12Resource> externalTexture,
    D3D12_RESOURCE_STATES lastState)
{
    return make_rcp<D3D12Texture>(ref_rcp(this), externalTexture, lastState);
}

void D3D12ResourceManager::transition(ID3D12GraphicsCommandList* cmdList,
                                      D3D12Resource* resource,
                                      D3D12_RESOURCE_STATES toState)
{
    assert(resource->m_lastState != toState);

    auto barrier = CD3DX12_RESOURCE_BARRIER::Transition(resource->resource(),
                                                        resource->m_lastState,
                                                        toState);
    cmdList->ResourceBarrier(1, &barrier);
    resource->m_lastState = toState;
}

void D3D12ResourceManager::clearUAV(ID3D12GraphicsCommandList* cmdList,
                                    ID3D12Resource* resource,
                                    CD3DX12_GPU_DESCRIPTOR_HANDLE& gpuHandle,
                                    CD3DX12_CPU_DESCRIPTOR_HANDLE& cpuHandle,
                                    const UINT clearColor[4],
                                    bool needsBarrier)
{
    if (needsBarrier)
    {
        D3D12_RESOURCE_BARRIER barriers[] = {
            CD3DX12_RESOURCE_BARRIER::UAV(resource)};

        cmdList->ResourceBarrier(1, barriers);
    }

    cmdList->ClearUnorderedAccessViewUint(gpuHandle,
                                          cpuHandle,
                                          resource,
                                          clearColor,
                                          0,
                                          nullptr);

    if (needsBarrier)
    {
        D3D12_RESOURCE_BARRIER barriers[] = {
            CD3DX12_RESOURCE_BARRIER::UAV(resource)};

        cmdList->ResourceBarrier(1, barriers);
    }
}

void D3D12ResourceManager::clearUAV(ID3D12GraphicsCommandList* cmdList,
                                    ID3D12Resource* resource,
                                    CD3DX12_GPU_DESCRIPTOR_HANDLE& gpuHandle,
                                    CD3DX12_CPU_DESCRIPTOR_HANDLE& cpuHandle,
                                    const float clearColor[4],
                                    bool needsBarrier)
{
    if (needsBarrier)
    {
        D3D12_RESOURCE_BARRIER barriers[] = {
            CD3DX12_RESOURCE_BARRIER::UAV(resource)};

        cmdList->ResourceBarrier(1, barriers);
    }

    cmdList->ClearUnorderedAccessViewFloat(gpuHandle,
                                           cpuHandle,
                                           resource,
                                           clearColor,
                                           0,
                                           nullptr);

    if (needsBarrier)
    {
        D3D12_RESOURCE_BARRIER barriers[] = {
            CD3DX12_RESOURCE_BARRIER::UAV(resource)};

        cmdList->ResourceBarrier(1, barriers);
    }
}

D3D12VolatileBufferPool::D3D12VolatileBufferPool(
    rcp<D3D12ResourceManager> manager,
    UINT alignment,
    UINT size) :
    GPUResourcePool(std::move(manager), MAX_POOL_SIZE),
    m_targetSize(std::max<UINT>(size, m_alignment)),
    m_alignment(alignment)
{}

inline D3D12ResourceManager* D3D12VolatileBufferPool::d3d() const
{
    return static_cast<D3D12ResourceManager*>(m_manager.get());
}

void D3D12VolatileBufferPool::setTargetSize(size_t size)
{
    m_targetSize = std::max<UINT>(static_cast<UINT>(size), m_alignment);
    assert(m_targetSize % m_alignment == 0);
}

rcp<D3D12VolatileBuffer> D3D12VolatileBufferPool::acquire()
{
    auto buffer =
        static_rcp_cast<D3D12VolatileBuffer>(GPUResourcePool::acquire());
    if (buffer == nullptr)
    {
        buffer = d3d()->makeVolatileBuffer(m_targetSize);
    }
    else if (buffer->sizeInBytes() != m_targetSize)
    {
        buffer->resizeBuffers(m_targetSize);
    }
    return buffer;
}

D3D12DescriptorHeapPool::D3D12DescriptorHeapPool(
    rcp<D3D12ResourceManager> manager,
    UINT numDescriptors,
    D3D12_DESCRIPTOR_HEAP_TYPE type,
    D3D12_DESCRIPTOR_HEAP_FLAGS flags) :
    GPUResourcePool(std::move(manager), MAX_POOL_SIZE),
    m_numDescriptors(numDescriptors),
    m_type(type),
    m_flags(flags)
{}

rcp<D3D12DescriptorHeap> D3D12DescriptorHeapPool::acquire()
{
    auto heap =
        static_rcp_cast<D3D12DescriptorHeap>(GPUResourcePool::acquire());
    if (heap == nullptr)
    {
        heap = d3d()->makeHeap(m_numDescriptors, m_type, m_flags);
    }

    return heap;
}

inline D3D12ResourceManager* D3D12DescriptorHeapPool::d3d() const
{
    return static_cast<D3D12ResourceManager*>(m_manager.get());
}

}; // namespace rive::gpu