text: /*
  * Copyright (c) 2020, Intel Corporation
  *
  * 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.
  */
  //!
  //! \file     mhw_vdbox_vdenc_cmdpar.h
  //! \brief    MHW command parameters
  //! \details
  //!
  
  #ifndef __MHW_VDBOX_VDENC_CMDPAR_H__
  #define __MHW_VDBOX_VDENC_CMDPAR_H__
  
  #include "mhw_vdbox_cmdpar.h"
  #include "codec_def_common.h"
  #include "codec_def_common_encode.h"
  
  namespace mhw
  {
  namespace vdbox
  {
  namespace vdenc
  {
  static constexpr uint32_t MAX_REF_LIST_NUM = 2;
  static constexpr uint32_t MAX_REF_NUM_L0   = 3;
  static constexpr uint32_t MAX_REF_NUM_L1   = 3;  //  low delay B may have 3 L1 refs
  static constexpr uint32_t MAX_REF_NUM      = MAX_REF_NUM_L0 > MAX_REF_NUM_L1 ? MAX_REF_NUM_L0 : MAX_REF_NUM_L1;
  static constexpr uint32_t MAX_REF_NUM_L0L1 = MAX_REF_NUM_L0 + MAX_REF_NUM_L0;
  
  static constexpr uint32_t VDENC_ROWSTORE_BASEADDRESS      = 2370;
  static constexpr uint32_t VDENC_IPDL_ROWSTORE_BASEADDRESS = 384;
  
  enum class SurfaceFormat
  {
      yuv422          = 0x0,
      rgba4444        = 0x1,
      yuv444          = 0x2,
      p010Variant     = 0x3,
      planar4208      = 0x4,
      yCrCbSwapY422   = 0x5,
      yCrCbSwapUv422  = 0x6,
      yCrCbSwapUvy422 = 0x7,
      y216            = 0x8,
      y210            = 0x8,
      r10g10b10a2     = 0x9,
      y410            = 0xa,
      nv21            = 0xb,
      y416            = 0xc,
      p010            = 0xd,
      planarP016      = 0xe,
      y8Unorm         = 0xf,
      y16             = 0x10,
      y216Variant     = 0x11,
      y416Variant     = 0x12,
      yuyvVariant     = 0x13,
      ayuvVariant     = 0x14,
  };
  
  struct _MHW_CMD_PAR_T(VDENC_CONTROL_STATE)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_CONTROL_STATE)() = default;
  
      bool vdencInitialization = true;
  };
  
  struct _MHW_CMD_PAR_T(VDENC_PIPE_MODE_SELECT)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_PIPE_MODE_SELECT)() = default;
  
      uint8_t standardSelect           = 0;
      bool    scalabilityMode          = false;
      bool    frameStatisticsStreamOut = false;
      bool    pakObjCmdStreamOut       = false;
      bool    tlbPrefetch              = false;
      bool    dynamicSlice             = false;
      bool    streamIn                 = false;
      uint8_t bitDepthMinus8           = 0;
      uint8_t chromaType               = 0;
      uint8_t outputRangeControlCsc    = 1;
      bool    tileBasedReplayMode      = false;
      bool    randomAccess             = false;
      bool    rgbEncodingMode          = false;
      bool    hmeRegionPrefetch        = true;
      uint8_t topPrefetchEnableMode    = 0;
      uint8_t leftPrefetchAtWrapAround = 1;
      uint8_t verticalShift32Minus1    = 2;
      uint8_t hzShift32Minus1          = 3;
      uint8_t numVerticalReqMinus1     = 6;
      uint8_t numHzReqMinus1           = 2;
      uint8_t prefetchOffset           = 0;
      uint8_t captureMode              = 0;
      uint8_t wirelessSessionId        = 0;
      uint8_t tailPointerReadFrequency = 0;
      uint8_t streamingBufferConfig    = 0;
  };
  
  struct _MHW_CMD_PAR_T(VDENC_SRC_SURFACE_STATE)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_SRC_SURFACE_STATE)() = default;
  
      uint32_t     alignedWidth         = 0;
      uint32_t     alignedHeight        = 0;
      bool         colorSpaceSelection  = false;
      bool         displayFormatSwizzle = false;
      uint8_t      vDirection           = 0;
      PMOS_SURFACE surface              = nullptr;
  };
  
  struct _MHW_CMD_PAR_T(VDENC_REF_SURFACE_STATE)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_REF_SURFACE_STATE)() = default;
  
      uint32_t     alignedWidth    = 0;
      uint32_t     alignedHeight   = 0;
      uint32_t     reconSurfHeight = 0;
      uint8_t      vDirection      = 0;
      PMOS_SURFACE surface         = nullptr;
  };
  
  struct _MHW_CMD_PAR_T(VDENC_DS_REF_SURFACE_STATE)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_DS_REF_SURFACE_STATE)() = default;
  
      PMOS_SURFACE surfaceStage1       = nullptr;
      PMOS_SURFACE surfaceStage2       = nullptr;
      uint8_t      vDirectionStage1    = 0;
      uint8_t      vDirectionStage2    = 0;
      uint32_t     alignedWidthStage1  = 0;
      uint32_t     alignedWidthStage2  = 0;
      uint32_t     alignedHeightStage1 = 0;
      uint32_t     alignedHeightStage2 = 0;
  };
  
  struct _MHW_CMD_PAR_T(VDENC_PIPE_BUF_ADDR_STATE)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_PIPE_BUF_ADDR_STATE)() = default;
  
      PMOS_SURFACE      surfaceRaw                        = nullptr;
      MOS_MEMCOMP_STATE mmcStateRaw                       = MOS_MEMCOMP_DISABLED;
      uint32_t          compressionFormatRaw              = 0;
      uint32_t          compressionFormatRecon            = 0;
      PMOS_RESOURCE     intraRowStoreScratchBuffer        = nullptr;
      PMOS_RESOURCE     streamOutBuffer                   = nullptr;
      uint32_t          streamOutOffset                   = 0;
      PMOS_RESOURCE     streamInBuffer                    = nullptr;
      uint32_t          numActiveRefL0                    = 0;
      uint32_t          numActiveRefL1                    = 0;
      PMOS_RESOURCE     refs[MAX_REF_NUM_L0L1]            = {};
      PMOS_RESOURCE     refsDsStage1[MAX_REF_NUM_L0L1]    = {};
      PMOS_RESOURCE     refsDsStage2[MAX_REF_NUM_L0L1]    = {};
      MOS_MEMCOMP_STATE mmcStatePreDeblock                = MOS_MEMCOMP_DISABLED;
      MOS_MEMCOMP_STATE mmcStatePostDeblock               = MOS_MEMCOMP_DISABLED;
      PMOS_SURFACE      surfaceDsStage1                   = nullptr;
      MOS_MEMCOMP_STATE mmcStateDsStage1                  = MOS_MEMCOMP_DISABLED;
      PMOS_SURFACE      surfaceDsStage2                   = nullptr;
      MOS_MEMCOMP_STATE mmcStateDsStage2                  = MOS_MEMCOMP_DISABLED;
      bool              lowDelayB                         = false;
      PMOS_RESOURCE     colocatedMvReadBuffer             = nullptr;
      PMOS_RESOURCE     colMvTempBuffer[MAX_REF_NUM_L0L1] = {};
      PMOS_RESOURCE     pakObjCmdStreamOutBuffer          = nullptr;
      PMOS_RESOURCE     segmentMapStreamInBuffer          = nullptr;
      PMOS_RESOURCE     segmentMapStreamOutBuffer         = nullptr;
      PMOS_RESOURCE     tileRowStoreBuffer                = nullptr;
      PMOS_RESOURCE     mfdIntraRowStoreScratchBuffer     = nullptr;
      PMOS_RESOURCE     cumulativeCuCountStreamOutBuffer  = nullptr;
      PMOS_RESOURCE     colocatedMvWriteBuffer            = nullptr;
  };
  
  struct _MHW_CMD_PAR_T(VDENC_WEIGHTSOFFSETS_STATE)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_WEIGHTSOFFSETS_STATE)() = default;
  
      int8_t   weightsLuma[MAX_REF_LIST_NUM][MAX_REF_NUM]      = {};
      int16_t  offsetsLuma[MAX_REF_LIST_NUM][MAX_REF_NUM]      = {};
      uint32_t denomLuma                                       = 0;
      int8_t   weightsChroma[MAX_REF_LIST_NUM][MAX_REF_NUM][2] = {};
      int16_t  offsetsChroma[MAX_REF_LIST_NUM][MAX_REF_NUM][2] = {};
      uint32_t denomChroma                                     = 0;
  };
  
  struct _MHW_CMD_PAR_T(VDENC_HEVC_VP9_TILE_SLICE_STATE)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_HEVC_VP9_TILE_SLICE_STATE)() = default;
  
      bool     tileEnable             = false;
      bool     tileRowStoreSelect     = false;
      uint32_t tileWidth              = 0;
      uint32_t tileHeight             = 0;
      uint32_t numPipe                = 0;
      uint32_t tileId                 = 0;
      uint32_t tileStartLCUX          = 0;
      uint32_t tileStartLCUY          = 0;
      uint32_t ctbSize                = 0;
      uint32_t tileStreamInOffset     = 0;
      uint32_t tileLCUStreamOutOffset = 0;
      uint32_t cumulativeCUTileOffset = 0;
  };
  
  struct _MHW_CMD_PAR_T(VDENC_WALKER_STATE)
  {
      virtual ~_MHW_CMD_PAR_T(VDENC_WALKER_STATE)() = default;
  
      bool     firstSuperSlice          = true;
      uint32_t tileSliceStartLcuMbX     = 0;
      uint32_t tileSliceStartLcuMbY     = 0;
      uint32_t nextTileSliceStartLcuMbX = 0;
      uint32_t nextTileSliceStartLcuMbY = 0;
  };
  
  struct _MHW_CMD_PAR_T(VD_PIPELINE_FLUSH)
  {
      virtual ~_MHW_CMD_PAR_T(VD_PIPELINE_FLUSH)() = default;
  
      bool waitDoneHEVC           = false;
      bool waitDoneVDENC          = false;
      bool waitDoneMFL            = false;
      bool waitDoneMFX            = false;
      bool waitDoneVDCmdMsgParser = false;
      bool flushHEVC              = false;
      bool flushVDENC             = false;
      bool flushMFL               = false;
      bool flushMFX               = false;
  };
  
  class CmdPar
  {
  public:
      virtual ~CmdPar() = default;
  
      _MHW_CMD_PAR_SET_DEF(VDENC_CONTROL_STATE);
      _MHW_CMD_PAR_SET_DEF(VDENC_PIPE_MODE_SELECT);
      _MHW_CMD_PAR_SET_DEF(VDENC_SRC_SURFACE_STATE);
      _MHW_CMD_PAR_SET_DEF(VDENC_REF_SURFACE_STATE);
      _MHW_CMD_PAR_SET_DEF(VDENC_DS_REF_SURFACE_STATE);
      _MHW_CMD_PAR_SET_DEF(VDENC_PIPE_BUF_ADDR_STATE);
      _MHW_CMD_PAR_SET_DEF(VDENC_WEIGHTSOFFSETS_STATE);
      _MHW_CMD_PAR_SET_DEF(VDENC_HEVC_VP9_TILE_SLICE_STATE);
      _MHW_CMD_PAR_SET_DEF(VDENC_WALKER_STATE);
      _MHW_CMD_PAR_SET_DEF(VD_PIPELINE_FLUSH);
  };
  }  // namespace vdenc
  }  // namespace vdbox
  }  // namespace mhw
  
  #ifndef MHW_VDBOX_VDENC_CMDPAR_T
  #define MHW_VDBOX_VDENC_CMDPAR_T mhw::vdbox::vdenc::CmdPar
  #endif
  
  #ifndef MHW_VDBOX_VDENC_CMD_PAR_T
  #define MHW_VDBOX_VDENC_CMD_PAR_T(cmd) mhw::vdbox::vdenc::_MHW_CMD_PAR_T(cmd)
  #endif
  
  #define MHW_VDBOX_VDENC_TO_ACTUAL_CMD_PAR(cmd)                                  \
      MHW_FUNCTION_ENTER;                                                         \
      auto params = mhw::DynamicPointerCast<MHW_VDBOX_VDENC_CMD_PAR_T(cmd)>(par); \
      MHW_CHK_NULL_RETURN(params)
  
  #endif  // __MHW_VDBOX_VDENC_CMDPAR_H__
  