text: /*
  * Copyright (c) 2017, 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_hcp_g9_bxt.cpp
  //! \brief    Defines functions for constructing Vdbox HCP commands on G9 BXT platform
  //!
  
  #include "mhw_vdbox_hcp_g9_bxt.h"
  #include "mhw_mi_hwcmd_g9_X.h"
  #include "mhw_vdbox_vdenc_hwcmd_g9_bxt.h"
  
  void MhwVdboxHcpInterfaceG9Bxt::InitRowstoreUserFeatureSettings()
  {
      MhwVdboxHcpInterfaceG9::InitRowstoreUserFeatureSettings();
  
      if (m_rowstoreCachingSupported && m_decodeInUse)
      {
          MOS_USER_FEATURE_VALUE_DATA userFeatureData;
  
          PLATFORM  platform;
          m_osInterface->pfnGetPlatform(m_osInterface, &platform);
  
          if (platform.usRevId >= 3)
          {
              MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
  #if (_DEBUG || _RELEASE_INTERNAL)
              MOS_UserFeature_ReadValue_ID(
                  nullptr,
                  __MEDIA_USER_FEATURE_VALUE_VP9_HVDROWSTORECACHE_DISABLE_ID,
                  &userFeatureData);
  #endif // _DEBUG || _RELEASE_INTERNAL
              m_vp9HvdRowStoreCache.bSupported = userFeatureData.i32Data ? false : true;
  
              MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
  #if (_DEBUG || _RELEASE_INTERNAL)
              MOS_UserFeature_ReadValue_ID(
                  nullptr,
                  __MEDIA_USER_FEATURE_VALUE_VP9_DFROWSTORECACHE_DISABLE_ID,
                  &userFeatureData);
  #endif // _DEBUG || _RELEASE_INTERNAL
              m_vp9DfRowStoreCache.bSupported = userFeatureData.i32Data ? false : true;
          }
      }
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::GetHcpStateCommandSize(
      uint32_t                        mode,
      uint32_t                        *commandsSize,
      uint32_t                        *patchListSize,
      PMHW_VDBOX_STATE_CMDSIZE_PARAMS params)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_FUNCTION_ENTER;
  
      uint32_t            maxSize = 0;
      uint32_t            patchListMaxSize = 0;
      uint32_t            standard = CodecHal_GetStandardFromMode(mode);
  
      if (standard == CODECHAL_HEVC)
      {
          maxSize =
              mhw_vdbox_vdenc_g9_bxt::VD_PIPELINE_FLUSH_CMD::byteSize +
              mhw_mi_g9_X::MI_FLUSH_DW_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_PIPE_MODE_SELECT_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_SURFACE_STATE_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_PIPE_BUF_ADDR_STATE_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_IND_OBJ_BASE_ADDR_STATE_CMD::byteSize;
  
          patchListMaxSize =
              PATCH_LIST_COMMAND(VD_PIPELINE_FLUSH_CMD) +
              PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD) +
              PATCH_LIST_COMMAND(HCP_PIPE_MODE_SELECT_CMD) +
              PATCH_LIST_COMMAND(HCP_SURFACE_STATE_CMD) +
              PATCH_LIST_COMMAND(HCP_PIPE_BUF_ADDR_STATE_CMD) +
              PATCH_LIST_COMMAND(HCP_IND_OBJ_BASE_ADDR_STATE_CMD);
  
          if (mode == CODECHAL_ENCODE_MODE_HEVC)
          {
              /* HCP_QM_STATE_CMD may be issued up to 20 times: 3x Colour Component plus 2x intra/inter plus 4x SizeID minus 4 for the 32x32 chroma components.
              HCP_FQP_STATE_CMD may be issued up to 8 times: 4 scaling list per intra and inter. */
              maxSize +=
                  mhw_vdbox_hcp_g9_bxt::HCP_SURFACE_STATE_CMD::byteSize + // encoder needs two surface state commands. One is for raw and another one is for recon surfaces.
                  20 * mhw_vdbox_hcp_g9_bxt::HCP_QM_STATE_CMD::byteSize +
                  8 * mhw_vdbox_hcp_g9_bxt::HCP_FQM_STATE_CMD::byteSize +
                  mhw_vdbox_hcp_g9_bxt::HCP_PIC_STATE_CMD::byteSize +
                  2 * mhw_mi_g9_X::MI_STORE_DATA_IMM_CMD::byteSize + // Slice level commands
                  2 * mhw_mi_g9_X::MI_FLUSH_DW_CMD::byteSize + // need for Status report, Mfc Status and
                  10 * mhw_mi_g9_X::MI_STORE_REGISTER_MEM_CMD::byteSize + // 8 for BRCStatistics and 2 for RC6 WAs
                  mhw_mi_g9_X::MI_LOAD_REGISTER_MEM_CMD::byteSize + // 1 for RC6
                  2 * mhw_vdbox_hcp_g9_bxt::HCP_PAK_INSERT_OBJECT_CMD::byteSize; // Two PAK insert object commands are for headers before the slice header and the header for the end of stream
  
              patchListMaxSize +=
                  20 * PATCH_LIST_COMMAND(HCP_QM_STATE_CMD) +
                  8 * PATCH_LIST_COMMAND(HCP_FQM_STATE_CMD) +
                  PATCH_LIST_COMMAND(HCP_PIC_STATE_CMD) +
                  PATCH_LIST_COMMAND(MI_BATCH_BUFFER_START_CMD) +   // When BRC is on, HCP_PIC_STATE_CMD command is in the BB
                  2 * PATCH_LIST_COMMAND(MI_STORE_DATA_IMM_CMD) +   // Slice level commands
                  2 * PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD) +   // need for Status report, Mfc Status and
                  11 * PATCH_LIST_COMMAND(MI_STORE_REGISTER_MEM_CMD); // 8 for BRCStatistics and 3 for RC6 WAs
          }
          else
          {
              maxSize +=
                  20 * mhw_vdbox_hcp_g9_bxt::HCP_QM_STATE_CMD::byteSize +
                  mhw_vdbox_hcp_g9_bxt::HCP_PIC_STATE_CMD::byteSize +
                  mhw_vdbox_hcp_g9_bxt::HCP_TILE_STATE_CMD::byteSize;
  
              patchListMaxSize +=
                  20 * PATCH_LIST_COMMAND(HCP_QM_STATE_CMD) +
                  PATCH_LIST_COMMAND(HCP_PIC_STATE_CMD) +
                  PATCH_LIST_COMMAND(HCP_TILE_STATE_CMD);
          }
      }
      else if (standard == CODECHAL_VP9)     // VP9 Clear Decode
      {
          maxSize =
              mhw_vdbox_vdenc_g9_bxt::VD_PIPELINE_FLUSH_CMD::byteSize +
              mhw_mi_g9_X::MI_FLUSH_DW_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_PIPE_MODE_SELECT_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_SURFACE_STATE_CMD::byteSize * 4 +
              mhw_vdbox_hcp_g9_bxt::HCP_PIPE_BUF_ADDR_STATE_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_IND_OBJ_BASE_ADDR_STATE_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_VP9_SEGMENT_STATE_CMD::byteSize * 8 +
              mhw_vdbox_hcp_g9_bxt::HCP_VP9_PIC_STATE_CMD::byteSize +
              mhw_vdbox_hcp_g9_bxt::HCP_BSD_OBJECT_CMD::byteSize;
  
          patchListMaxSize =
              PATCH_LIST_COMMAND(VD_PIPELINE_FLUSH_CMD) +
              PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD) +
              PATCH_LIST_COMMAND(HCP_PIPE_MODE_SELECT_CMD) +
              PATCH_LIST_COMMAND(HCP_SURFACE_STATE_CMD) * 4 +
              PATCH_LIST_COMMAND(HCP_PIPE_BUF_ADDR_STATE_CMD) +
              PATCH_LIST_COMMAND(HCP_IND_OBJ_BASE_ADDR_STATE_CMD) +
              PATCH_LIST_COMMAND(HCP_VP9_SEGMENT_STATE_CMD) * 8 +
              PATCH_LIST_COMMAND(HCP_VP9_PIC_STATE_CMD) +
              PATCH_LIST_COMMAND(HCP_BSD_OBJECT_CMD);
      }
      else
      {
          MHW_ASSERTMESSAGE("Unsupported standard.");
          eStatus = MOS_STATUS_UNKNOWN;
      }
  
      *commandsSize = maxSize;
      *patchListSize = patchListMaxSize;
  
      return eStatus;
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::GetHcpPrimitiveCommandSize(
      uint32_t                        mode,
      uint32_t                        *commandsSize,
      uint32_t                        *patchListSize,
      bool                            modeSpecific)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_FUNCTION_ENTER;
  
      uint32_t            standard = CodecHal_GetStandardFromMode(mode);
      uint32_t            maxSize = 0;
      uint32_t            patchListMaxSize = 0;
  
      if (standard == CODECHAL_HEVC)
      {
          if (mode == CODECHAL_ENCODE_MODE_HEVC)
          {
              maxSize =
                  2 * mhw_vdbox_hcp_g9_bxt::HCP_REF_IDX_STATE_CMD::byteSize +
                  2 * mhw_vdbox_hcp_g9_bxt::HCP_WEIGHTOFFSET_STATE_CMD::byteSize +
                  mhw_vdbox_hcp_g9_bxt::HCP_SLICE_STATE_CMD::byteSize +
                  mhw_vdbox_hcp_g9_bxt::HCP_PAK_INSERT_OBJECT_CMD::byteSize +
                  mhw_mi_g9_X::MI_BATCH_BUFFER_START_CMD::byteSize;
  
              patchListMaxSize =
                  2 * PATCH_LIST_COMMAND(HCP_REF_IDX_STATE_CMD) +
                  2 * PATCH_LIST_COMMAND(HCP_WEIGHTOFFSET_STATE_CMD) +
                  PATCH_LIST_COMMAND(HCP_SLICE_STATE_CMD) +
                  PATCH_LIST_COMMAND(HCP_PAK_INSERT_OBJECT_CMD) +
                  2 * PATCH_LIST_COMMAND(MI_BATCH_BUFFER_START_CMD); // One is for the PAK command and another one is for the BB when BRC and single task mode are on
  
          }
          else
          {
              maxSize =
                  2 * mhw_vdbox_hcp_g9_bxt::HCP_REF_IDX_STATE_CMD::byteSize +
                  2 * mhw_vdbox_hcp_g9_bxt::HCP_WEIGHTOFFSET_STATE_CMD::byteSize +
                  mhw_vdbox_hcp_g9_bxt::HCP_SLICE_STATE_CMD::byteSize +
                  mhw_vdbox_hcp_g9_bxt::HCP_BSD_OBJECT_CMD::byteSize +
                  mhw_mi_g9_X::MI_BATCH_BUFFER_END_CMD::byteSize;
  
              patchListMaxSize =
                  2 * PATCH_LIST_COMMAND(HCP_REF_IDX_STATE_CMD) +
                  2 * PATCH_LIST_COMMAND(HCP_WEIGHTOFFSET_STATE_CMD) +
                  PATCH_LIST_COMMAND(HCP_SLICE_STATE_CMD) +
                  PATCH_LIST_COMMAND(HCP_BSD_OBJECT_CMD);
          }
      }
      else if (standard == CODECHAL_VP9)      // VP9 Clear decode does not require primitive level commands. VP9 DRM does.
      {
          if (modeSpecific)                  // VP9 DRM
          {
              maxSize +=
                  mhw_vdbox_hcp_g9_bxt::HCP_VP9_SEGMENT_STATE_CMD::byteSize * 8 +
                  mhw_vdbox_hcp_g9_bxt::HCP_VP9_PIC_STATE_CMD::byteSize +
                  mhw_vdbox_hcp_g9_bxt::HCP_BSD_OBJECT_CMD::byteSize +
                  mhw_mi_g9_X::MI_BATCH_BUFFER_END_CMD::byteSize;
  
              patchListMaxSize =
                  PATCH_LIST_COMMAND(HCP_VP9_SEGMENT_STATE_CMD) * 8 +
                  PATCH_LIST_COMMAND(HCP_VP9_PIC_STATE_CMD) +
                  PATCH_LIST_COMMAND(HCP_BSD_OBJECT_CMD);
          }
      }
      else
      {
          MHW_ASSERTMESSAGE("Unsupported standard.");
          eStatus = MOS_STATUS_UNKNOWN;
      }
  
      *commandsSize = maxSize;
      *patchListSize = patchListMaxSize;
  
      return eStatus;
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpPipeModeSelectCmd(
      PMOS_COMMAND_BUFFER                  cmdBuffer,
      PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS   params)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_FUNCTION_ENTER;
  
      MHW_MI_CHK_NULL(params);
  
      mhw_vdbox_hcp_g9_bxt::HCP_PIPE_MODE_SELECT_CMD   *cmd =
          (mhw_vdbox_hcp_g9_bxt::HCP_PIPE_MODE_SELECT_CMD*)cmdBuffer->pCmdPtr;
  
      MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceG9<mhw_vdbox_hcp_g9_bxt>::AddHcpPipeModeSelectCmd(cmdBuffer, params));
  
      m_cpInterface->SetProtectionSettingsForHcpPipeModeSelect((uint32_t *)cmd);
  
      return eStatus;
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpDecodeSurfaceStateCmd(
      PMOS_COMMAND_BUFFER              cmdBuffer,
      PMHW_VDBOX_SURFACE_PARAMS        params)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_MI_CHK_NULL(params);
  
      mhw_vdbox_hcp_g9_bxt::HCP_SURFACE_STATE_CMD  *cmd =
          (mhw_vdbox_hcp_g9_bxt::HCP_SURFACE_STATE_CMD*)cmdBuffer->pCmdPtr;
  
      MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceGeneric<mhw_vdbox_hcp_g9_bxt>::AddHcpDecodeSurfaceStateCmd(cmdBuffer, params));
  
      if (params->ucBitDepthLumaMinus8 == 0 && params->ucBitDepthChromaMinus8 == 0)
      {
          cmd->DW2.SurfaceFormat = HCP_SURFACE_FORMAT_PLANAR_420_8;
      }
      else
      {
          cmd->DW2.SurfaceFormat = HCP_SURFACE_FORMAT_P010;
      }
  
      return eStatus;
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpEncodeSurfaceStateCmd(
      PMOS_COMMAND_BUFFER              cmdBuffer,
      PMHW_VDBOX_SURFACE_PARAMS        params)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_MI_CHK_NULL(params);
  
      mhw_vdbox_hcp_g9_bxt::HCP_SURFACE_STATE_CMD  *cmd =
          (mhw_vdbox_hcp_g9_bxt::HCP_SURFACE_STATE_CMD*)cmdBuffer->pCmdPtr;
  
      MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceGeneric<mhw_vdbox_hcp_g9_bxt>::AddHcpEncodeSurfaceStateCmd(cmdBuffer, params));
  
      if (params->ucBitDepthLumaMinus8 == 0 && params->ucBitDepthChromaMinus8 == 0)
      {
          cmd->DW2.SurfaceFormat = HCP_SURFACE_FORMAT_PLANAR_420_8;
      }
      else
      {
          cmd->DW2.SurfaceFormat = HCP_SURFACE_FORMAT_P010;
      }
  
      return eStatus;
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpDecodePicStateCmd(
      PMOS_COMMAND_BUFFER              cmdBuffer,
      PMHW_VDBOX_HEVC_PIC_STATE        params)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_FUNCTION_ENTER;
  
      MHW_MI_CHK_NULL(params);
      MHW_MI_CHK_NULL(params->pHevcPicParams);
  
      mhw_vdbox_hcp_g9_bxt::HCP_PIC_STATE_CMD  *cmd =
          (mhw_vdbox_hcp_g9_bxt::HCP_PIC_STATE_CMD*)cmdBuffer->pCmdPtr;
  
      MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceGeneric<mhw_vdbox_hcp_g9_bxt>::AddHcpDecodePicStateCmd(cmdBuffer, params));
  
      auto hevcPicParams = params->pHevcPicParams;
      PLATFORM  platform;
      m_osInterface->pfnGetPlatform(m_osInterface, &platform);
  
      // HCP is changed from B-STEPPING for HEVC MAIN 10 decode
      if (platform.usRevId > 2)
      {
          cmd->DW5.BitDepthChromaMinus8 = hevcPicParams->bit_depth_chroma_minus8;
          cmd->DW5.BitDepthLumaMinus8 = hevcPicParams->bit_depth_luma_minus8;
      }
  
      return eStatus;
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpDecodeSliceStateCmd(
      PMOS_COMMAND_BUFFER              cmdBuffer,
      PMHW_VDBOX_HEVC_SLICE_STATE      hevcSliceState)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_FUNCTION_ENTER;
  
      MHW_MI_CHK_NULL(hevcSliceState);
      MHW_MI_CHK_NULL(hevcSliceState->pHevcPicParams);
      MHW_MI_CHK_NULL(hevcSliceState->pHevcSliceParams);
  
      auto hevcPicParams = hevcSliceState->pHevcPicParams;
      auto hevcSliceParams = hevcSliceState->pHevcSliceParams;
  
      mhw_vdbox_hcp_g9_bxt::HCP_SLICE_STATE_CMD  *cmd =
          (mhw_vdbox_hcp_g9_bxt::HCP_SLICE_STATE_CMD*)cmdBuffer->pCmdPtr;
  
      MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceGeneric<mhw_vdbox_hcp_g9_bxt>::AddHcpDecodeSliceStateCmd(cmdBuffer, hevcSliceState));
  
      PLATFORM  platform;
      m_osInterface->pfnGetPlatform(m_osInterface, &platform);
  
      // HCP is changed from B-STEPPING for HEVC MAIN 10 decode
      if (platform.usRevId > 2)
      {
          int32_t sliceQP = hevcSliceParams->slice_qp_delta + hevcPicParams->init_qp_minus26 + 26;
          cmd->DW3.SliceqpSignFlag = (sliceQP >= 0) ? 0 : 1;
          cmd->DW3.Sliceqp = ABS(sliceQP);
      }
      else
      {
          cmd->DW3.Sliceqp = hevcSliceParams->slice_qp_delta +
              hevcPicParams->init_qp_minus26 + 26;
      }
  
      return eStatus;
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd(
      PMOS_COMMAND_BUFFER              cmdBuffer,
      PMHW_BATCH_BUFFER                batchBuffer,
      PMHW_VDBOX_VP9_PIC_STATE         params)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_MI_CHK_NULL(params);
      MHW_MI_CHK_NULL(params->pVp9PicParams);
  
      mhw_vdbox_hcp_g9_bxt::HCP_VP9_PIC_STATE_CMD cmd;
      auto vp9PicParams = params->pVp9PicParams;
      auto vp9RefList = params->ppVp9RefList;
  
      uint32_t curFrameWidth                      = vp9PicParams->FrameWidthMinus1 + 1;
      uint32_t curFrameHeight                     = vp9PicParams->FrameHeightMinus1 + 1;
  
      cmd.DW1.FrameWidthInPixelsMinus1            = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
      cmd.DW1.FrameHeightInPixelsMinus1           = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
  
      cmd.DW2.FrameType                           = vp9PicParams->PicFlags.fields.frame_type;
      cmd.DW2.AdaptProbabilitiesFlag              = !vp9PicParams->PicFlags.fields.error_resilient_mode && !vp9PicParams->PicFlags.fields.frame_parallel_decoding_mode;
      cmd.DW2.IntraonlyFlag                       = vp9PicParams->PicFlags.fields.intra_only;
      cmd.DW2.RefreshFrameContext                 = vp9PicParams->PicFlags.fields.refresh_frame_context;
      cmd.DW2.ErrorResilientMode                  = vp9PicParams->PicFlags.fields.error_resilient_mode;
      cmd.DW2.FrameParallelDecodingMode           = vp9PicParams->PicFlags.fields.frame_parallel_decoding_mode;
      cmd.DW2.FilterLevel                         = vp9PicParams->filter_level;
      cmd.DW2.SharpnessLevel                      = vp9PicParams->sharpness_level;
      cmd.DW2.SegmentationEnabled                 = vp9PicParams->PicFlags.fields.segmentation_enabled;
      cmd.DW2.SegmentationUpdateMap               = cmd.DW2.SegmentationEnabled && vp9PicParams->PicFlags.fields.segmentation_update_map;
      cmd.DW2.LosslessMode                        = vp9PicParams->PicFlags.fields.LosslessFlag;
      cmd.DW2.SegmentIdStreamoutEnable            = cmd.DW2.SegmentationUpdateMap;
  
      cmd.DW3.Log2TileRow                         = vp9PicParams->log2_tile_rows;        // No need to minus 1 here.
      cmd.DW3.Log2TileColumn                      = vp9PicParams->log2_tile_columns;     // No need to minus 1 here.
  
      cmd.DW10.UncompressedHeaderLengthInBytes70  = vp9PicParams->UncompressedHeaderLengthInBytes;
      cmd.DW10.FirstPartitionSizeInBytes150       = vp9PicParams->FirstPartitionSize;
  
      if (vp9PicParams->PicFlags.fields.frame_type && !vp9PicParams->PicFlags.fields.intra_only)
      {
          PCODEC_PICTURE refFrameList     = &(vp9PicParams->RefFrameList[0]);
  
          uint8_t  lastRefPicIndex        = refFrameList[vp9PicParams->PicFlags.fields.LastRefIdx].FrameIdx;
          uint32_t lastRefFrameWidth      = vp9RefList[lastRefPicIndex]->dwFrameWidth;
          uint32_t lastRefFrameHeight     = vp9RefList[lastRefPicIndex]->dwFrameHeight;
  
          uint8_t  goldenRefPicIndex      = refFrameList[vp9PicParams->PicFlags.fields.GoldenRefIdx].FrameIdx;
          uint32_t goldenRefFrameWidth    = vp9RefList[goldenRefPicIndex]->dwFrameWidth;
          uint32_t goldenRefFrameHeight   = vp9RefList[goldenRefPicIndex]->dwFrameHeight;
  
          uint8_t  altRefPicIndex         = refFrameList[vp9PicParams->PicFlags.fields.AltRefIdx].FrameIdx;
          uint32_t altRefFrameWidth       = vp9RefList[altRefPicIndex]->dwFrameWidth;
          uint32_t altRefFrameHeight      = vp9RefList[altRefPicIndex]->dwFrameHeight;
  
          bool isScaling                  = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
  
          cmd.DW2.AllowHiPrecisionMv              = vp9PicParams->PicFlags.fields.allow_high_precision_mv;
          cmd.DW2.McompFilterType                 = vp9PicParams->PicFlags.fields.mcomp_filter_type;
          cmd.DW2.SegmentationTemporalUpdate      = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update;
  
          cmd.DW2.RefFrameSignBias02              = vp9PicParams->PicFlags.fields.LastRefSignBias | 
                                                    (vp9PicParams->PicFlags.fields.GoldenRefSignBias << 1) | 
                                                    (vp9PicParams->PicFlags.fields.AltRefSignBias << 2);
  
          cmd.DW2.LastFrameType                   = !params->PrevFrameParams.fields.KeyFrame;
  
          cmd.DW2.UsePrevInFindMvReferences       = vp9PicParams->PicFlags.fields.error_resilient_mode    ||
                                                      params->PrevFrameParams.fields.KeyFrame             ||
                                                      params->PrevFrameParams.fields.IntraOnly            ||
                                                      !params->PrevFrameParams.fields.Display             ||
                                                      isScaling ? false : true;
  
          cmd.DW2.SegmentIdStreaminEnable         = vp9PicParams->PicFlags.fields.error_resilient_mode    ||
                                                      !cmd.DW2.SegmentationEnabled ||
                                                      isScaling ? false : true;
  
          cmd.DW4.HorizontalScaleFactorForLast    = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
          cmd.DW4.VerticalScaleFactorForLast      = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
  
          cmd.DW5.HorizontalScaleFactorForGolden  = (goldenRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
          cmd.DW5.VerticalScaleFactorForGolden    = (goldenRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
  
          cmd.DW6.HorizontalScaleFactorForAltref  = (altRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
          cmd.DW6.VerticalScaleFactorForAltref    = (altRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
  
          cmd.DW7.LastFrameWidthInPixelsMinus1    = lastRefFrameWidth - 1;
          cmd.DW7.LastFrameHieghtInPixelsMinus1   = lastRefFrameHeight - 1;
  
          cmd.DW8.GoldenFrameWidthInPixelsMinus1  = goldenRefFrameWidth - 1;
          cmd.DW8.GoldenFrameHieghtInPixelsMinus1 = goldenRefFrameHeight - 1;
  
          cmd.DW9.AltrefFrameWidthInPixelsMinus1  = altRefFrameWidth - 1;
          cmd.DW9.AltrefFrameHieghtInPixelsMinus1 = altRefFrameHeight - 1;
      }
  
      MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(cmdBuffer, batchBuffer, &cmd, cmd.byteSize));
  
      return eStatus;
  }
  
  MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9SegmentStateCmd(
      PMOS_COMMAND_BUFFER              cmdBuffer,
      PMHW_BATCH_BUFFER                batchBuffer,
      PMHW_VDBOX_VP9_SEGMENT_STATE     params)
  {
      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
  
      MHW_MI_CHK_NULL(params);
  
      mhw_vdbox_hcp_g9_bxt::HCP_VP9_SEGMENT_STATE_CMD  cmd;
      void*  segData = nullptr;
  
      cmd.DW1.SegmentId = params->ucCurrentSegmentId;
  
      if (!this->m_decodeInUse)
      {
          CODEC_VP9_ENCODE_SEG_PARAMS             vp9SegData;
  
          vp9SegData = params->pVp9EncodeSegmentParams->SegData[params->ucCurrentSegmentId];
  
          if (params->pbSegStateBufferPtr)   // Use the seg data from this buffer (output of BRC)
          {
              segData = params->pbSegStateBufferPtr;
          }
          else    // Prepare the seg data
          {
              cmd.DW2.SegmentSkipped = vp9SegData.SegmentFlags.fields.SegmentSkipped;
              cmd.DW2.SegmentReference = vp9SegData.SegmentFlags.fields.SegmentReference;
              cmd.DW2.SegmentReferenceEnabled = vp9SegData.SegmentFlags.fields.SegmentReferenceEnabled;
  
              segData = &cmd;
          }
      }
      else
      {
          CODEC_VP9_SEG_PARAMS            vp9SegData;
          vp9SegData = params->pVp9SegmentParams->SegData[params->ucCurrentSegmentId];
  
          cmd.DW2.SegmentSkipped = vp9SegData.SegmentFlags.fields.SegmentReferenceSkipped;
          cmd.DW2.SegmentReference = vp9SegData.SegmentFlags.fields.SegmentReference;
          cmd.DW2.SegmentReferenceEnabled = vp9SegData.SegmentFlags.fields.SegmentReferenceEnabled;
  
          cmd.DW3.Filterlevelref0Mode0 = vp9SegData.FilterLevel[0][0];
          cmd.DW3.Filterlevelref0Mode1 = vp9SegData.FilterLevel[0][1];
          cmd.DW3.Filterlevelref1Mode0 = vp9SegData.FilterLevel[1][0];
          cmd.DW3.Filterlevelref1Mode1 = vp9SegData.FilterLevel[1][1];
  
          cmd.DW4.Filterlevelref2Mode0 = vp9SegData.FilterLevel[2][0];
          cmd.DW4.Filterlevelref2Mode1 = vp9SegData.FilterLevel[2][1];
          cmd.DW4.Filterlevelref3Mode0 = vp9SegData.FilterLevel[3][0];
          cmd.DW4.Filterlevelref3Mode1 = vp9SegData.FilterLevel[3][1];
  
          cmd.DW5.LumaDcQuantScaleDecodeModeOnly = vp9SegData.LumaDCQuantScale;
          cmd.DW5.LumaAcQuantScaleDecodeModeOnly = vp9SegData.LumaACQuantScale;
  
          cmd.DW6.ChromaDcQuantScaleDecodeModeOnly = vp9SegData.ChromaDCQuantScale;
          cmd.DW6.ChromaAcQuantScaleDecodeModeOnly = vp9SegData.ChromaACQuantScale;
  
          segData = &cmd;
      }
  
      MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(cmdBuffer, batchBuffer, segData, cmd.byteSize));
  
      return eStatus;
  }