////----------------------------------------------------------------------------------
// File:        CDX12_TrueHDR_VSR_Demo.h
// SDK Version: 1.0.2
//
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 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.
//
//----------------------------------------------------------------------------------

///////////////////////////////////////////
// CDX12_TrueHDR_VSR_Demo.h
//
// This is an example of a DX12 class using the RTX_Video_API functions for TrueHDR and VSR.
// StreamData is used for input setup and reading from the uncompressed file
//

#pragma once

#include <d3d12.h>
#include "TrueHDR_VSR_Demo.h"
#include "CDx12Api.h"
#include "CDx12Sync.h"
#include "CDx12SwapChain.h"

struct CStreamData12
{
    BOOL                    Enable;

    ID3D12Resource*         pTexture;
    ID3D12Resource*         pBuffer;

    CDx12SyncObject*        pSyncObject;

    UINT64                  nBufferSize;
    UINT64                  nLumaBufferSize;
    UINT64                  nChromaBufferSize;
    bool                    bSplitChroma;

    BOOL                    FileBased;

    class CVideoFile*       pVideoFile;
    int                     FramesRead;
    char                    FileName[MAX_PATH];
    int                     Width;
    int                     Height;
    int                     Pitch;
    int                     MaxFrameCount;
    int                     CurFrameCount;

    DXGI_FORMAT             StreamFormat;
    D3D12_RESOURCE_STATES   StreamState;
};



class CDX12_TrueHDR_VSR_Demo
{
public:
    CDX12_TrueHDR_VSR_Demo();
    ~CDX12_TrueHDR_VSR_Demo();

    HRESULT Init(HWND hWndDisplay, HWND hWndDisplayAlt, Configuration_s* pConfiguration);
    HRESULT NextFrame(bool bBackward = false);
    void    Shutdown();

protected:
    class CDx12Api*                                 m_pCDx12Api = nullptr;
    Configuration_s                                 m_Configuration = {};
    CDx1xCommon                                     m_CDx1xCommon = {};

    UINT                                            m_StreamCount = 1;
    UINT                                            m_uCurFrameCount = 0;

    ID3D12Resource*                                 m_pDstTexture = nullptr;
    CDx12SyncObject*                                m_pDstSyncObj = nullptr;
    D3D12_RESOURCE_STATES                           m_DstState = {};

    UINT                                            m_DstWidth = 0;
    UINT                                            m_DstHeight = 0;
    DXGI_FORMAT                                     m_DstFormat = {};
    DXGI_COLOR_SPACE_TYPE                           m_DstColorSpace = {};

    UINT                                            m_OutWidth = 0;
    UINT                                            m_OutHeight = 0;
    DXGI_FORMAT                                     m_OutFormat = {};
    DXGI_COLOR_SPACE_TYPE                           m_OutColorSpace = {};

    FLOAT                                           m_BackgroundColor[4] = {};

    ID3D12CommandAllocator*                         m_commandAllocator = nullptr;
    ID3D12CommandQueue*                             m_commandQueue = nullptr;
    ID3D12GraphicsCommandList*                      m_commandList = nullptr;
    CDx12SyncObject*                                m_AllocatorSyncObj = nullptr;
    CDx12SwapChain*                                 m_pDx12SwapChain = nullptr;
    CDx12SwapChain*                                 m_pDx12SwapChainAlt = nullptr;
    ID3D12VideoProcessor*                           m_pD3D12VideoProcessor = nullptr;
    ID3D12VideoProcessor*                           m_pD3D12VideoProcessorSwapBuffer = nullptr;

    RECT                                            m_NGXSrcRect = {};
    RECT                                            m_NGXDstRect = {};

    ID3D12Resource*                                 m_pNGXInputBuffer = nullptr;

    D3D12_VIDEO_PROCESS_OUTPUT_STREAM_ARGUMENTS     m_VPOutputStream = {};
    D3D12_VIDEO_PROCESS_INPUT_STREAM_ARGUMENTS1     m_VPInputStream = {};
    CStreamData12                                   m_StreamData = {};


    HRESULT SetupStreamData(D3D12_VIDEO_PROCESS_INPUT_STREAM_DESC* pVPInputStreamDesc, char* szFile);

    void CopyBufferToSurface(CStreamData12 *pStreamData);

    HRESULT FillFrameFromFile(CStreamData12 *pStreamData, D3D12_VIDEO_PROCESS_INPUT_STREAM_ARGUMENTS1* pVPInputStream, bool bBackward);
};