//----------------------------------------------------------------------------------
// File:        CDx12Api.h
// SDK Version: 1.0.2
//
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.
//
//----------------------------------------------------------------------------------

///////////////////////////////////////////
// CDx12Api.h
//
// Top level API into DX12 video devices
//

#pragma once

#include <d3d12.h>
#include <d3d12video.h>
#include "CDx1x_Common.h"

#define MAX_SWAP_BUFFERS        16

class CDx12SyncObject;
class CDx12SwapChain;


class CDx12Api
{
public:
    CDx12Api() {}

    HRESULT Init(CDx1xCommon* pCDx1xCommon, UINT gpuIndex, HWND hWndDisplay);
    void    ShutDown();

    HRESULT VpInit(UINT NumStreams, D3D12_VIDEO_PROCESS_INPUT_STREAM_DESC* pVPInputStreamDesc,
                     UINT WidthOut, UINT HeightOut, DXGI_FORMAT vpOutFormat, DXGI_COLOR_SPACE_TYPE OutputSpace,
                     FLOAT BackgroundColor[4],
                     ID3D12VideoProcessor** ppD3D12VideoProcessor = nullptr);

    HRESULT CreateVideoTexture(
        UINT64              Width,
        UINT                Height,
        DXGI_FORMAT         dxgiFormat,
        bool                bIsHwRT,
        bool                bIsCPUWrite,
        bool                bIsDecodeSurf,
        UINT64*             pBufferSize,
        ID3D12Resource**    ppTexture,
        UINT                creationNodeMask = 1,
        UINT                nodeMask = 1,
        bool                bIsShared = false,
        D3D12_RESOURCE_STATES* pInitState = nullptr);

    HRESULT VpBltHd(D3D12_VIDEO_PROCESS_OUTPUT_STREAM_ARGUMENTS* pOutputStream,
                    CDx12SyncObject* pDstSyncObj,
                    D3D12_VIDEO_PROCESS_INPUT_STREAM_ARGUMENTS1* pVPInputStreams,
                    UINT nInputStreamCount,
                    ID3D12VideoProcessor* pD3D12VideoProcessor = nullptr);

    ID3D12Device* GetD3D12Device()                  const { return m_pD3D12Device; }
    ID3D12CommandQueue* GetCommandQueue()           const { return m_pCommandQueue; }

    bool CheckWriteImmediateSupport(ID3D12Device* pD3D12Device);

protected:
    ID3D12Device*                                   m_pD3D12Device              = nullptr;
    ID3D12VideoDevice*                              m_pD3D12VideoDevice         = nullptr;
    ID3D12CommandQueue*                             m_pCommandQueue             = nullptr;
    ID3D12CommandAllocator*                         m_pCommandAllocator         = nullptr;
    ID3D12GraphicsCommandList*                      m_pCommandList              = nullptr;
    ID3D12CommandQueue*                             m_pVideoCommandQueue        = nullptr;
    ID3D12CommandAllocator*                         m_pVideoCommandAllocator    = nullptr;
    ID3D12VideoProcessCommandList*                  m_pVideoProcessCommandList  = nullptr;
    ID3D12VideoProcessCommandList1*                 m_pVideoProcessCommandList1 = nullptr;
    ID3D12VideoProcessor*                           m_pD3D12VideoProcessor      = nullptr;
    ID3D12Resource*                                 m_pPredication              = nullptr;
    ID3D12Resource*                                 m_pWriteImmediateBuffer     = nullptr;

    CDx12SyncObject*                                m_AllocatorSyncObj          = nullptr;

    UINT                                            m_nFrameCount = 0;

    UINT                                            m_gpuIndex = 0;
    UINT                                            m_gpuMask = 1;
};
