blob: d855d70c7d177172ccec88cb8e86be58ffc34318 [file] [log] [blame]
/*
* Copyright (c) 2019-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 policy.cpp
//! \brief Defines the common interface for vp features manager
//! \details The vp manager is further sub-divided by vp type
//! this file is for the base interface which is shared by all components.
//!
#include "policy.h"
#include "vp_obj_factories.h"
#include "vp_feature_manager.h"
#include "vp_platform_interface.h"
#include "sw_filter_handle.h"
using namespace vp;
/****************************************************************************************************/
/* Policy */
/****************************************************************************************************/
Policy::Policy(VpInterface &vpInterface) : m_vpInterface(vpInterface)
{
MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
// Read user feature key to get the Composition Bypass mode
MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
UserFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
// Vebox Comp Bypass is on by default
UserFeatureData.u32Data = VP_COMP_BYPASS_ENABLED;
MOS_USER_FEATURE_INVALID_KEY_ASSERT(MOS_UserFeature_ReadValue_ID(
nullptr,
__VPHAL_BYPASS_COMPOSITION_ID,
&UserFeatureData,
m_vpInterface.GetHwInterface() && m_vpInterface.GetHwInterface()->m_osInterface ? m_vpInterface.GetHwInterface()->m_osInterface->pOsContext : nullptr));
m_bypassCompMode = UserFeatureData.u32Data;
}
Policy::~Policy()
{
while (!m_VeboxSfcFeatureHandlers.empty())
{
std::map<FeatureType, PolicyFeatureHandler*>::iterator it = m_VeboxSfcFeatureHandlers.begin();
MOS_Delete(it->second);
m_VeboxSfcFeatureHandlers.erase(it);
}
while (!m_RenderFeatureHandlers.empty())
{
std::map<FeatureType, PolicyFeatureHandler*>::iterator it = m_RenderFeatureHandlers.begin();
MOS_Delete(it->second);
m_RenderFeatureHandlers.erase(it);
}
}
MOS_STATUS Policy::Initialize()
{
VpPlatformInterface *vpPlatformInterface = (VpPlatformInterface *)m_vpInterface.GetHwInterface()->m_vpPlatformInterface;
VP_PUBLIC_CHK_NULL_RETURN(vpPlatformInterface);
VP_PUBLIC_CHK_STATUS_RETURN(vpPlatformInterface->InitVpVeboxSfcHwCaps(m_veboxHwEntry, Format_Count, m_sfcHwEntry, Format_Count));
// Place hold for render hw caps.
VP_PUBLIC_CHK_STATUS_RETURN(vpPlatformInterface->InitVpRenderHwCaps());
VP_PUBLIC_CHK_STATUS_RETURN(RegisterFeatures());
m_initialized = true;
return MOS_STATUS_SUCCESS;
}
bool Policy::IsVeboxSfcFormatSupported(MOS_FORMAT formatInput, MOS_FORMAT formatOutput)
{
if (!m_initialized)
{
return false;
}
if (m_sfcHwEntry[formatInput].inputSupported &&
m_sfcHwEntry[formatOutput].outputSupported)
{
return true;
}
else
{
return false;
}
}
MOS_STATUS Policy::RegisterFeatures()
{
VP_FUNC_CALL();
// Vebox/Sfc features.
PolicyFeatureHandler *p = MOS_New(PolicySfcCscHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnSfc, p));
p = MOS_New(PolicySfcRotMirHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeRotMirOnSfc, p));
p = MOS_New(PolicySfcScalingHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeScalingOnSfc, p));
p = MOS_New(PolicyVeboxDnHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeDnOnVebox, p));
p = MOS_New(PolicyVeboxDiHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeDiOnVebox, p));
p = MOS_New(PolicyVeboxCscHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnVebox, p));
p = MOS_New(PolicyVeboxSteHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeSteOnVebox, p));
p = MOS_New(PolicyVeboxTccHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeTccOnVebox, p));
p = MOS_New(PolicyVeboxProcampHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeProcampOnVebox, p));
p = MOS_New(PolicyVeboxHdrHandler);
VP_PUBLIC_CHK_NULL_RETURN(p);
m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeHdrOnVebox, p));
// Next step to add a table to trace all SW features based on platforms
m_featurePool.clear();
m_featurePool.push_back(FeatureTypeCsc);
m_featurePool.push_back(FeatureTypeScaling);
m_featurePool.push_back(FeatureTypeRotMir);
m_featurePool.push_back(FeatureTypeDn);
m_featurePool.push_back(FeatureTypeSte);
m_featurePool.push_back(FeatureTypeTcc);
m_featurePool.push_back(FeatureTypeProcamp);
m_featurePool.push_back(FeatureTypeHdr);
m_featurePool.push_back(FeatureTypeDi);
return MOS_STATUS_SUCCESS;
}
/* Enable SwFilterPipe */
MOS_STATUS Policy::CreateHwFilter(SwFilterPipe &subSwFilterPipe, HwFilter *&pFilter)
{
VP_FUNC_CALL();
if (subSwFilterPipe.IsEmpty())
{
pFilter = nullptr;
return MOS_STATUS_SUCCESS;
}
HW_FILTER_PARAMS param = {};
MOS_STATUS status = GetHwFilterParam(subSwFilterPipe, param);
if (MOS_FAILED(status))
{
VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
return status;
}
pFilter = m_vpInterface.GetHwFilterFactory().Create(param);
ReleaseHwFilterParam(param);
if (!pFilter)
{
VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
return MOS_STATUS_UNIMPLEMENTED;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetHwFilterParam(SwFilterPipe& subSwFilterPipe, HW_FILTER_PARAMS& params)
{
VP_FUNC_CALL();
MOS_STATUS status;
params.Type = EngineTypeInvalid;
// Create and clear executedFilters.
if (params.executedFilters)
{
params.executedFilters->Clean();
}
else
{
status = m_vpInterface.GetSwFilterPipeFactory().Create(params.executedFilters);
if (status != MOS_STATUS_SUCCESS)
{
m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
VP_PUBLIC_ASSERTMESSAGE("Create Executed Filter Failed, Return Error");
return status;
}
}
status = GetExecuteCaps(subSwFilterPipe, params);
if (status != MOS_STATUS_SUCCESS)
{
m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
VP_PUBLIC_ASSERTMESSAGE("Create Executed Filter Failed, Return Error");
return status;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetExecuteCaps(SwFilterPipe& subSwFilterPipe, HW_FILTER_PARAMS& params)
{
VP_FUNC_CALL();
VP_EXECUTE_CAPS caps = {};
SwFilterSubPipe* inputPipe = nullptr;
uint32_t index = 0;
VP_PUBLIC_NORMALMESSAGE("Only Support primary layer for advanced processing");
inputPipe = subSwFilterPipe.GetSwFilterPrimaryPipe(index);
if (inputPipe)
{
VP_PUBLIC_CHK_STATUS_RETURN(BuildExecutionEngines(*inputPipe));
}
VP_PUBLIC_CHK_STATUS_RETURN(BuildFilters(subSwFilterPipe, params));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetExecutionCapsForSingleFeature(FeatureType featureType, SwFilterSubPipe& swFilterPipe)
{
SwFilter* feature = swFilterPipe.GetSwFilter(featureType);
SwFilter* diFilter = nullptr;
if (!feature)
{
VP_PUBLIC_NORMALMESSAGE("Feature %d is not enabled in current pipe", featureType);
return MOS_STATUS_SUCCESS;
}
else
{
VP_PUBLIC_NORMALMESSAGE("Feature %d is enabled in current pipe", featureType);
}
switch (featureType)
{
case FeatureTypeCsc:
diFilter = swFilterPipe.GetSwFilter(FeatureTypeDi);
if (diFilter)
{
VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCapsDi(feature));
}
else
{
VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature));
}
break;
case FeatureTypeScaling:
VP_PUBLIC_CHK_STATUS_RETURN(GetScalingExecutionCaps(feature));
break;
case FeatureTypeRotMir:
VP_PUBLIC_CHK_STATUS_RETURN(GetRotationExecutionCaps(feature));
break;
case FeatureTypeDn:
VP_PUBLIC_CHK_STATUS_RETURN(GetDenoiseExecutionCaps(feature));
break;
case FeatureTypeSte:
VP_PUBLIC_CHK_STATUS_RETURN(GetSteExecutionCaps(feature));
break;
case FeatureTypeTcc:
VP_PUBLIC_CHK_STATUS_RETURN(GetTccExecutionCaps(feature));
break;
case FeatureTypeProcamp:
VP_PUBLIC_CHK_STATUS_RETURN(GetProcampExecutionCaps(feature));
break;
case FeatureTypeHdr:
VP_PUBLIC_CHK_STATUS_RETURN(GetHdrExecutionCaps(feature));
break;
case FeatureTypeDi:
VP_PUBLIC_CHK_STATUS_RETURN(GetDeinterlaceExecutionCaps(feature));
break;
default:
VP_PUBLIC_CHK_STATUS_RETURN(GetExecutionCaps(feature));
VP_PUBLIC_NORMALMESSAGE("Feature didn't have supported in driver, default to use Render");
break;
}
if (feature->GetFilterEngineCaps().value == 0)
{
VP_PUBLIC_ASSERTMESSAGE("Error! No engine being assigned!");
return MOS_STATUS_INVALID_PARAMETER;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::BuildExecutionEngines(SwFilterSubPipe& swFilterPipe)
{
VP_FUNC_CALL();
SwFilter* feature = nullptr;
for (auto filterID : m_featurePool)
{
VP_PUBLIC_CHK_STATUS_RETURN(GetExecutionCapsForSingleFeature(filterID, swFilterPipe));
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetCSCExecutionCapsHdr(SwFilter *HDR, SwFilter *CSC)
{
SwFilterHdr *hdr = nullptr;
SwFilterCsc *csc = nullptr;
FeatureParamHdr *hdrParams = nullptr;
FeatureParamCsc *cscParams = nullptr;
VP_EngineEntry *cscEngine = nullptr;
VP_PUBLIC_CHK_NULL_RETURN(HDR);
VP_PUBLIC_CHK_NULL_RETURN(CSC);
hdr = (SwFilterHdr *)HDR;
csc = (SwFilterCsc *)CSC;
hdrParams = &hdr->GetSwFilterParams();
cscParams = &csc->GetSwFilterParams();
cscEngine = &csc->GetFilterEngineCaps();
//HDR CSC processing
if (!hdrParams || hdrParams->hdrMode == VPHAL_HDR_MODE_NONE)
{
VP_PUBLIC_ASSERTMESSAGE("HDR Mode is NONE");
VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
}
MOS_FORMAT hdrFormat = Format_Any;
VPHAL_CSPACE hdrCSpace = CSpace_Any;
if (m_sfcHwEntry[cscParams->formatInput].inputSupported &&
m_sfcHwEntry[cscParams->formatOutput].outputSupported &&
m_sfcHwEntry[cscParams->formatInput].cscSupported)
{
hdrCSpace = IS_COLOR_SPACE_BT2020(cscParams->colorSpaceOutput) ? CSpace_BT2020_RGB : CSpace_sRGB;
hdrFormat = IS_COLOR_SPACE_BT2020(cscParams->colorSpaceOutput) ? Format_R10G10B10A2 : Format_A8R8G8B8;
if (m_sfcHwEntry[hdrFormat].inputSupported &&
m_sfcHwEntry[cscParams->formatOutput].outputSupported &&
m_sfcHwEntry[hdrFormat].cscSupported)
{
cscEngine->bEnabled = 1;
cscEngine->SfcNeeded |= 1;
}
}
else
{
VP_PUBLIC_ASSERTMESSAGE("Post CSC for HDR not supported by SFC");
return MOS_STATUS_INVALID_PARAMETER;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetCSCExecutionCapsDi(SwFilter* feature)
{
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterCsc* csc = dynamic_cast<SwFilterCsc*>(feature);
VP_PUBLIC_CHK_NULL_RETURN(csc);
VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature));
VP_EngineEntry *cscEngine = &csc->GetFilterEngineCaps();
VP_PUBLIC_CHK_NULL_RETURN(cscEngine);
if (cscEngine->bEnabled &&
(cscEngine->SfcNeeded && cscEngine->VeboxNeeded ||
0 == cscEngine->SfcNeeded && 0 == cscEngine->VeboxNeeded && 0 == cscEngine->RenderNeeded))
{
cscEngine->SfcNeeded = 1;
cscEngine->VeboxNeeded = 0;
cscEngine->RenderNeeded = 0;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetCSCExecutionCaps(SwFilter* feature)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterCsc* csc = (SwFilterCsc*)feature;
FeatureParamCsc *cscParams = &csc->GetSwFilterParams();
MOS_FORMAT midFormat = Format_Any;
VP_EngineEntry *cscEngine = &csc->GetFilterEngineCaps();
if (cscEngine->value != 0)
{
VP_PUBLIC_NORMALMESSAGE("CSC Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
if (m_bypassCompMode != VP_COMP_BYPASS_DISABLED &&
cscParams->formatInput == cscParams->formatOutput &&
cscParams->colorSpaceInput == cscParams->colorSpaceOutput &&
cscParams->chromaSitingInput == cscParams->chromaSitingOutput &&
nullptr == cscParams->pIEFParams)
{
// for non-csc cases, all engine supported
cscEngine->bEnabled = 1;
cscEngine->SfcNeeded = 0;
cscEngine->VeboxNeeded = 0;
cscEngine->RenderNeeded = 0;
return MOS_STATUS_SUCCESS;
}
if (IS_COLOR_SPACE_BT2020_YUV(cscParams->colorSpaceInput))
{
if ((cscParams->colorSpaceOutput == CSpace_BT601) ||
(cscParams->colorSpaceOutput == CSpace_BT709) ||
(cscParams->colorSpaceOutput == CSpace_BT601_FullRange) ||
(cscParams->colorSpaceOutput == CSpace_BT709_FullRange) ||
(cscParams->colorSpaceOutput == CSpace_stRGB) ||
(cscParams->colorSpaceOutput == CSpace_sRGB))
{
midFormat = Format_A8R8G8B8;
cscEngine->VeboxNeeded |= ENGINE_MUST(1); // Vebox Gamut compression is needed
}
}
// SFC CSC enabling check
if (m_sfcHwEntry[cscParams->formatInput].inputSupported &&
m_sfcHwEntry[cscParams->formatOutput].outputSupported &&
m_sfcHwEntry[cscParams->formatInput].cscSupported)
{
if (midFormat != Format_Any &&
!m_sfcHwEntry[midFormat].cscSupported)
{
cscEngine->FurtherProcessNeeded |= 1;
cscEngine->DisableVeboxSFCMode |= 1;
//Another CSC Path is needed, need to create a new internal Surface and SW filter(Call SW Filter Factory) for processing
}
else
{
cscEngine->bEnabled = 1;
cscEngine->SfcNeeded |= 1;
}
}
// if vebox bypass composition mode disabled, then such mega feature like CSC will not take effect in Vebox.
// then CSC will must be assign to SFC/Render path for execution.
if (m_bypassCompMode != VP_COMP_BYPASS_DISABLED &&
!cscParams->pIEFParams &&
(!cscParams->pAlphaParams ||
cscParams->pAlphaParams->AlphaMode != VPHAL_ALPHA_FILL_MODE_BACKGROUND) &&
m_veboxHwEntry[cscParams->formatInput].inputSupported &&
m_veboxHwEntry[cscParams->formatOutput].outputSupported &&
m_veboxHwEntry[cscParams->formatInput].iecp &&
m_veboxHwEntry[cscParams->formatInput].backEndCscSupported)
{
cscEngine->bEnabled = 1;
cscEngine->VeboxNeeded |= 1;
}
/* Place Holder: Render support to be added, Futher process also need to be added */
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetScalingExecutionCaps(SwFilter* feature)
{
VP_FUNC_CALL();
uint32_t dwSurfaceWidth, dwSurfaceHeight;
uint32_t dwOutputSurfaceWidth, dwOutputSurfaceHeight;
uint32_t dwSfcMinWidth, dwSfcMaxWidth;
uint32_t dwSfcMinHeight, dwSfcMaxHeight;
uint32_t dwDstMinHeight;
float fScaleMin, fScaleMax;
float fScaleX, fScaleY;
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterScaling* scaling = (SwFilterScaling*)feature;
FeatureParamScaling *scalingParams = &scaling->GetSwFilterParams();
VP_EngineEntry *scalingEngine = &scaling->GetFilterEngineCaps();
if (scalingEngine->value != 0)
{
VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
dwSfcMinWidth = m_sfcHwEntry[scalingParams->formatInput].minResolution;
dwSfcMaxWidth = m_sfcHwEntry[scalingParams->formatInput].maxResolution;
dwSfcMinHeight = m_sfcHwEntry[scalingParams->formatInput].minResolution;
dwSfcMaxHeight = m_sfcHwEntry[scalingParams->formatInput].maxResolution;
fScaleMin = m_sfcHwEntry[scalingParams->formatInput].minScalingRatio;
fScaleMax = m_sfcHwEntry[scalingParams->formatInput].maxScalingRatio;
switch (scalingParams->interlacedScalingType)
{
case ISCALING_INTERLEAVED_TO_FIELD:
dwDstMinHeight = dwSfcMinHeight / 2;
break;
case ISCALING_FIELD_TO_INTERLEAVED:
dwDstMinHeight = dwSfcMinHeight * 2;
break;
default:
dwDstMinHeight = dwSfcMinHeight;
}
dwSurfaceWidth = scalingParams->dwWidthInput;
dwSurfaceHeight = scalingParams->dwHeightInput;
dwOutputSurfaceWidth = scalingParams->dwWidthOutput;
dwOutputSurfaceHeight = scalingParams->dwHeightOutput;
// Region of the input frame which needs to be processed by SFC
uint32_t dwSourceRegionHeight = MOS_ALIGN_FLOOR(
MOS_MIN((uint32_t)(scalingParams->rcSrcInput.bottom - scalingParams->rcSrcInput.top), dwSurfaceHeight),
m_sfcHwEntry[scalingParams->formatInput].verticalAlignUnit);
uint32_t dwSourceRegionWidth = MOS_ALIGN_FLOOR(
MOS_MIN((uint32_t)(scalingParams->rcSrcInput.right - scalingParams->rcSrcInput.left), dwSurfaceWidth),
m_sfcHwEntry[scalingParams->formatInput].horizontalAlignUnit);
// Size of the Output Region over the Render Target
uint32_t dwOutputRegionHeight = MOS_ALIGN_CEIL(
(uint32_t)(scalingParams->rcDstInput.bottom - scalingParams->rcDstInput.top),
m_sfcHwEntry[scalingParams->formatOutput].verticalAlignUnit);
uint32_t dwOutputRegionWidth = MOS_ALIGN_CEIL(
(uint32_t)(scalingParams->rcDstInput.right - scalingParams->rcDstInput.left),
m_sfcHwEntry[scalingParams->formatOutput].horizontalAlignUnit);
// Calculate the scaling ratio
// Both source region and scaled region are pre-rotated
// Need to take Interlace scaling into consideration next step
fScaleX = (float)dwOutputRegionWidth / (float)dwSourceRegionWidth;
fScaleY = (float)dwOutputRegionHeight / (float)dwSourceRegionHeight;
if (fScaleX == 1.0f && fScaleY == 1.0f &&
// Only support vebox crop from left-top, which is to align with legacy path.
0 == scalingParams->rcSrcInput.left && 0 == scalingParams->rcSrcInput.top)
{
// for non-Scaling cases, all engine supported
scalingEngine->bEnabled = 1;
scalingEngine->SfcNeeded = 0;
scalingEngine->VeboxNeeded = 0;
scalingEngine->RenderNeeded = 0;
return MOS_STATUS_SUCCESS;
}
// SFC Scaling enabling check
if (m_sfcHwEntry[scalingParams->formatInput].inputSupported &&
m_sfcHwEntry[scalingParams->formatOutput].outputSupported &&
m_sfcHwEntry[scalingParams->formatInput].scalingSupported)
{
if (!(OUT_OF_BOUNDS(dwSurfaceWidth, dwSfcMinWidth, dwSfcMaxWidth) ||
OUT_OF_BOUNDS(dwSurfaceHeight, dwSfcMinHeight, dwSfcMaxHeight) ||
OUT_OF_BOUNDS(dwSourceRegionWidth, dwSfcMinWidth, dwSfcMaxWidth) ||
OUT_OF_BOUNDS(dwSourceRegionHeight, dwSfcMinHeight, dwSfcMaxHeight) ||
OUT_OF_BOUNDS(dwOutputRegionWidth, dwSfcMinWidth, dwSfcMaxWidth) ||
OUT_OF_BOUNDS(dwOutputRegionHeight, dwDstMinHeight, dwSfcMaxHeight) ||
OUT_OF_BOUNDS(dwOutputSurfaceWidth, dwSfcMinWidth, dwSfcMaxWidth) ||
OUT_OF_BOUNDS(dwOutputSurfaceHeight, dwDstMinHeight, dwSfcMaxHeight)))
{
if (OUT_OF_BOUNDS(fScaleX, fScaleMin, fScaleMax) ||
OUT_OF_BOUNDS(fScaleY, fScaleMin, fScaleMax) ||
(scalingParams->scalingPreference == VPHAL_SCALING_PREFER_COMP))
{
// Render Pipe, need to add more conditions next step for multiple SFC mode
// if Render didn't have AVS but Scaling quality mode needed
scalingEngine->bEnabled = 1;
scalingEngine->RenderNeeded = 1;
scalingEngine->SfcNeeded = 0;
}
// SFC feasible
else
{
scalingEngine->bEnabled = 1;
scalingEngine->SfcNeeded = 1;
}
}
}
/* Multi-process Scaling need to ba added for futher feature enabling */
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetRotationExecutionCaps(SwFilter* feature)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterRotMir* rotation = (SwFilterRotMir*)feature;
FeatureParamRotMir *rotationParams = &rotation->GetSwFilterParams();
VP_EngineEntry *rotationEngine = &rotation->GetFilterEngineCaps();
if (rotationEngine->value != 0)
{
VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
if (rotationParams->rotation == VPHAL_ROTATION_IDENTITY)
{
// for non-rotation cases, all engine supported
rotationEngine->bEnabled = 1;
rotationEngine->VeboxNeeded = 0;
rotationEngine->SfcNeeded = 0;
rotationEngine->RenderNeeded = 0;
return MOS_STATUS_SUCCESS;
}
// SFC Rotation/Mirror enabling check
if (m_sfcHwEntry[rotationParams->formatInput].inputSupported &&
m_sfcHwEntry[rotationParams->formatOutput].outputSupported)
{
if (rotationParams->rotation > VPHAL_ROTATION_270 &&
(!m_sfcHwEntry[rotationParams->formatInput].mirrorSupported ||
rotationParams->tileOutput != MOS_TILE_Y))
{
// Render FC Path for Rotation
rotationEngine->bEnabled = 1;
rotationEngine->RenderNeeded = 1;
rotationEngine->SfcNeeded = 0;
}
else
{
rotationEngine->bEnabled = 1;
rotationEngine->SfcNeeded = 1;
}
}
else
{
// Render FC Path for Rotation
rotationEngine->bEnabled = 1;
rotationEngine->RenderNeeded = 1;
rotationEngine->SfcNeeded = 0;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetDenoiseExecutionCaps(SwFilter* feature)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterDenoise* denoise = dynamic_cast<SwFilterDenoise*>(feature);
VP_PUBLIC_CHK_NULL_RETURN(denoise);
FeatureParamDenoise& denoiseParams = denoise->GetSwFilterParams();
VP_EngineEntry& denoiseEngine = denoise->GetFilterEngineCaps();
MOS_FORMAT inputformat = denoiseParams.formatInput;
// MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
if (inputformat < 0)
{
inputformat = Format_Any;
}
uint32_t widthAlignUint = m_veboxHwEntry[inputformat].horizontalAlignUnit;
uint32_t heightAlignUnit = m_veboxHwEntry[inputformat].verticalAlignUnit;
if (denoiseEngine.value != 0)
{
VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
if (m_veboxHwEntry[inputformat].denoiseSupported)
{
widthAlignUint = MOS_ALIGN_CEIL(m_veboxHwEntry[inputformat].horizontalAlignUnit, 2);
if (inputformat == Format_NV12 ||
inputformat == Format_P010 ||
inputformat == Format_P016)
{
heightAlignUnit = MOS_ALIGN_CEIL(m_veboxHwEntry[inputformat].verticalAlignUnit, 4);
}
else
{
heightAlignUnit = MOS_ALIGN_CEIL(m_veboxHwEntry[inputformat].verticalAlignUnit, 2);
}
if (MOS_IS_ALIGNED(denoiseParams.heightInput, heightAlignUnit))
{
denoiseEngine.bEnabled = 1;
denoiseEngine.VeboxNeeded = 1;
}
else
{
VP_PUBLIC_NORMALMESSAGE("Denoise Feature is disabled since heightInput (%d) not being %d aligned.", denoiseParams.heightInput, heightAlignUnit);
}
}
denoiseParams.widthAlignUnitInput = widthAlignUint;
denoiseParams.heightAlignUnitInput = heightAlignUnit;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetDeinterlaceExecutionCaps(SwFilter* feature)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterDeinterlace* swFilterDi = dynamic_cast<SwFilterDeinterlace*>(feature);
VP_PUBLIC_CHK_NULL_RETURN(swFilterDi);
FeatureParamDeinterlace &diParams = swFilterDi->GetSwFilterParams();
VP_EngineEntry &diEngine = swFilterDi->GetFilterEngineCaps();
MOS_FORMAT inputformat = diParams.formatInput;
// MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
if (inputformat < 0)
{
inputformat = Format_Any;
}
if (diEngine.value != 0)
{
VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
if (m_vpInterface.GetResourceManager()->IsRefValid() &&
m_vpInterface.GetResourceManager()->IsSameSamples())
{
diEngine.bypassVeboxFeatures = 1;
}
else if (m_veboxHwEntry[inputformat].deinterlaceSupported)
{
diEngine.bEnabled = 1;
diEngine.VeboxNeeded = 1;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetSteExecutionCaps(SwFilter* feature)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterSte* steFilter = dynamic_cast<SwFilterSte*>(feature);
VP_PUBLIC_CHK_NULL_RETURN(steFilter);
FeatureParamSte& steParams = steFilter->GetSwFilterParams();
VP_EngineEntry& steEngine = steFilter->GetFilterEngineCaps();
MOS_FORMAT inputformat = steParams.formatInput;
// MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
if (inputformat < 0)
{
inputformat = Format_Any;
}
if (steEngine.value != 0)
{
VP_PUBLIC_NORMALMESSAGE("ACE Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
if (m_veboxHwEntry[inputformat].inputSupported &&
m_veboxHwEntry[inputformat].iecp)
{
steEngine.bEnabled = 1;
steEngine.VeboxNeeded = 1;
steEngine.VeboxIECPNeeded = 1;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetTccExecutionCaps(SwFilter* feature)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterTcc* tccFilter = dynamic_cast<SwFilterTcc*>(feature);
VP_PUBLIC_CHK_NULL_RETURN(tccFilter);
FeatureParamTcc& tccParams = tccFilter->GetSwFilterParams();
VP_EngineEntry& tccEngine = tccFilter->GetFilterEngineCaps();
MOS_FORMAT inputformat = tccParams.formatInput;
// MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
if (inputformat < 0)
{
inputformat = Format_Any;
}
if (tccEngine.value != 0)
{
VP_PUBLIC_NORMALMESSAGE("TCC Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
if (m_veboxHwEntry[inputformat].inputSupported &&
m_veboxHwEntry[inputformat].iecp)
{
tccEngine.bEnabled = 1;
tccEngine.VeboxNeeded = 1;
tccEngine.VeboxIECPNeeded = 1;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetProcampExecutionCaps(SwFilter* feature)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterProcamp* procampFilter = dynamic_cast<SwFilterProcamp*>(feature);
VP_PUBLIC_CHK_NULL_RETURN(procampFilter);
FeatureParamProcamp& procampParams = procampFilter->GetSwFilterParams();
VP_EngineEntry& procampEngine = procampFilter->GetFilterEngineCaps();
MOS_FORMAT inputformat = procampParams.formatInput;
// MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
if (inputformat < 0)
{
inputformat = Format_Any;
}
if (procampEngine.value != 0)
{
VP_PUBLIC_NORMALMESSAGE("Procamp Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
if (m_veboxHwEntry[inputformat].inputSupported &&
m_veboxHwEntry[inputformat].iecp)
{
procampEngine.bEnabled = 1;
procampEngine.VeboxNeeded = 1;
procampEngine.VeboxIECPNeeded = 1;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetHdrExecutionCaps(SwFilter *feature)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
SwFilterHdr *hdrFilter = dynamic_cast<SwFilterHdr *>(feature);
FeatureParamHdr *hdrParams = &hdrFilter->GetSwFilterParams();
VP_EngineEntry *pHDREngine = &hdrFilter->GetFilterEngineCaps();
MOS_FORMAT inputformat = hdrParams->formatInput;
// MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
if (inputformat < 0)
{
inputformat = Format_Any;
}
if (pHDREngine->value != 0)
{
VP_PUBLIC_NORMALMESSAGE("HDR Feature Already been processed, Skip further process");
return MOS_STATUS_SUCCESS;
}
if (m_veboxHwEntry[hdrParams->formatInput].inputSupported &&
m_veboxHwEntry[hdrParams->formatOutput].outputSupported &&
m_veboxHwEntry[hdrParams->formatInput].iecp)
{
pHDREngine->bEnabled = 1;
pHDREngine->VeboxNeeded = 1;
pHDREngine->VeboxIECPNeeded = 1;
if (hdrParams->formatOutput == Format_A8B8G8R8 || hdrParams->formatOutput == Format_A8R8G8B8)
{
pHDREngine->VeboxARGBOut = 1;
}
else if (hdrParams->formatOutput == Format_B10G10R10A2 || hdrParams->formatOutput == Format_R10G10B10A2)
{
pHDREngine->VeboxARGB10bitOutput = 1;
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetExecutionCaps(SwFilter* feature)
{
VP_PUBLIC_CHK_NULL_RETURN(feature);
VP_EngineEntry defaultEngine = feature->GetFilterEngineCaps();
defaultEngine.RenderNeeded = 1;
defaultEngine.bEnabled = 1;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::BuildFilters(SwFilterPipe& featurePipe, HW_FILTER_PARAMS& params)
{
VP_FUNC_CALL();
VP_EngineEntry engineCaps;
VP_EXECUTE_CAPS caps;
MOS_ZeroMemory(&caps, sizeof(VP_EXECUTE_CAPS));
MOS_ZeroMemory(&engineCaps, sizeof(VP_EngineEntry));
VP_PUBLIC_CHK_STATUS_RETURN(UpdateFilterCaps(featurePipe, engineCaps, caps));
// Sublayer will be processed in render path
if (!engineCaps.value)
{
engineCaps.bEnabled = 1;
engineCaps.RenderNeeded = 1;
engineCaps.CompositionNeeded = 1;
}
else if (engineCaps.bEnabled && engineCaps.VeboxNeeded == 0 &&
engineCaps.SfcNeeded == 0 && engineCaps.RenderNeeded == 0)
{
// Only scaling/csc/rotation filters and supported by all engines. Select vebox by default.
engineCaps.bEnabled = 1;
engineCaps.VeboxNeeded = 1;
engineCaps.SfcNeeded = 0;
engineCaps.RenderNeeded = 0;
}
// Enable Vebox Feature only
bool veboxOnlyEnabled = ENGINE_MUST_MASK(engineCaps.VeboxNeeded) && engineCaps.DisableVeboxSFCMode;
if (veboxOnlyEnabled)
{
// only select Vebox only features
caps.bVebox = 1;
caps.bIECP = engineCaps.VeboxIECPNeeded;
}
else
{
caps.bVebox = ((engineCaps.VeboxNeeded != 0) || (engineCaps.SfcNeeded != 0)) ? 1 : 0;
caps.bIECP = (caps.bVebox) ? engineCaps.VeboxIECPNeeded : 0;
VP_PUBLIC_CHK_STATUS_RETURN(UpdateFilterCaps(featurePipe, engineCaps, caps));
caps.bSFC = (engineCaps.SfcNeeded != 0) ? 1 : 0;
if (!caps.bVebox &&
!caps.bSFC)
{
caps.bRender = 1;
}
else
{
caps.bRender = 0;
}
caps.bComposite = (engineCaps.CompositionNeeded != 0);
}
if (IsVeboxSecurePathEnabled(featurePipe, caps))
{
// Process Vebox Secure workload
VP_PUBLIC_CHK_STATUS_RETURN(BuildVeboxSecureFilters(featurePipe, caps, params));
VP_PUBLIC_CHK_STATUS_RETURN(SetupFilterResource(featurePipe, caps, params));
VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteHwFilter(featurePipe, caps, params));
return MOS_STATUS_SUCCESS;
}
VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteFilter(featurePipe, caps, params));
VP_PUBLIC_CHK_STATUS_RETURN(featurePipe.ResetSecureFlag());
/* Place Holder for Resource Manager to manage intermedia surface or HW needed surface in policy*/
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::UpdateFilterCaps(SwFilterPipe& featurePipe, VP_EngineEntry& engineCaps, VP_EXECUTE_CAPS &caps)
{
VP_FUNC_CALL();
SwFilterSubPipe* inputPipe = nullptr;
SwFilter* feature = nullptr;
uint32_t index = 0;
inputPipe = featurePipe.GetSwFilterPrimaryPipe(index);
// Update the Engine Caps after engine setting up
if (engineCaps.value !=0 && inputPipe)
{
bool sfcNeeded = false;
// check whether sfc being must have.
for (auto filterID : m_featurePool)
{
feature = inputPipe->GetSwFilter(FeatureType(filterID));
if (feature)
{
if (feature->GetFilterEngineCaps().VeboxNeeded == 0 &&
feature->GetFilterEngineCaps().SfcNeeded != 0)
{
sfcNeeded = true;
break;
}
}
}
// check the feature pool, generate a workable engine Pipe
for (auto filterID : m_featurePool)
{
feature = inputPipe->GetSwFilter(FeatureType(filterID));
if (feature)
{
if (feature->GetFilterEngineCaps().VeboxNeeded != 0 &&
caps.bVebox)
{
if (sfcNeeded && feature->GetFilterEngineCaps().SfcNeeded)
{
feature->GetFilterEngineCaps().VeboxNeeded = 0;
feature->GetFilterEngineCaps().RenderNeeded = 0;
}
else
{
feature->GetFilterEngineCaps().SfcNeeded = 0;
feature->GetFilterEngineCaps().RenderNeeded = 0;
}
}
if (engineCaps.bypassVeboxFeatures)
{
if (caps.bVebox && feature->GetFilterEngineCaps().VeboxNeeded)
{
// Disable vebox features.
feature->GetFilterEngineCaps().bEnabled = false;
}
if (FeatureTypeDi == filterID)
{
caps.bDiProcess2ndField = 1;
}
}
}
}
}
engineCaps.value = 0;
// Set Engine Caps the first time
if (inputPipe)
{
// check the feature pool, generate a workable engine Pipe
for (auto filterID : m_featurePool)
{
feature = inputPipe->GetSwFilter(FeatureType(filterID));
if (feature)
{
engineCaps.value |= feature->GetFilterEngineCaps().value;
}
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::BuildExecuteFilter(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
{
VP_FUNC_CALL();
params.Type = EngineTypeInvalid;
params.vpExecuteCaps = caps;
VP_PUBLIC_CHK_STATUS_RETURN(SetupExecuteFilter(featurePipe, caps, params));
// Build Execute surface needed
VP_PUBLIC_CHK_STATUS_RETURN(SetupFilterResource(featurePipe, caps, params));
VP_PUBLIC_CHK_STATUS_RETURN(featurePipe.Update());
VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->Update());
VP_PUBLIC_CHK_STATUS_RETURN(BuildExecuteHwFilter(featurePipe, caps, params));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::BuildExecuteHwFilter(SwFilterPipe& subSwFilterPipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
{
VP_FUNC_CALL();
if (caps.bVebox || caps.bSFC)
{
params.Type = caps.bSFC ? EngineTypeVeboxSfc : EngineTypeVebox;
params.vpExecuteCaps = caps;
auto it = m_VeboxSfcFeatureHandlers.begin();
for (; it != m_VeboxSfcFeatureHandlers.end(); ++it)
{
if ((*(it->second)).IsFeatureEnabled(caps))
{
HwFilterParameter* pHwFilterParam = (*(it->second)).CreateHwFilterParam(caps, *params.executedFilters, m_vpInterface.GetHwInterface());
if (pHwFilterParam)
{
params.Params.push_back(pHwFilterParam);
}
else
{
VP_PUBLIC_ASSERTMESSAGE("Create HW Filter Failed, Return Error");
return MOS_STATUS_NO_SPACE;
}
}
}
}
else if (caps.bRender)
{
params.Type = EngineTypeRender;
params.vpExecuteCaps = caps;
auto it = m_RenderFeatureHandlers.begin();
for (; it != m_RenderFeatureHandlers.end(); ++it)
{
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::SetupExecuteFilter(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
{
VP_FUNC_CALL();
// Select the Pipe Engine for primary pipe
uint32_t index = 0;
SwFilterSubPipe* inputPipe = featurePipe.GetSwFilterPrimaryPipe(index);
SwFilter* feature = nullptr;
VP_SURFACE* surfInput = nullptr;
VP_SURFACE* surfOutput = nullptr;
VP_EngineEntry *engineCaps = nullptr;
// only process Primary surface
VP_PUBLIC_CHK_NULL_RETURN(inputPipe);
if (caps.value)
{
// Move surfaces from subSwFilterPipe to executedFilters.
surfInput = featurePipe.GetSurface(true, index);
if (surfInput)
{
// surface should be added before swFilters, since empty feature pipe will be allocated accordingly when surface being added.
VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->AddSurface(surfInput, true, index));
VP_SURFACE *pastRefSurface = featurePipe.RemovePastSurface(index);
VP_SURFACE *futureRefSurface = featurePipe.RemoveFutureSurface(index);
params.executedFilters->SetPastSurface(index, pastRefSurface);
params.executedFilters->SetFutureSurface(index, futureRefSurface);
}
else
{
VP_PUBLIC_ASSERTMESSAGE("No input for current pipe");
}
}
if (inputPipe)
{
for (auto filterID : m_featurePool)
{
feature = (SwFilter*)inputPipe->GetSwFilter(FeatureType(filterID));
if (feature)
{
engineCaps = &(feature->GetFilterEngineCaps());
// if SFC enabled, Vebox is must as SFC need connect with Vebox
if (caps.bSFC && engineCaps->bEnabled && !engineCaps->RenderNeeded)
{
if (!engineCaps->VeboxNeeded && !engineCaps->SfcNeeded)
{
engineCaps->SfcNeeded = 1;
}
/* Place Holder: need to add FurtherProcessNeeded conditions in next step*/
// Choose SFC as execution engine
UpdateExeCaps(feature, caps, engineCaps->SfcNeeded ? EngineTypeVeboxSfc : EngineTypeVebox);
featurePipe.RemoveSwFilter(feature);
params.executedFilters->AddSwFilterUnordered(feature, true, 0);
}
// Vebox only cases
else if (caps.bVebox && engineCaps->bEnabled &&
(engineCaps->VeboxNeeded || (caps.bIECP && filterID == FeatureTypeCsc)))
{
UpdateExeCaps(feature, caps, EngineTypeVebox);
featurePipe.RemoveSwFilter(feature);
params.executedFilters->AddSwFilterUnordered(feature, true, 0);
}
else if (caps.bComposite && engineCaps->RenderNeeded)
{
// use render path to implement feature.
UpdateExeCaps(feature, caps, EngineTypeRender);
if (caps.bIECP && filterID == FeatureTypeCsc)
{
AddNewFilterOnVebox(featurePipe, caps, *params.executedFilters, FeatureTypeCsc);
}
}
else
{
auto handler = m_vpInterface.GetSwFilterHandler(feature->GetFeatureType());
if (!handler)
{
VP_PUBLIC_ASSERTMESSAGE("no Feature Handle, Return Pipe Init Error");
return MOS_STATUS_INVALID_HANDLE;
}
// For feature which is force enabled on Sfc, just drop it if sfc not being used.
featurePipe.RemoveSwFilter(feature);
handler->Destory(feature);
VP_PUBLIC_NORMALMESSAGE("filter missed packets generation");
}
}
}
VP_PUBLIC_CHK_STATUS_RETURN(AddFiltersBasedOnCaps(featurePipe, caps, *params.executedFilters));
}
else
{
// goto Composition in Render
}
/* Place Holder: order pipe need to be insert in next step*/
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::GetResourceHint(SwFilterPipe& featurePipe, RESOURCE_ASSIGNMENT_HINT &hint)
{
uint32_t index = 0;
SwFilterSubPipe* inputPipe = featurePipe.GetSwFilterPrimaryPipe(index);
// only process Primary surface
VP_PUBLIC_CHK_NULL_RETURN(inputPipe);
for (auto filterID : m_featurePool)
{
SwFilter* feature = (SwFilter*)inputPipe->GetSwFilter(FeatureType(filterID));
if (feature)
{
VP_PUBLIC_CHK_STATUS_RETURN(feature->SetResourceAssignmentHint(hint));
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::SetupFilterResource(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
{
VP_FUNC_CALL();
VP_SURFACE* surfInput = nullptr;
VP_SURFACE* surfOutput = nullptr;
uint32_t index = 0;
SwFilterSubPipe* inputPipe = featurePipe.GetSwFilterPrimaryPipe(index);
if (featurePipe.IsPrimaryEmpty())
{
// Update the input feature surfaces
surfInput = featurePipe.RemoveSurface(true, index);
surfOutput = featurePipe.RemoveSurface(false, 0);
if (surfOutput)
{
// surface should be added before swFilters, since empty feature pipe will be allocated accordingly when surface being added.
VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->AddSurface(surfOutput, false, 0));
}
}
else
{
VP_PUBLIC_ASSERTMESSAGE("Output is not empty, featurePipe.IsPrimaryEmpty() = %d", featurePipe.IsPrimaryEmpty());
/* Place Holder: nest step resource manager will create intermeida surface here for surface sharing b/w packets */
}
VP_PUBLIC_CHK_STATUS_RETURN(AssignExecuteResource(caps, params));
// Place Holder for multi-Process(include FC) cases where Temp surface needed here
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::UpdateExeCaps(SwFilter* feature, VP_EXECUTE_CAPS& caps, EngineType Type)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(feature);
FeatureType featureType = feature->GetFeatureType();
if (Type == EngineTypeVeboxSfc)
{
switch (featureType)
{
case FeatureTypeCsc:
caps.bSfcCsc = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Sfc)));
break;
case FeatureTypeScaling:
caps.bSfcScaling = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Scaling, Sfc)));
break;
case FeatureTypeRotMir:
caps.bSfcRotMir = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(RotMir, Sfc)));
break;
default:
break;
}
}
if (Type == EngineTypeVebox)
{
switch (featureType)
{
case FeatureTypeDn:
caps.bDN = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Dn, Vebox)));
break;
case FeatureTypeSte:
caps.bSTE = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Ste, Vebox)));
break;
case FeatureTypeDi:
caps.bDI = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Di, Vebox)));
break;
case FeatureTypeAce:
caps.bACE = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Ace, Vebox)));
break;
case FeatureTypeTcc:
caps.bTCC = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Tcc, Vebox)));
break;
case FeatureTypeProcamp:
caps.bProcamp = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Procamp, Vebox)));
break;
case FeatureTypeCsc:
caps.bBeCSC = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Vebox)));
break;
case FeatureTypeHdr:
caps.bHDR3DLUT = 1;
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Hdr, Vebox)));
break;
default:
break;
}
}
if (Type == EngineTypeRender)
{
caps.bComposite = 1;
switch (featureType)
{
case FeatureTypeCsc:
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Csc, Render)));
break;
case FeatureTypeScaling:
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Scaling, Render)));
break;
case FeatureTypeRotMir:
feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(RotMir, Render)));
break;
default:
break;
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::AssignExecuteResource(VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
{
VP_FUNC_CALL();
VP_PUBLIC_CHK_NULL_RETURN(params.executedFilters);
VP_SURFACE *inputSurface = params.executedFilters->GetSurface(true, 0);
VP_SURFACE *outputSurface = params.executedFilters->GetSurface(false, 0);
VP_SURFACE *pastSurface = params.executedFilters->GetPastSurface(0);
VP_SURFACE *futureSurface = params.executedFilters->GetFutureSurface(0);
RESOURCE_ASSIGNMENT_HINT resHint = {};
VP_PUBLIC_CHK_STATUS_RETURN(GetResourceHint(*params.executedFilters, resHint));
VP_PUBLIC_CHK_STATUS_RETURN(m_vpInterface.GetResourceManager()->AssignExecuteResource(caps, inputSurface, outputSurface,
pastSurface, futureSurface, resHint, params.executedFilters->GetSurfacesGroup()));
return MOS_STATUS_SUCCESS;
}
bool Policy::IsVeboxSecurePathEnabled(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps)
{
VP_FUNC_CALL();
if (m_vpInterface.GetHwInterface())
{
VP_PUBLIC_ASSERTMESSAGE("No VP Interface Available");
return false;
}
if (m_vpInterface.GetHwInterface()->m_osInterface &&
m_vpInterface.GetHwInterface()->m_osInterface->osCpInterface)
{
VP_PUBLIC_ASSERTMESSAGE("No CP Interface Available");
return false;
}
MosCpInterface* cpInterface = (m_vpInterface.GetHwInterface()->m_osInterface->osCpInterface);
// Place holder: DDI can also have conditions for Kernel resource using
if (!featurePipe.GetSecureProcessFlag() && caps.bVebox && cpInterface->IsHMEnabled())
{
featurePipe.SetSecureProcessFlag(true);
return true;
}
return false;
}
MOS_STATUS Policy::BuildVeboxSecureFilters(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
{
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::ReleaseHwFilterParam(HW_FILTER_PARAMS &params)
{
VP_FUNC_CALL();
if (EngineTypeInvalid == params.Type || params.Params.empty())
{
params.Type = EngineTypeInvalid;
while (!params.Params.empty())
{
HwFilterParameter *p = params.Params.back();
params.Params.pop_back();
MOS_Delete(p);
}
m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
return MOS_STATUS_SUCCESS;
}
std::map<FeatureType, PolicyFeatureHandler*> &featureHandler =
(EngineTypeVebox == params.Type || EngineTypeVeboxSfc == params.Type) ? m_VeboxSfcFeatureHandlers : m_RenderFeatureHandlers;
params.Type = EngineTypeInvalid;
while (!params.Params.empty())
{
HwFilterParameter *p = params.Params.back();
params.Params.pop_back();
if (p)
{
auto it = featureHandler.find(p->GetFeatureType());
if (featureHandler.end() == it)
{
MOS_Delete(p);
}
else
{
it->second->ReleaseHwFeatureParameter(p);
}
}
}
m_vpInterface.GetSwFilterPipeFactory().Destory(params.executedFilters);
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::AddFiltersBasedOnCaps(
SwFilterPipe& featurePipe,
VP_EXECUTE_CAPS& caps,
SwFilterPipe& executedFilters)
{
//Create and Add CSC filter for VEBOX IECP chromasiting config
if (caps.bSFC && !caps.bBeCSC && (caps.bIECP || caps.bDI))
{
VP_PUBLIC_CHK_STATUS_RETURN(AddNewFilterOnVebox(featurePipe, caps, executedFilters, FeatureTypeCsc));
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS Policy::AddNewFilterOnVebox(
SwFilterPipe& featurePipe,
VP_EXECUTE_CAPS& caps,
SwFilterPipe& executedFilters,
FeatureType featureType)
{
PVP_SURFACE pSurfInput = featurePipe.GetSurface(true, 0);
PVP_SURFACE pSurfOutput = featurePipe.GetSurface(false, 0);
VP_PUBLIC_CHK_NULL_RETURN(pSurfInput);
VP_PUBLIC_CHK_NULL_RETURN(pSurfOutput);
auto handler = m_vpInterface.GetSwFilterHandler(featureType);
if (!handler)
{
VP_PUBLIC_ASSERTMESSAGE("no Feature Handle, Return Pipe Init Error");
return MOS_STATUS_INVALID_HANDLE;
}
SwFilter* swfilter = handler->CreateSwFilter();
VP_PUBLIC_CHK_NULL_RETURN(swfilter);
MOS_STATUS status = swfilter->Configure(pSurfInput, pSurfOutput, caps);
if (MOS_FAILED(status))
{
handler->Destory(swfilter);
VP_PUBLIC_CHK_STATUS_RETURN(status);
}
VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(swfilter, caps, EngineTypeVebox));
status = executedFilters.AddSwFilterUnordered(swfilter, true, 0);
VP_PUBLIC_CHK_STATUS_RETURN(status);
return status;
}