/* * Copyright (c) 2018, 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_encode_scalability.cpp //! \brief Implements the encode interface extension for encode scalability. //! \details Implements all functions required by CodecHal for scalability encoding. //! #include "codechal_encoder_base.h" #include "codechal_encode_scalability.h" #include "mos_util_user_interface.h" #include "mos_os_virtualengine_next.h" MOS_STATUS CodecHalEncodeScalability_InitializeState ( PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState, CodechalHwInterface *hwInterface) { PMOS_VIRTUALENGINE_INTERFACE pVEInterface; MOS_STATUS eStatus = MOS_STATUS_SUCCESS; PMOS_INTERFACE osInterface; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState); CODECHAL_ENCODE_CHK_NULL_RETURN(hwInterface); osInterface = hwInterface->GetOsInterface(); CODECHAL_ENCODE_CHK_NULL_RETURN(osInterface); pScalabilityState->pHwInterface = hwInterface; pScalabilityState->ucScalablePipeNum = 1; pScalabilityState->VideoContextSinglePipe = MOS_GPU_CONTEXT_VIDEO3; pScalabilityState->VideoContextScalable = MOS_GPU_CONTEXT_INVALID_HANDLE; //virtual engine init with scalability MOS_VIRTUALENGINE_INIT_PARAMS VEInitParms; MOS_ZeroMemory(&VEInitParms, sizeof(VEInitParms)); VEInitParms.bScalabilitySupported = true; // Disabling the Secondary command buffer creation in MOS_VE // To be programmed once Encode moves to using secondary command buffers in MOS VE interface VEInitParms.ucMaxNumOfSdryCmdBufInOneFrame = VEInitParms.ucNumOfSdryCmdBufSets = 0; VEInitParms.ucMaxNumPipesInUse = MOS_MAX_ENGINE_INSTANCE_PER_CLASS; CODECHAL_ENCODE_CHK_STATUS_RETURN(osInterface->pfnVirtualEngineInterfaceInitialize(osInterface, &VEInitParms)); pScalabilityState->pVEInterface = pVEInterface = osInterface->pVEInterf; if (pVEInterface->pfnVEGetHintParams) { CODECHAL_ENCODE_CHK_STATUS_RETURN(pVEInterface->pfnVEGetHintParams(pVEInterface, true, &pScalabilityState->pScalHintParms)); } if (pVEInterface->pfnVEGetHintParams) { CODECHAL_ENCODE_CHK_STATUS_RETURN(pVEInterface->pfnVEGetHintParams(pVEInterface, false, &pScalabilityState->pSingleHintParms)); } return eStatus; } MOS_STATUS CodechalEncodeScalability_ConstructParmsForGpuCtxCreation( PCODECHAL_ENCODE_SCALABILITY_STATE pScalState, PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreatOpts) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(pScalState); CODECHAL_ENCODE_CHK_NULL_RETURN(pScalState->pHwInterface); CODECHAL_ENCODE_CHK_NULL_RETURN(gpuCtxCreatOpts); gpuCtxCreatOpts->UsingSFC = false; gpuCtxCreatOpts->LRCACount = pScalState->ucScalablePipeNum; #if (_DEBUG || _RELEASE_INTERNAL) PMOS_INTERFACE pOsInterface = pScalState->pHwInterface->GetOsInterface(); CODECHAL_ENCODE_CHK_NULL_RETURN(pOsInterface); if (pOsInterface->bEnableDbgOvrdInVE) { PMOS_VIRTUALENGINE_INTERFACE pVEInterface = pScalState->pVEInterface; CODECHAL_ENCODE_CHK_NULL_RETURN(pVEInterface); gpuCtxCreatOpts->DebugOverride = true; if (pOsInterface->apoMosEnabled) { CODECHAL_ENCODE_CHK_NULL_RETURN(pVEInterface->veInterface); for (uint32_t i = 0; i < pVEInterface->veInterface->GetEngineCount(); i++) { gpuCtxCreatOpts->EngineInstance[i] = pVEInterface->veInterface->GetEngineLogicId(i); } } else { for (uint32_t i = 0; i < pVEInterface->ucEngineCount; i++) { gpuCtxCreatOpts->EngineInstance[i] = pVEInterface->EngineLogicId[i]; } } } #endif return eStatus; } MOS_STATUS CodecHalEncodeScalability_PopulateHintParams( PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState, PMOS_COMMAND_BUFFER cmdBuffer) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState); CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); PMOS_CMD_BUF_ATTRI_VE pAttriVe = (PMOS_CMD_BUF_ATTRI_VE)(cmdBuffer->Attributes.pAttriVe); if (pAttriVe) { if (pScalabilityState->ucScalablePipeNum >= 2) { CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState->pScalHintParms); pAttriVe->VEngineHintParams = *(pScalabilityState->pScalHintParms); } else { CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState->pSingleHintParms); pAttriVe->VEngineHintParams = *(pScalabilityState->pSingleHintParms); } pAttriVe->bUseVirtualEngineHint = true; } return eStatus; } MOS_STATUS CodecHalEncodeScalability_SetHintParams( CodechalEncoderState *pEncoder, PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState, PCODECHAL_ENCODE_SCALABILITY_SETHINT_PARMS pSetHintParms) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; PMOS_INTERFACE pOsInterface; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState); CODECHAL_ENCODE_CHK_NULL_RETURN(pSetHintParms); CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface); CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface()); pOsInterface = pScalabilityState->pHwInterface->GetOsInterface(); PMOS_VIRTUALENGINE_INTERFACE pVEInterface = pScalabilityState->pVEInterface; MOS_VIRTUALENGINE_SET_PARAMS VEParams; MOS_ZeroMemory(&VEParams, sizeof(VEParams)); VEParams.ucScalablePipeNum = pScalabilityState->ucScalablePipeNum; VEParams.bScalableMode = (pScalabilityState->ucScalablePipeNum >= 2); if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(pOsInterface)) { //not used by VE2.0 VEParams.bNeedSyncWithPrevious = pSetHintParms->bNeedSyncWithPrevious; VEParams.bSameEngineAsLastSubmission = pSetHintParms->bSameEngineAsLastSubmission; } if (pScalabilityState->ucScalablePipeNum >= 2) { for (auto i = 0; i < pScalabilityState->ucScalablePipeNum; i++) { VEParams.veBatchBuffer[i] = pSetHintParms->veBatchBuffer[i]; } } if (pVEInterface->pfnVESetHintParams) { CODECHAL_ENCODE_CHK_STATUS_RETURN(pVEInterface->pfnVESetHintParams(pVEInterface, &VEParams)); } return eStatus; } MOS_STATUS CodechalEncodeScalability_ChkGpuCtxReCreation( CodechalEncoderState *pEncoder, PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState, PMOS_GPUCTX_CREATOPTIONS_ENHANCED CurgpuCtxCreatOpts) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; PMOS_INTERFACE pOsInterface; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState); CODECHAL_ENCODE_CHK_NULL_RETURN(CurgpuCtxCreatOpts); pOsInterface = pScalabilityState->pHwInterface->GetOsInterface(); bool changed = false; CODECHAL_ENCODE_CHK_NULL_RETURN(pOsInterface); #if (_DEBUG || _RELEASE_INTERNAL) if (pOsInterface->bEnableDbgOvrdInVE) { changed = false; } else #endif { if (CurgpuCtxCreatOpts->LRCACount != pScalabilityState->ucScalablePipeNum) { changed = true; CurgpuCtxCreatOpts->LRCACount = pScalabilityState->ucScalablePipeNum; } else { changed = false; } } if (changed) { // Create a scalable GPU context once based on MOS_GPU_CONTEXT_VDBOX2_VIDEO3 if needed if (pScalabilityState->VideoContextScalable == MOS_GPU_CONTEXT_INVALID_HANDLE) { pScalabilityState->VideoContextScalable = MOS_VE_MULTINODESCALING_SUPPORTED(pOsInterface) ? MOS_GPU_CONTEXT_VIDEO6 : MOS_GPU_CONTEXT_VDBOX2_VIDEO3; eStatus = (MOS_STATUS)pOsInterface->pfnCreateGpuContext( pOsInterface, pScalabilityState->VideoContextScalable, MOS_GPU_NODE_VIDEO, CurgpuCtxCreatOpts); CODECHAL_ENCODE_CHK_STATUS_RETURN(pOsInterface->pfnRegisterBBCompleteNotifyEvent( pOsInterface, pScalabilityState->VideoContextScalable)); } // Switch across single pipe/ scalable mode gpu contexts MOS_GPU_CONTEXT GpuContext = (pScalabilityState->ucScalablePipeNum == 1) ? pScalabilityState->VideoContextSinglePipe : pScalabilityState->VideoContextScalable; pEncoder->SetVideoContext(GpuContext); pOsInterface->pfnSetEncodePakContext(pOsInterface, GpuContext); } return eStatus; } void CodecHalEncodeScalability_EncodePhaseToSubmissionType( bool isFirstPipe, PMOS_COMMAND_BUFFER pCmdBuffer) { if (isFirstPipe) { pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_MASTER; } else { pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_SLAVE; } }