blob: 52f77912bb8c91f0c8bec6f06a23cbe1c38b03fa [file] [log] [blame]
/*
* 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(Mos_VirtualEngineInterface_Initialize(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;
}
}