| /* |
| * Copyright (c) 2016-2019, 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 codechal_decode_scalability.h |
| //! \brief Defines the decode interface extension for scalability. |
| //! \details Defines all types, macros, and functions required by CodecHal for virtual engine decode supporting both single pipe and scalable mode. Definitions are not externally facing. |
| //! |
| |
| #ifndef __CODECHAL_DECODER_SCALABILITY_H__ |
| #define __CODECHAL_DECODER_SCALABILITY_H__ |
| |
| #include "codechal.h" |
| #include "codechal_hw.h" |
| #include "codechal_decoder.h" |
| #include "mos_os_virtualengine_scalability.h" |
| |
| #define CODEC_VTILE_MAX_NUM 8 |
| |
| // first tile column width |
| |
| #define CODEC_SCALABILITY_FIRST_TILE_WIDTH_4K 2048 |
| #define CODEC_SCALABILITY_FIRST_TILE_WIDTH_8K 4096 |
| |
| #define CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD1_WIDTH 3840 |
| #define CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD2_WIDTH 3996 |
| #define CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD3_WIDTH 5120 |
| #define CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD4_WIDTH 7680 |
| #define CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD1_HEIGHT 1440 |
| #define CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD2_HEIGHT 1716 |
| #define CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD3_HEIGHT 2160 |
| #define CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD4_HEIGHT 4320 |
| |
| inline static bool CodechalDecodeResolutionEqualLargerThan4k(uint32_t width, uint32_t height) |
| { |
| return (((width * height) >= (CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD1_WIDTH * CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD3_HEIGHT)) |
| || ((width >= CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD1_WIDTH) && (height >= CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD2_HEIGHT))); |
| } |
| |
| inline static bool CodechalDecodeResolutionEqualLargerThan5k(uint32_t width, uint32_t height) |
| { |
| return (((width * height) >= (CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD3_WIDTH * CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD3_HEIGHT)) |
| || ((width >= CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD3_WIDTH) && (height >= CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD1_HEIGHT))); |
| } |
| |
| inline static bool CodechalDecodeNonRextFormat(MOS_FORMAT format) |
| { |
| return ((format == Format_NV12) || (format == Format_P010)); |
| } |
| |
| //! |
| //! \enum CODECHAL_HCP_DECODE_SCALABLE_PHASE |
| //! \brief extended HCP decode phase for scalability mode |
| //! |
| typedef enum |
| { |
| CODECHAL_HCP_DECODE_PHASE_FE = CodechalDecode::CodechalHcpDecodePhaseMax, //!< HCP decode virtual tile frontend phase |
| CODECHAL_HCP_DECODE_PHASE_BE0, //!< HCP decode virutal tile backend pipe0 phase |
| CODECHAL_HCP_DECODE_PHASE_BE1, //!< HCP decode virutal tile backend pipe1 phase |
| CODECHAL_HCP_DECODE_PHASE_RESERVED, //!< HCP decode reserved phase |
| CODECHAL_HCP_DECODE_SCALABLE_PHASE_MAX //!< HCP decode maximal phase in scalability mode |
| }CODECHAL_HCP_DECODE_SCALABLE_PHASE; |
| |
| static const int CODECHAL_HCP_STREAMOUT_BUFFER_MAX_NUM = 2; |
| |
| static const int CODECHAL_HCP_DECODE_SCALABLE_MAX_PHASE_NUM = (CODECHAL_HCP_DECODE_PHASE_BE1 + 1 - CODECHAL_HCP_DECODE_PHASE_FE + 1); |
| |
| typedef struct _CODECHAL_DECODE_SCALABILITY_FE_STATUS |
| { |
| uint64_t dwCarryFlagOfReportedSizeMinusAllocSize; //!< Carry flag of reported stream out size minus allocated size |
| } CODECHAL_DECODE_SCALABILITY_FE_STATUS, *PCODECHAL_DECODE_SCALABILITY_FE_STATUS; |
| |
| typedef struct _CODECHAL_DECODE_SCALABILITY_FE_CABAC_STREAMOUT_BUFF_SIZE |
| { |
| uint64_t dwCabacStreamoutBuffSize; //!< Cabac Streamout buff size |
| } CODECHAL_DECODE_SCALABILITY_FE_CABAC_STREAMOUT_BUFF_SIZE, *PCODECHAL_DECODE_SCALABILITY_FE_CABAC_STREAMOUT_BUFF_SIZE; |
| |
| typedef struct _CODECHAL_DECODE_SCALABILITY_SETHINT_PARMS |
| { |
| bool bSameEngineAsLastSubmission; |
| bool bNeedSyncWithPrevious; |
| bool bSFCInUse; |
| }CODECHAL_DECODE_SCALABILITY_SETHINT_PARMS, *PCODECHAL_DECODE_SCALABILITY_SETHINT_PARMS; |
| |
| typedef struct _CODECHAL_DECODE_SCALABILITY_INIT_PARAMS |
| { |
| uint32_t u32PicWidthInPixel; //!< Picture width in pixel align to minimal coding block |
| uint32_t u32PicHeightInPixel; //!< Picture height in pixel align to minimal coding block |
| MOS_FORMAT format; //!< Surface format |
| bool usingSFC; |
| uint8_t u8NumTileColumns; //!< Number of tile columns for this picture |
| uint8_t u8NumTileRows; //!< Number of tile rows for this picture |
| MOS_GPU_CONTEXT gpuCtxInUse; //!< gpu context in use |
| bool usingSecureDecode; |
| bool usingHistogram; |
| }CODECHAL_DECODE_SCALABILITY_INIT_PARAMS, *PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS; |
| |
| typedef struct _CODECHAL_DECODE_SCALABILITY_STATE CODECHAL_DECODE_SCALABILITY_STATE, *PCODECHAL_DECODE_SCALABILITY_STATE; |
| |
| struct _CODECHAL_DECODE_SCALABILITY_STATE |
| { |
| CodechalHwInterface *pHwInterface; |
| uint32_t Standard; |
| MOS_GPU_CONTEXT VideoContextForFE; |
| MOS_GPU_CONTEXT VideoContext; |
| MOS_GPU_CONTEXT VideoContextForSP; |
| MOS_GPU_CONTEXT VideoContextForMP; |
| MOS_GPU_CONTEXT VideoContextFor3P; |
| uint32_t HcpDecPhase; |
| bool bScalableDecodeMode; |
| |
| bool bFESeparateSubmission; |
| bool bFESeparateSubmissionVT; |
| bool bShortFormatInUse; |
| bool bUseSecdryCmdBuffer; |
| bool bIsEvenSplit; |
| uint8_t ucScalablePipeNum; |
| uint8_t ucNumVdbox; |
| uint32_t uiFirstTileColWidth; |
| uint32_t dwHcpDecModeSwtichTh1Width; |
| uint32_t dwHcpDecModeSwtichTh2Width; |
| MOS_RESOURCE resSliceStateStreamOutBuffer; |
| MOS_RESOURCE resMvUpRightColStoreBuffer; |
| MOS_RESOURCE resIntraPredUpRightColStoreBuffer; |
| MOS_RESOURCE resIntraPredLeftReconColStoreBuffer; |
| MOS_RESOURCE resCABACSyntaxStreamOutBuffer[CODECHAL_HCP_STREAMOUT_BUFFER_MAX_NUM]; |
| bool bToggleCABACStreamOutBuffer; |
| PMOS_RESOURCE presCABACStreamOutBuffer; |
| MOS_RESOURCE resSemaMemBEs; |
| MOS_RESOURCE resSemaMemFEBE; |
| MOS_RESOURCE resSemaMemCompletion; |
| MOS_RESOURCE resFEStatusBuffer; |
| MOS_RESOURCE resFeBeSyncObject; |
| MOS_RESOURCE resDelayMinus; |
| uint32_t numDelay; |
| uint32_t dwCABACSyntaxStreamOutBufferSize; |
| bool bIsEnableEndCurrentBatchBuffLevel; |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| bool bAlwaysFrameSplit; |
| uint32_t dbgOvrdWidthInMinCb; |
| #endif |
| |
| //For SFC Scalability |
| uint32_t fistValidTileIndex; |
| uint32_t lastValidTileIndex; |
| uint32_t dstXLandingCount; |
| uint32_t lastDstEndX; |
| uint32_t sliceStateCLs; |
| |
| //Virtual Engine related |
| PMOS_VIRTUALENGINE_INTERFACE pVEInterface; |
| PMOS_VIRTUALENGINE_HINT_PARAMS pScalHintParms; |
| PMOS_VIRTUALENGINE_HINT_PARAMS pSingleHintParms; |
| |
| MOS_STATUS(*pfnIsHcpBufferReallocNeeded) ( |
| CodechalHwInterface *pHwInterface, |
| MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE BufferType, |
| PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pReallocParam); |
| |
| MOS_STATUS (*pfnGetHcpBufferSize) ( |
| CodechalHwInterface *pHwInterface, |
| MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE dwBufferType, |
| PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS pHcpBufSizeParam); |
| |
| MOS_STATUS (*pfnDecidePipeNum) ( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalState, |
| PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS pInitParams); |
| |
| MOS_STATUS(*pfnMapPipeNumToLRCACount)( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalState, |
| uint32_t *LRCACount); |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| MOS_STATUS (*pfnDebugOvrdDecidePipeNum)( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalState); |
| #endif |
| }; |
| |
| #define CodecHalDecodeScalabilityIsBEPhase(pScalabilityState) \ |
| (pScalabilityState && pScalabilityState->bScalableDecodeMode && \ |
| ((pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0) || \ |
| (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE1) || \ |
| (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_RESERVED))) |
| |
| #define CodecHalDecodeScalabilityIsFEPhase(pScalabilityState) \ |
| (pScalabilityState && pScalabilityState->bScalableDecodeMode && pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_FE) |
| |
| #define CodecHalDecodeScalabilityIsFinalBEPhase(pScalabilityState) \ |
| (pScalabilityState && pScalabilityState->bScalableDecodeMode && \ |
| ((pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0 && pScalabilityState->ucScalablePipeNum == 1) || \ |
| (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE1 && pScalabilityState->ucScalablePipeNum == 2) || \ |
| (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_RESERVED && \ |
| pScalabilityState->ucScalablePipeNum == CODECHAL_HCP_DECODE_PHASE_RESERVED - CODECHAL_HCP_DECODE_PHASE_FE))) |
| |
| #define CodecHalDecodeScalablity_DecPhaseToHwWorkMode(EngineMode, PipeWorkMode)\ |
| do \ |
| { \ |
| if (m_hcpDecPhase == CODECHAL_HCP_DECODE_PHASE_FE) \ |
| { \ |
| EngineMode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_FE_LEGACY; \ |
| PipeWorkMode = MHW_VDBOX_HCP_PIPE_WORK_MODE_CABAC_FE; \ |
| } \ |
| else if (m_hcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0) \ |
| { \ |
| EngineMode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_LEFT; \ |
| PipeWorkMode = MHW_VDBOX_HCP_PIPE_WORK_MODE_CODEC_BE; \ |
| } \ |
| else if (m_hcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE1) \ |
| { \ |
| CODECHAL_DECODE_ASSERT(m_scalabilityState->ucScalablePipeNum >= 2); \ |
| EngineMode = (m_scalabilityState->ucScalablePipeNum == 2) ? \ |
| MHW_VDBOX_HCP_MULTI_ENGINE_MODE_RIGHT : MHW_VDBOX_HCP_MULTI_ENGINE_MODE_MIDDLE; \ |
| PipeWorkMode = MHW_VDBOX_HCP_PIPE_WORK_MODE_CODEC_BE; \ |
| } \ |
| else if (m_hcpDecPhase == CODECHAL_HCP_DECODE_PHASE_RESERVED) \ |
| { \ |
| CODECHAL_DECODE_ASSERT(m_scalabilityState->ucScalablePipeNum >= CODECHAL_HCP_DECODE_PHASE_RESERVED - CODECHAL_HCP_DECODE_PHASE_FE); \ |
| EngineMode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_RIGHT; \ |
| PipeWorkMode = MHW_VDBOX_HCP_PIPE_WORK_MODE_CODEC_BE; \ |
| } \ |
| }while (0) |
| |
| #define CodecHalDecodeScalabilityIsScalableMode(pScalabilityState) \ |
| (pScalabilityState ? pScalabilityState->bScalableDecodeMode : false) |
| |
| #define CodecHalDecodeScalabilityIsFESeparateSubmission(pScalabilityState) \ |
| (pScalabilityState ? (pScalabilityState->bScalableDecodeMode && pScalabilityState->bFESeparateSubmission) : false) |
| |
| #define CodecHalDecodeScalability1stDecPhase(pScalabilityState)\ |
| (pScalabilityState->HcpDecPhase == CodechalDecode::CodechalHcpDecodePhaseLegacyS2L || \ |
| (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_FE && !pScalabilityState->bShortFormatInUse)) |
| |
| #define CodecHalDecodeScalabilityIsLastCompletePhase(pScalabilityState)\ |
| (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0) |
| |
| #define CodecHalDecodeScalability1stPhaseofSubmission(pScalabilityState)\ |
| (CodecHalDecodeScalability1stDecPhase(pScalabilityState) || \ |
| (pScalabilityState->HcpDecPhase == CODECHAL_HCP_DECODE_PHASE_BE0 && pScalabilityState->bFESeparateSubmission)) |
| |
| //HCP Decode pipe number |
| typedef enum _CODECHAL_DECODE_HCP_SCALABILITY_PIPE_NUM |
| { |
| CODECHAL_DECODE_HCP_Legacy_PIPE_NUM_1 = 1, |
| CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_2 = 2, |
| CODECHAL_DECODE_HCP_SCALABLE_PIPE_NUM_RESERVED, |
| CODECHAL_DECODE_HCP_SCALABLE_MAX_PIPE_NUM |
| }CODECHAL_DECODE_HCP_SCALABILITY_PIPE_NUM; |
| |
| #define CODECHAL_SCALABILITY_DECODE_SECONDARY_CMDBUFSET_NUM 16 |
| #define CODECHAL_SCALABILITY_SLICE_STATE_CACHELINES_PER_SLICE 8 |
| |
| //! |
| //! \brief Decide pipe num of scalability decode |
| //! \param [in] pScalState |
| //! pointer to Scalability decode state |
| //! \param [in] pInitParams |
| //! pointer to initialize parameter |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_DecidePipeNum( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalState, |
| PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS pInitParams); |
| |
| //! |
| //! \brief Map the scalability pipe num to the LRCA count |
| //! \param [in] pScalState |
| //! pointer to Scalability decode state |
| //! \param [in] LRCACount |
| //! pointer to LRCA count |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodechalDecodeScalability_MapPipeNumToLRCACount( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalState, |
| uint32_t *LRCACount); |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| //! |
| //! \brief Debug override for scalability pipe num |
| //! \param [in] pScalState |
| //! pointer to Scalability decode state |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodechalDecodeScalability_DebugOvrdDecidePipeNum( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalState); |
| #endif |
| |
| //! |
| //! \brief Judge if Hevc buffer reallocate is needed |
| //! \param [in] hwInterface |
| //! HW interface for codechal |
| //! \param [in] bufferType |
| //! Type of the buffer |
| //! \param [in] reallocParam |
| //! Parameter of the reallocation |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS IsHevcBufferReallocNeeded( |
| CodechalHwInterface *hwInterface, |
| MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType, |
| PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam); |
| |
| //! |
| //! \brief Get Hevc buffer size |
| //! \param [in] hwInterface |
| //! HW interface for codechal |
| //! \param [in] bufferType |
| //! Type of the buffer |
| //! \param [in] hcpBufSizeParam |
| //! Parameter of the buffer size |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS GetHevcBufferSize( |
| CodechalHwInterface *hwInterface, |
| MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType, |
| PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam); |
| |
| //! |
| //! \brief Judge if Vp9 buffer reallocate is needed |
| //! \param [in] hwInterface |
| //! HW interface for codechal |
| //! \param [in] bufferType |
| //! Type of the buffer |
| //! \param [in] reallocParam |
| //! Parameter of the reallocation |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS IsVp9BufferReallocNeeded( |
| CodechalHwInterface *hwInterface, |
| MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType, |
| PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam); |
| |
| //! |
| //! \brief Get Vp9 buffer size |
| //! \param [in] hwInterface |
| //! HW interface for codechal |
| //! \param [in] bufferType |
| //! Type of the buffer |
| //! \param [in] hcpBufSizeParam |
| //! Parameter of the buffer size |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS GetVp9BufferSize( |
| CodechalHwInterface *hwInterface, |
| MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType, |
| PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam); |
| |
| //! |
| //! \brief Allocate fixed size resources for scalability decode |
| //! \param [in] pScalabilityState |
| //! pointer to Scalability decode state |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_AllocateResources_FixedSizes( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState); |
| |
| //! |
| //! \brief Allocate variable size resources for scalability decode |
| //! \param [in] pScalabilityState |
| //! pointer to Scalability decode state |
| //! \param [in] pHcpBufSizeParam |
| //! pointer to HCP Buf size parameter |
| //! \param [in] pAllocParam |
| //! pointer to Re-alloc parameter |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_AllocateResources_VariableSizes( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS pHcpBufSizeParam, |
| PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pAllocParam); |
| |
| //! |
| //! \brief Allocate CABAC streamout buffer for scalability decode |
| //! \param [in] pScalabilityState |
| //! pointer to Scalability decode state |
| //! \param [in] pHcpBufSizeParam |
| //! pointer to HCP Buf size parameter |
| //! \param [in] pAllocParam |
| //! pointer to Re-alloc parameter |
| //! \param [in] presCABACStreamOutBuffer |
| //! pointer to cabac streamout buffer |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| MOS_STATUS CodecHalDecodeScalability_AllocateCABACStreamOutBuffer( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMHW_VDBOX_HCP_BUFFER_SIZE_PARAMS pHcpBufSizeParam, |
| PMHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS pAllocParam, |
| PMOS_RESOURCE presCABACStreamOutBuffer); |
| |
| //! |
| //! \brief Destroy resources for scalability decoder |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| void CodecHalDecodeScalability_Destroy ( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState); |
| |
| //! |
| //! \brief get command buffer to use |
| //! \details decide and get command buffer to add cmds. it is for decoder which can support both scalability and single pipe |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pScdryCmdBuf |
| //! pointer to secondary cmd buffer |
| //! \param [in] ppCmdBufToUse |
| //! pointer to cmd buffer to use |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_GetCmdBufferToUse( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pScdryCmdBuf, |
| PMOS_COMMAND_BUFFER *ppCmdBufToUse); |
| |
| //! |
| //! \brief return secondary cmd buffer |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pScdryCmdBuf |
| //! pointer to secondary cmd buffer |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_ReturnSdryCmdBuffer( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pSdryCmdBuf); |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| //! |
| //! \brief dump command buffer in scalability mode |
| //! \param [in] pDecoder |
| //! Decoder device |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_DbgDumpCmdBuffer( |
| CodechalDecode *pDecoder, |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| CodechalDebugInterface *debugInterface, |
| PMOS_COMMAND_BUFFER pPrimCmdBuf); |
| #endif |
| |
| //! |
| //! \brief Set FE CABAC Streamout buffer overflow status for Scalability Decode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pCmdBufferInUse |
| //! Address of command buffer in use |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalablity_SetFECabacStreamoutOverflowStatus( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pCmdBufferInUse); |
| |
| //! |
| //! \brief Get FE Reported CABAC Streamout buffer size from register for Scalability Decode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pCmdBufferInUse |
| //! Address of command buffer in use |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalablity_GetFEReportedCabacStreamoutBufferSize( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pCmdBufferInUse); |
| |
| //! |
| //! \brief Determine decode phase |
| //! \details determine decode phase for decoder supporting scalability mode but not necessarily always running in scalable mode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pHcpDecPhase |
| //! Address of hcp decode phase |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_DetermineDecodePhase( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| uint32_t *pHcpDecPhase); |
| |
| //! |
| //! \brief Determine if sending watch dog timer start cmd |
| //! \details determine decode phase for decoder supporting scalability mode but not necessarily always running in scalable mode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pbSend |
| //! pointer to a flag indicating if to send |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_DetermineSendWatchdogTimerStart( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| bool *pbSend); |
| |
| //! |
| //! \brief switch gpu context in scalability decode mode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_SwitchGpuContext( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState); |
| |
| //! |
| //! \brief Initiliaze BEBE sync resources in scalability decode mode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pCmdBufferInUse |
| //! address of command buffer |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_InitSemaMemResources( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pCmdBuffer); |
| |
| //! |
| //! \brief Initiliaze Decode Parameters for virtual engine decode |
| //! \details Initiliaze decode parameters for virtual engine decode. this is for decoder supporting scalability but not necessarily always running in scalable mode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pInitParams |
| //! pointer to parameters to initialize decode scalability |
| //! \param [in] pucDecPassNum |
| //! pointer to decode pass number |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_InitScalableParams( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PCODECHAL_DECODE_SCALABILITY_INIT_PARAMS pInitParams, |
| uint16_t *pucDecPassNum); |
| |
| //! |
| //! \brief Set virtual engine hint parameters for scalable decode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pSetHintParms |
| //! pointer to set hint parameter |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_SetHintParams( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PCODECHAL_DECODE_SCALABILITY_SETHINT_PARMS pSetHintParms); |
| |
| //! |
| //! \brief Populate virtual engine hint parameters |
| //! \details Populate virtual engine hint parameters. Support both scalable and single pipe decode mode. |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pPrimCmdBuf |
| //! pointer to primary cmd buffer |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_PopulateHintParams( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pPrimCmdBuf); |
| |
| //! |
| //! \brief Signal HW or SW semaphore for sync between FE and BE |
| //! \details signal hw or sw semaphore at end of FE cmd buffer for sync between FE and BE |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pCmdBufferInUse |
| //! address of command buffer |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_SignalFE2BESemaphore( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pCmdBufferInUse); |
| |
| //! |
| //! \brief Sync between FE and BE |
| //! \details This function does 3 major things |
| //! 1) send hw or sw semaphore wait at start of BE0 cmd. |
| //! 2) use HW semaphore wait and MI ATOMIC cmd to make all BEs start running at the same time |
| //! 3) add COND BB END cmd to check if CABAC stream out buffer overflow. |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pCmdBufferInUse |
| //! address of command buffer |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_FEBESync( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pCmdBufferInUse); |
| |
| //! |
| //! \brief To judge if command buffer should be submitted. |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \return bool |
| //! True means to submit command buffer, False means not to submit. |
| //! |
| bool CodecHalDecodeScalabilityIsToSubmitCmdBuffer( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState); |
| |
| //! |
| //! \brief Calculate parameters for adding HCP_TILE_CODING cmd |
| //! \details Calculate parameters for adding HCP_TILE_CODING cmd in scalability decode |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pvStandardPicParams |
| //! HEVC or VP9 picture parameters |
| //! \param [in] pHcpTileCodingParam |
| //! pointer of HCP_TILE_CODING parameters |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| template <class TILE_CODING_PARAMS> |
| MOS_STATUS CodecHalDecodeScalability_CalculateHcpTileCodingParams( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| void *pvStandardPicParams, |
| TILE_CODING_PARAMS *pHcpTileCodingParam) |
| { |
| PCODEC_HEVC_PIC_PARAMS pHevcPicParams = nullptr; |
| PCODEC_VP9_PIC_PARAMS pVp9PicParams = nullptr; |
| uint32_t i, uiMaxCbSize, uiMinCbSize, uiWidthInPixel, uiHeightInPixel; |
| uint32_t uiPicWidthInMinCb, uiPicHeightInMinCb, uiPicWidthInCtb; |
| uint8_t ucPipeIdx; |
| uint16_t usVTileColPos = 0; |
| uint16_t usVTileWidthInLCU[CODEC_VTILE_MAX_NUM]; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| CODECHAL_DECODE_CHK_NULL(pScalabilityState); |
| CODECHAL_DECODE_CHK_NULL(pScalabilityState->pHwInterface); |
| CODECHAL_DECODE_CHK_NULL(pvStandardPicParams); |
| CODECHAL_DECODE_CHK_NULL(pHcpTileCodingParam); |
| |
| //BEs: HCP TILE CODING |
| CODECHAL_DECODE_ASSERT(pScalabilityState->HcpDecPhase >= CODECHAL_HCP_DECODE_PHASE_BE0); |
| ucPipeIdx = pScalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_BE0; |
| |
| //calc virtual tile parameters |
| if (pScalabilityState->Standard == CODECHAL_HEVC) |
| { |
| pHevcPicParams = (PCODEC_HEVC_PIC_PARAMS)pvStandardPicParams; |
| uiMinCbSize = 1 << (pHevcPicParams->log2_min_luma_coding_block_size_minus3 + 3); |
| uiMaxCbSize = (1 << (pHevcPicParams->log2_diff_max_min_luma_coding_block_size)) * uiMinCbSize; |
| uiWidthInPixel = uiMinCbSize * (pHevcPicParams->PicWidthInMinCbsY); |
| uiHeightInPixel = uiMinCbSize * (pHevcPicParams->PicHeightInMinCbsY); |
| uiPicWidthInCtb = MOS_ROUNDUP_DIVIDE(uiWidthInPixel, uiMaxCbSize); |
| uiPicWidthInMinCb = pHevcPicParams->PicWidthInMinCbsY; |
| uiPicHeightInMinCb = pHevcPicParams->PicHeightInMinCbsY; |
| } |
| else if (pScalabilityState->Standard == CODECHAL_VP9) |
| { |
| pVp9PicParams = (PCODEC_VP9_PIC_PARAMS)pvStandardPicParams; |
| uiMinCbSize = CODEC_VP9_MIN_BLOCK_WIDTH; |
| uiMaxCbSize = CODEC_VP9_SUPER_BLOCK_WIDTH; |
| uiWidthInPixel = pVp9PicParams->FrameWidthMinus1 + 1; |
| uiHeightInPixel = pVp9PicParams->FrameHeightMinus1 + 1; |
| uiPicWidthInCtb = MOS_ROUNDUP_DIVIDE(pVp9PicParams->FrameWidthMinus1 + 1, CODEC_VP9_SUPER_BLOCK_WIDTH); |
| uiPicWidthInMinCb = MOS_ROUNDUP_DIVIDE(pVp9PicParams->FrameWidthMinus1 + 1, CODEC_VP9_MIN_BLOCK_WIDTH); |
| uiPicHeightInMinCb = MOS_ROUNDUP_DIVIDE(pVp9PicParams->FrameHeightMinus1 + 1, CODEC_VP9_MIN_BLOCK_WIDTH); |
| } |
| else |
| { |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| CODECHAL_DECODE_ASSERTMESSAGE("invalid codec type, only HEVC/VP9 are supported in scalability mode."); |
| goto finish; |
| } |
| |
| //calc virtual tile width and position |
| for (i = 0; i <= ucPipeIdx; i++) |
| { |
| usVTileWidthInLCU[i] = ((i + 1) * uiPicWidthInCtb / pScalabilityState->ucScalablePipeNum) - |
| (i * uiPicWidthInCtb / pScalabilityState->ucScalablePipeNum); |
| |
| usVTileColPos += (i == 0 ? 0 : usVTileWidthInLCU[i - 1]); |
| } |
| |
| if (usVTileWidthInLCU[ucPipeIdx] < 2) |
| { |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| MHW_ASSERTMESSAGE("HW limitation: Virtual tile for decode should be at least 2 LCU."); |
| goto finish; |
| } |
| |
| MOS_ZeroMemory(pHcpTileCodingParam, sizeof(TILE_CODING_PARAMS)); |
| |
| if (pScalabilityState->bIsEvenSplit) |
| { |
| //if the last tile, the tilewidth need to align to min CU not LCU. |
| if ( ucPipeIdx == (pScalabilityState->ucScalablePipeNum - 1)) |
| { |
| uint16_t usVTileColPosInMinCb = usVTileColPos * uiMaxCbSize / uiMinCbSize; |
| pHcpTileCodingParam->TileWidthInMinCbMinus1 = uiPicWidthInMinCb - usVTileColPosInMinCb - 1; |
| } |
| else |
| { |
| pHcpTileCodingParam->TileWidthInMinCbMinus1 = usVTileWidthInLCU[ucPipeIdx] * uiMaxCbSize / uiMinCbSize - 1; |
| } |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| if (pScalabilityState->dbgOvrdWidthInMinCb && pScalabilityState->ucScalablePipeNum == 2) |
| { |
| if (ucPipeIdx == 1) |
| { |
| pHcpTileCodingParam->TileWidthInMinCbMinus1 = uiPicWidthInMinCb - pScalabilityState->dbgOvrdWidthInMinCb - 1; |
| usVTileColPos = pScalabilityState->dbgOvrdWidthInMinCb * uiMinCbSize / uiMaxCbSize; |
| } |
| else |
| { |
| pHcpTileCodingParam->TileWidthInMinCbMinus1 = pScalabilityState->dbgOvrdWidthInMinCb - 1; |
| usVTileColPos = 0; |
| } |
| } |
| #endif |
| } |
| else |
| { |
| if (ucPipeIdx == 0) |
| { |
| usVTileColPos = 0; |
| if ((uiWidthInPixel * uiHeightInPixel) >= (CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD4_WIDTH * CODECHAL_HCP_DECODE_SCALABLE_THRESHOLD4_HEIGHT)) |
| { |
| // need to align first Tile Column to 4096 |
| pScalabilityState->uiFirstTileColWidth = CODEC_SCALABILITY_FIRST_TILE_WIDTH_8K; |
| } |
| else |
| { |
| // need to align first Tile Column to 2048 |
| pScalabilityState->uiFirstTileColWidth = CODEC_SCALABILITY_FIRST_TILE_WIDTH_4K; |
| } |
| |
| if (uiWidthInPixel <= pScalabilityState->uiFirstTileColWidth) |
| { |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| MHW_ASSERTMESSAGE("HW limitation: pic width %d should be greater than min tile width %d.", uiWidthInPixel, pScalabilityState->uiFirstTileColWidth); |
| goto finish; |
| } |
| |
| pHcpTileCodingParam->TileWidthInMinCbMinus1 = MOS_ROUNDUP_DIVIDE(pScalabilityState->uiFirstTileColWidth, uiMinCbSize) - 1; |
| } |
| else if (ucPipeIdx == 1) |
| { |
| usVTileColPos = GFX_CEIL_DIV(pScalabilityState->uiFirstTileColWidth, uiMaxCbSize); |
| pHcpTileCodingParam->TileWidthInMinCbMinus1 = uiPicWidthInMinCb - MOS_ROUNDUP_DIVIDE(pScalabilityState->uiFirstTileColWidth, uiMinCbSize) - 1; |
| } |
| else |
| { |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| CODECHAL_DECODE_ASSERTMESSAGE("Invalid pipe number %d for scalability + MMC.", ucPipeIdx); |
| goto finish; |
| } |
| } |
| |
| pHcpTileCodingParam->TileHeightInMinCbMinus1 = uiPicHeightInMinCb - 1; |
| pHcpTileCodingParam->TileStartLCUX = usVTileColPos; |
| pHcpTileCodingParam->ucNumDecodePipes = pScalabilityState->ucScalablePipeNum; |
| pHcpTileCodingParam->ucPipeIdx = ucPipeIdx; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Sync for all BEs completion |
| //! \details Add hw semaphore and/or MI ATOMIC cmd for all other BEs execution completion |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] pCmdBufferInUse |
| //! address of command buffer |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_BEsCompletionSync( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pCmdBufferInUse); |
| |
| //! |
| //! \brief Read CS ENGINEID register to know which engine is in use for current workload |
| //! \param [in] pDecodeStatusBuf |
| //! Decode status buffer |
| //! \param [in] pCmdBufferInUse |
| //! address of command buffer |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_ReadCSEngineIDReg( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| CodechalDecodeStatusBuffer *pDecodeStatusBuf, |
| PMOS_COMMAND_BUFFER pCmdBufferInUse); |
| |
| //! |
| //! \brief State initialization for virtual engine decode supporting scalable and single pipe mode |
| //! \param [in] pDecoder |
| //! Decoder device |
| //! \param [in] pScalabilityState |
| //! Scalability decode state |
| //! \param [in] bShortFormat |
| //! short format decode flag |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodecHalDecodeScalability_InitializeState ( |
| CodechalDecode *pDecoder, |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| CodechalHwInterface *hwInterface, |
| bool bShortFormat); |
| |
| //! \brief construct gpu context creation options when scalability supported |
| //! \param [in] scalabilityState |
| //! Scalability decode state |
| //! \param [in] gpuCtxCreatOptions |
| //! pointer to gpu context creation options |
| //! \param [in] codechalSetting |
| //! Pointer to codechal setting |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodechalDecodeScalability_ConstructParmsForGpuCtxCreation( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalState, |
| PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreatOpts, |
| CodechalSetting * codecHalSetting); |
| |
| //! \brief Check if need to recreate gpu context and if yes, do it. |
| //! \param [in] scalabilityState |
| //! Scalability decode state |
| //! \param [in] gpuCtxCreatOptions |
| //! pointer to gpu context creation options |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS CodechalDecodeScalability_ChkGpuCtxReCreation( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_GPUCTX_CREATOPTIONS_ENHANCED CurgpuCtxCreatOpts); |
| |
| //! |
| //! \brief Convert Decode Phase to Batch Buffer Submission Type |
| //! \param [in] scalabilityState |
| //! Scalability decode state |
| //! \param [in] pCmdBuffer |
| //! Pointer to command buffer |
| //! \return void |
| //! void |
| //! |
| void CodecHalDecodeScalability_DecPhaseToSubmissionType( |
| PCODECHAL_DECODE_SCALABILITY_STATE pScalabilityState, |
| PMOS_COMMAND_BUFFER pCmdBuffer); |
| |
| #endif //__CODECHAL_DECODER_SCALABILITY_H__ |