| /* |
| * Copyright (c) 2012-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 vphal_render_sfc_base.cpp |
| //! \brief VPHAL SFC rendering component |
| //! \details The SFC renderer supports Scaling, IEF, CSC/ColorFill and Rotation. |
| //! It's responsible for setting up HW states and generating the SFC |
| //! commands. |
| //! |
| #include "vphal_render_vebox_base.h" |
| #include "vphal_render_ief.h" |
| #include "vphal_render_sfc_base.h" |
| |
| #if __VPHAL_SFC_SUPPORTED |
| |
| //! |
| //! \brief Constants used to derive Line Buffer sizes |
| //! |
| #define SFC_CACHELINE_SIZE_IN_BYTES (512 / 8) |
| #define SFC_AVS_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL (5 * SFC_CACHELINE_SIZE_IN_BYTES / 8) |
| #define SFC_IEF_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL (1 * SFC_CACHELINE_SIZE_IN_BYTES / 4) |
| |
| //! |
| //! \brief Initialize SFC Output Surface Command parameters |
| //! \details Initialize MHW SFC Output Surface Command parameters from SFC Pipe output Surface |
| //! \param [in] pSfcPipeOutSurface |
| //! pointer to SFC Pipe output Surface |
| //! \param [out] pMhwOutSurfParams |
| //! pointer to SFC Output Surface Command parameters |
| //! \return MOS_STATUS |
| //! |
| MOS_STATUS VpHal_InitMhwOutSurfParams( |
| PVPHAL_SURFACE pSfcPipeOutSurface, |
| PMHW_SFC_OUT_SURFACE_PARAMS pMhwOutSurfParams) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| VPHAL_RENDER_CHK_NULL(pSfcPipeOutSurface); |
| VPHAL_RENDER_CHK_NULL(pMhwOutSurfParams); |
| |
| MOS_ZeroMemory(pMhwOutSurfParams, sizeof(*pMhwOutSurfParams)); |
| |
| pMhwOutSurfParams->ChromaSiting = pSfcPipeOutSurface->ChromaSiting; |
| pMhwOutSurfParams->dwWidth = pSfcPipeOutSurface->dwWidth; |
| pMhwOutSurfParams->dwHeight = pSfcPipeOutSurface->dwHeight; |
| pMhwOutSurfParams->dwPitch = pSfcPipeOutSurface->dwPitch; |
| pMhwOutSurfParams->TileType = pSfcPipeOutSurface->TileType; |
| pMhwOutSurfParams->TileModeGMM = pSfcPipeOutSurface->TileModeGMM; |
| pMhwOutSurfParams->bGMMTileEnabled = pSfcPipeOutSurface->bGMMTileEnabled; |
| pMhwOutSurfParams->pOsResource = &(pSfcPipeOutSurface->OsResource); |
| pMhwOutSurfParams->Format = pSfcPipeOutSurface->Format; |
| pMhwOutSurfParams->bCompressible = pSfcPipeOutSurface->bCompressible; |
| pMhwOutSurfParams->dwCompressionFormat = pSfcPipeOutSurface->CompressionFormat; |
| pMhwOutSurfParams->dwSurfaceXOffset = pSfcPipeOutSurface->YPlaneOffset.iXOffset; |
| pMhwOutSurfParams->dwSurfaceYOffset = pSfcPipeOutSurface->YPlaneOffset.iYOffset; |
| |
| if (pSfcPipeOutSurface->dwPitch > 0) |
| { |
| pMhwOutSurfParams->dwUYoffset = ((pSfcPipeOutSurface->UPlaneOffset.iSurfaceOffset - pSfcPipeOutSurface->YPlaneOffset.iSurfaceOffset) / pSfcPipeOutSurface->dwPitch) + pSfcPipeOutSurface->UPlaneOffset.iYOffset; |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Get SFC Rotation mode parameter |
| //! \details Get MHW SFC Rotation mode parameter |
| //! \param [in] Rotation |
| //! VPHAL roration mode parameter |
| //! \return MHW_ROTATION |
| //! |
| MHW_ROTATION VpHal_GetMhwRotationParam(VPHAL_ROTATION Rotation) |
| { |
| switch (Rotation) |
| { |
| case VPHAL_ROTATION_90: |
| return MHW_ROTATION_90; // 90 Degree Rotation |
| |
| case VPHAL_ROTATION_180: |
| return MHW_ROTATION_180; // 180 Degree Rotation |
| |
| case VPHAL_ROTATION_270: |
| return MHW_ROTATION_270; // 270 Degree Rotation |
| |
| case VPHAL_MIRROR_HORIZONTAL: |
| return MHW_MIRROR_HORIZONTAL; // Horizontal Mirror |
| |
| case VPHAL_MIRROR_VERTICAL: |
| return MHW_MIRROR_VERTICAL; // Vertical Mirror |
| |
| case VPHAL_ROTATE_90_MIRROR_VERTICAL: |
| return MHW_ROTATION_270; // 270 Degree rotation and Horizontal Mirror |
| |
| case VPHAL_ROTATE_90_MIRROR_HORIZONTAL: |
| return MHW_ROTATION_90; // 90 Degree rotation and Horizontal Mirror |
| |
| default: |
| case VPHAL_ROTATION_IDENTITY: |
| return MHW_ROTATION_IDENTITY; |
| } |
| } |
| |
| //! |
| //! \brief Get SFC Scaling mode parameter |
| //! \details Get MHW SFC Scaling mode parameter |
| //! \param [in] Scaling mode |
| //! VPHAL Scaling mode parameter |
| //! \return MHW_SCALING_MODE |
| //! |
| MHW_SCALING_MODE VpHal_GetMhwScalingModeParam(VPHAL_SCALING_MODE ScalingMode) |
| { |
| switch (ScalingMode) |
| { |
| case VPHAL_SCALING_NEAREST: |
| return MHW_SCALING_NEAREST; // Nearest interpolation |
| |
| case VPHAL_SCALING_BILINEAR: |
| return MHW_SCALING_BILINEAR; // Bilinear interpolation |
| |
| case VPHAL_SCALING_AVS: |
| case VPHAL_SCALING_ADV_QUALITY: |
| default: |
| return MHW_SCALING_AVS; |
| } |
| } |
| |
| bool VphalSfcState::IsFormatMMCSupported( |
| MOS_FORMAT Format) |
| { |
| // Check if Sample Format is supported |
| if ((Format != Format_NV12) && |
| (Format != Format_UYVY) && |
| (Format != Format_YUYV)) |
| { |
| VPHAL_RENDER_NORMALMESSAGE("Unsupported Format '0x%08x' for SFC MMC.", Format); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| VphalSfcState::VphalSfcState( |
| PMOS_INTERFACE osInterface, |
| PRENDERHAL_INTERFACE renderHal, |
| PMHW_SFC_INTERFACE sfcInterface) |
| { |
| VPHAL_RENDER_ASSERT(osInterface); |
| VPHAL_RENDER_ASSERT(renderHal); |
| VPHAL_RENDER_ASSERT(sfcInterface); |
| |
| m_renderHal = renderHal; |
| m_sfcInterface = sfcInterface; |
| m_osInterface = osInterface; |
| |
| // Allocate AVS state |
| VpHal_RndrCommonInitAVSParams( |
| &m_AvsParameters, |
| POLYPHASE_Y_COEFFICIENT_TABLE_SIZE_G9, |
| POLYPHASE_UV_COEFFICIENT_TABLE_SIZE_G9); |
| } |
| |
| VphalSfcState::~VphalSfcState() |
| { |
| VpHal_RndrCommonDestroyAVSParams(&m_AvsParameters); |
| MOS_FreeMemAndSetNull(m_renderData.SfcStateParams); |
| } |
| |
| bool VphalSfcState::IsOutputCapable( |
| bool isColorFill, |
| PVPHAL_SURFACE src, |
| PVPHAL_SURFACE renderTarget) |
| { |
| bool isOutputCapable = false; |
| |
| VPHAL_RENDER_NORMALMESSAGE( |
| "isColorFill %d, \ |
| src->rcDst.top %d, \ |
| src->rcDst.left %d, \ |
| renderTarget->TileType %d, \ |
| renderTarget->Format %d", |
| isColorFill, |
| src->rcDst.top, |
| src->rcDst.left, |
| renderTarget->TileType, |
| renderTarget->Format); |
| |
| // H/W does not support ColorFill, the (OffsetX, OffsetY) |
| // of scaled region not being (0, 0) or the tile type not being |
| // Tile_Y on NV12/P010/P016 output surface. Disable SFC even if other |
| // features are supported. |
| if ((isColorFill || |
| src->rcDst.top != 0 || |
| src->rcDst.left != 0 || |
| renderTarget->TileType != MOS_TILE_Y) && |
| (renderTarget->Format == Format_NV12 || |
| renderTarget->Format == Format_P010 || |
| renderTarget->Format == Format_P016)) |
| { |
| isOutputCapable = false; |
| } |
| else |
| { |
| isOutputCapable = true; |
| } |
| |
| return isOutputCapable; |
| } |
| |
| void VphalSfcState::AdjustBoundary( |
| PVPHAL_SURFACE pSurface, |
| uint32_t* pdwSurfaceWidth, |
| uint32_t* pdwSurfaceHeight) |
| { |
| uint32_t dwVeboxHeight; |
| uint32_t dwVeboxWidth; |
| uint32_t dwVeboxBottom; |
| uint32_t dwVeboxRight; |
| MEDIA_WA_TABLE *pWaTable = nullptr; |
| |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(m_sfcInterface); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(m_osInterface); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pSurface); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pdwSurfaceWidth); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pdwSurfaceHeight); |
| |
| pWaTable = m_osInterface->pfnGetWaTable(m_osInterface); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pWaTable); |
| |
| if (MEDIA_IS_WA(pWaTable, WaVeboxInputHeight16Aligned) && |
| (pSurface->Format == Format_NV12 || |
| pSurface->Format == Format_P010 || |
| pSurface->Format == Format_P016)) |
| { |
| m_sfcInterface->m_veHeightAlignment = 16; |
| } |
| else |
| { |
| m_sfcInterface->m_veHeightAlignment = MHW_SFC_VE_HEIGHT_ALIGN; |
| } |
| |
| // For the VEBOX output to SFC, the width is multiple of 16 and height |
| // is multiple of 4 |
| dwVeboxHeight = pSurface->dwHeight; |
| dwVeboxWidth = pSurface->dwWidth; |
| dwVeboxBottom = (uint32_t)pSurface->rcMaxSrc.bottom; |
| dwVeboxRight = (uint32_t)pSurface->rcMaxSrc.right; |
| |
| if(pSurface->bDirectionalScalar) |
| { |
| dwVeboxHeight *= 2; |
| dwVeboxWidth *= 2; |
| dwVeboxBottom *= 2; |
| dwVeboxRight *= 2; |
| } |
| |
| *pdwSurfaceHeight = MOS_ALIGN_CEIL( |
| MOS_MIN(dwVeboxHeight, MOS_MAX(dwVeboxBottom, MHW_VEBOX_MIN_HEIGHT)), |
| m_sfcInterface->m_veHeightAlignment); |
| *pdwSurfaceWidth = MOS_ALIGN_CEIL( |
| MOS_MIN(dwVeboxWidth, MOS_MAX(dwVeboxRight, MHW_VEBOX_MIN_WIDTH)), |
| m_sfcInterface->m_veWidthAlignment); |
| |
| finish: |
| return; |
| } |
| |
| bool VphalSfcState::IsOutputPipeSfcFeasible( |
| PCVPHAL_RENDER_PARAMS pcRenderParams, |
| PVPHAL_SURFACE pSrcSurface, |
| PVPHAL_SURFACE pRenderTarget) |
| { |
| VPHAL_RENDER_NORMALMESSAGE( |
| "IsDisabled %d, \ |
| uDstCount %d, \ |
| Rotation %d, \ |
| pTarget[0]->TileType %d, \ |
| IsFormatSupported %d, \ |
| InputFormat %d, \ |
| OutputFormat %d, \ |
| pCompAlpha %p, \ |
| pDeinterlaceParams %p, \ |
| bQueryVariance %d", |
| IsDisabled(), |
| pcRenderParams->uDstCount, |
| pSrcSurface->Rotation, |
| pcRenderParams->pTarget[0]->TileType, |
| IsFormatSupported(pSrcSurface, pcRenderParams->pTarget[0], pcRenderParams->pCompAlpha), |
| pSrcSurface->Format, |
| pcRenderParams->pTarget[0]->Format, |
| pcRenderParams->pCompAlpha, |
| pSrcSurface->pDeinterlaceParams, |
| pSrcSurface->bQueryVariance); |
| |
| //! |
| //! \brief SFC can be the output pipe when the following conditions are all met |
| //! 1. User feature keys value "SFC Disable" is false |
| //! 2. Single render target only |
| //! 3. Rotation disabled or ONLY Rotation enabled when the SFC output is Y-tile |
| //! 4. i/o format is supported by SFC, taking into account the alpha fill info |
| //! 5. Comp DI(ARGB/ABGR) is disabled |
| //! 6. Variance Query is disabled |
| //! |
| if (IsDisabled() == false && |
| pcRenderParams->uDstCount == 1 && |
| (pSrcSurface->Rotation == VPHAL_ROTATION_IDENTITY || |
| (pSrcSurface->Rotation <= VPHAL_ROTATION_270 && |
| pcRenderParams->pTarget[0]->TileType == MOS_TILE_Y)) && |
| IsFormatSupported(pSrcSurface, pcRenderParams->pTarget[0], pcRenderParams->pCompAlpha) && |
| (pSrcSurface->pDeinterlaceParams == nullptr || |
| (pSrcSurface->Format != Format_A8R8G8B8 && pSrcSurface->Format != Format_A8B8G8R8)) && |
| pSrcSurface->bQueryVariance == false) |
| { |
| // For platforms with VEBOX disabled but procamp enabled, go Render path |
| if (MEDIA_IS_SKU(m_renderHal->pSkuTable, FtrDisableVEBoxFeatures) && pSrcSurface->pProcampParams != nullptr) |
| { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| return false; |
| } |
| |
| VPHAL_OUTPUT_PIPE_MODE VphalSfcState::GetOutputPipe( |
| PVPHAL_SURFACE pSrc, |
| PVPHAL_SURFACE pRenderTarget, |
| PCVPHAL_RENDER_PARAMS pcRenderParams) |
| { |
| float fScaleX; |
| float fScaleY; |
| uint32_t dwSurfaceWidth; |
| uint32_t dwSurfaceHeight; |
| VPHAL_OUTPUT_PIPE_MODE OutputPipe; |
| bool bColorFill; |
| uint16_t wWidthAlignUnit; |
| uint16_t wHeightAlignUnit; |
| uint32_t dwSourceRegionWidth; |
| uint32_t dwSourceRegionHeight; |
| uint32_t dwOutputRegionWidth; |
| uint32_t dwOutputRegionHeight; |
| uint32_t dwSfcMaxWidth; |
| uint32_t dwSfcMaxHeight; |
| uint32_t dwSfcMinWidth; |
| uint32_t dwSfcMinHeight; |
| |
| OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP; |
| |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(m_sfcInterface); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrc); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderTarget); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pcRenderParams); |
| |
| dwSfcMaxWidth = m_sfcInterface->m_maxWidth; |
| dwSfcMaxHeight = m_sfcInterface->m_maxHeight; |
| dwSfcMinWidth = m_sfcInterface->m_minWidth; |
| dwSfcMinHeight = m_sfcInterface->m_minHeight; |
| wWidthAlignUnit = 1; |
| wHeightAlignUnit = 1; |
| |
| // Check if the feature can be supported by SFC output pipe |
| if (!IsOutputPipeSfcFeasible(pcRenderParams, pSrc, pRenderTarget)) |
| { |
| VPHAL_RENDER_NORMALMESSAGE("Feature or surface format not supported by SFC Pipe."); |
| OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP; |
| return OutputPipe; |
| } |
| |
| // Get the SFC input surface size from Vebox |
| AdjustBoundary( |
| pSrc, |
| &dwSurfaceWidth, |
| &dwSurfaceHeight); |
| |
| // Apply alignment restriction to the source and scaled regions. |
| switch(pRenderTarget->Format) |
| { |
| case Format_NV12: |
| wWidthAlignUnit = 2; |
| wHeightAlignUnit = 2; |
| break; |
| case Format_YUY2: |
| case Format_UYVY: |
| wWidthAlignUnit = 2; |
| break; |
| default: |
| break; |
| } |
| |
| // Region of the input frame which needs to be processed by SFC |
| dwSourceRegionHeight = MOS_ALIGN_FLOOR( |
| MOS_MIN((uint32_t)(pSrc->rcSrc.bottom - pSrc->rcSrc.top), dwSurfaceHeight), |
| wHeightAlignUnit); |
| dwSourceRegionWidth = MOS_ALIGN_FLOOR( |
| MOS_MIN((uint32_t)(pSrc->rcSrc.right - pSrc->rcSrc.left), dwSurfaceWidth), |
| wWidthAlignUnit); |
| |
| // Size of the Output Region over the Render Target |
| dwOutputRegionHeight = MOS_ALIGN_CEIL( |
| (uint32_t)(pSrc->rcDst.bottom - pSrc->rcDst.top), |
| wHeightAlignUnit); |
| dwOutputRegionWidth = MOS_ALIGN_CEIL( |
| (uint32_t)(pSrc->rcDst.right - pSrc->rcDst.left), |
| wWidthAlignUnit); |
| |
| // SFC i/o width and height should fall into the range of [128, 4K] |
| 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, dwSfcMinHeight, dwSfcMaxHeight) || |
| OUT_OF_BOUNDS(pRenderTarget->dwWidth, dwSfcMinWidth, dwSfcMaxWidth) || |
| OUT_OF_BOUNDS(pRenderTarget->dwHeight, dwSfcMinHeight, dwSfcMaxHeight)) |
| { |
| VPHAL_RENDER_NORMALMESSAGE("Surface dimensions not supported by SFC Pipe."); |
| OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP; |
| return OutputPipe; |
| } |
| |
| // Size of the Output Region over the Render Target |
| dwOutputRegionHeight = MOS_MIN(dwOutputRegionHeight, pRenderTarget->dwHeight); |
| dwOutputRegionWidth = MOS_MIN(dwOutputRegionWidth, pRenderTarget->dwWidth); |
| |
| // Calculate the scaling ratio |
| // Both source region and scaled region are pre-rotated |
| if (pSrc->Rotation == VPHAL_ROTATION_IDENTITY || |
| pSrc->Rotation == VPHAL_ROTATION_180 || |
| pSrc->Rotation == VPHAL_MIRROR_HORIZONTAL || |
| pSrc->Rotation == VPHAL_MIRROR_VERTICAL) |
| { |
| fScaleX = (float)dwOutputRegionWidth / (float)dwSourceRegionWidth; |
| fScaleY = (float)dwOutputRegionHeight / (float)dwSourceRegionHeight; |
| } |
| else |
| { |
| // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 || VPHAL_ROTATE_90_MIRROR_VERTICAL || VPHAL_ROTATE_90_MIRROR_HORIZONTAL |
| fScaleX = (float)dwOutputRegionHeight / (float)dwSourceRegionWidth; |
| fScaleY = (float)dwOutputRegionWidth / (float)dwSourceRegionHeight; |
| } |
| |
| // SFC scaling range is [0.125, 8] for both X and Y direction. |
| if ((fScaleX < 0.125F) || (fScaleX > 8.0F) || |
| (fScaleY < 0.125F) || (fScaleY > 8.0F)) |
| { |
| VPHAL_RENDER_NORMALMESSAGE("Scaling factor not supported by SFC Pipe."); |
| OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP; |
| return OutputPipe; |
| } |
| |
| if (MEDIA_IS_WA(m_renderHal->pWaTable, WaDisableSFCSrcCrop) && |
| dwSurfaceHeight > 1120 && |
| (((pSrc->rcSrc.left > 0) || (dwSurfaceWidth - pSrc->rcSrc.right > 0)) || |
| ((pSrc->rcSrc.bottom > 1120) && (pSrc->rcSrc.bottom < (int32_t)dwSurfaceHeight)) || |
| ((pSrc->rcSrc.top > 1120) && (pSrc->rcSrc.top < (int32_t)dwSurfaceHeight)) || |
| (pSrc->rcSrc.bottom < (int32_t)dwSurfaceHeight))) |
| { |
| VPHAL_RENDER_NORMALMESSAGE("Fallback to comp path as SW WA for SFC Cropping TDR."); |
| OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP; |
| return OutputPipe; |
| } |
| |
| // if ScalingPreference == Composition, switch to use composition path |
| // This flag can be set by app. |
| if (pSrc->ScalingPreference == VPHAL_SCALING_PREFER_COMP) |
| { |
| VPHAL_RENDER_NORMALMESSAGE("DDI set ScalingPreference to Composition to use render for scaling."); |
| OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP; |
| return OutputPipe; |
| } |
| |
| bColorFill = (pcRenderParams->pColorFillParams && |
| (!RECT1_CONTAINS_RECT2(pSrc->rcDst, pRenderTarget->rcDst))) ? |
| true : false; |
| |
| if (IsOutputCapable(bColorFill, pSrc, pRenderTarget)) |
| { |
| OutputPipe = VPHAL_OUTPUT_PIPE_MODE_SFC; |
| } |
| else |
| { |
| OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP; |
| } |
| |
| finish: |
| return OutputPipe; |
| } |
| |
| void VphalSfcState::DetermineCscParams( |
| PVPHAL_SURFACE src, |
| PVPHAL_SURFACE renderTarget) |
| { |
| // Determine if CSC is required in SFC pipe |
| if (IS_RGB_CSPACE(src->ColorSpace)) |
| { |
| if (IS_YUV_CSPACE(renderTarget->ColorSpace)) |
| { |
| m_renderData.SfcInputCspace = renderTarget->ColorSpace; |
| } |
| else if (MEDIA_IS_HDCONTENT(src->dwWidth, src->dwHeight)) |
| { |
| m_renderData.SfcInputCspace = CSpace_BT709; |
| } |
| else |
| { |
| m_renderData.SfcInputCspace = CSpace_BT601; |
| } |
| } |
| else |
| { |
| m_renderData.SfcInputCspace = src->ColorSpace; |
| } |
| |
| if (m_renderData.SfcInputCspace != renderTarget->ColorSpace) |
| { |
| m_renderData.bCSC = true; |
| } |
| } |
| |
| void VphalSfcState::DetermineInputFormat( |
| PVPHAL_SURFACE src, |
| PVPHAL_VEBOX_RENDER_DATA veboxRenderData) |
| { |
| // Determine SFC input surface format |
| if (IS_RGB_FORMAT(src->Format)) |
| { |
| m_renderData.SfcInputFormat = Format_AYUV; |
| } |
| else if (veboxRenderData->bDeinterlace) |
| { |
| m_renderData.SfcInputFormat = Format_YUY2; |
| } |
| else |
| { |
| m_renderData.SfcInputFormat = src->Format; |
| } |
| } |
| |
| void VphalSfcState::SetRenderingFlags( |
| PVPHAL_COLORFILL_PARAMS pColorFillParams, |
| PVPHAL_ALPHA_PARAMS pAlphaParams, |
| PVPHAL_SURFACE pSrc, |
| PVPHAL_SURFACE pRenderTarget, |
| PVPHAL_VEBOX_RENDER_DATA pRenderData) |
| { |
| PRENDERHAL_INTERFACE pRenderHal; |
| float fScaleX; |
| float fScaleY; |
| uint32_t dwSurfaceWidth; |
| uint32_t dwSurfaceHeight; |
| uint16_t wWidthAlignUnit; |
| uint16_t wHeightAlignUnit; |
| uint32_t dwSourceRegionWidth; |
| uint32_t dwSourceRegionHeight; |
| uint32_t dwOutputRegionWidth; |
| uint32_t dwOutputRegionHeight; |
| uint32_t dwVeboxBottom; |
| uint32_t dwVeboxRight; |
| VPHAL_COLORPACK dstColorPack; |
| |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrc); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderTarget); |
| |
| pRenderHal = m_renderHal; |
| wWidthAlignUnit = 1; |
| wHeightAlignUnit = 1; |
| dwVeboxBottom = (uint32_t)pSrc->rcSrc.bottom; |
| dwVeboxRight = (uint32_t)pSrc->rcSrc.right; |
| dstColorPack = VpHal_GetSurfaceColorPack(pRenderTarget->Format); |
| |
| // Get the SFC input surface size from Vebox |
| AdjustBoundary( |
| pSrc, |
| &dwSurfaceWidth, |
| &dwSurfaceHeight); |
| |
| // Apply alignment restriction to the source and scaled regions. |
| switch (dstColorPack) |
| { |
| case VPHAL_COLORPACK_420: |
| wWidthAlignUnit = 2; |
| wHeightAlignUnit = 2; |
| break; |
| case VPHAL_COLORPACK_422: |
| wWidthAlignUnit = 2; |
| break; |
| default: |
| break; |
| } |
| |
| if(pSrc->bDirectionalScalar) |
| { |
| dwVeboxBottom *= 2; |
| dwVeboxRight *= 2; |
| } |
| |
| // Region of the input frame which needs to be processed by SFC |
| dwSourceRegionHeight = MOS_ALIGN_FLOOR( |
| MOS_MIN((uint32_t)(dwVeboxBottom - pSrc->rcSrc.top), dwSurfaceHeight), |
| wHeightAlignUnit); |
| dwSourceRegionWidth = MOS_ALIGN_FLOOR( |
| MOS_MIN((uint32_t)(dwVeboxRight - pSrc->rcSrc.left), dwSurfaceWidth), |
| wWidthAlignUnit); |
| |
| // Size of the Output Region over the Render Target |
| dwOutputRegionHeight = MOS_ALIGN_CEIL( |
| MOS_MIN((uint32_t)(pSrc->rcDst.bottom - pSrc->rcDst.top), pRenderTarget->dwHeight), |
| wHeightAlignUnit); |
| dwOutputRegionWidth = MOS_ALIGN_CEIL( |
| MOS_MIN((uint32_t)(pSrc->rcDst.right - pSrc->rcDst.left), pRenderTarget->dwWidth), |
| wWidthAlignUnit); |
| |
| // Calculate the scaling ratio |
| // Both source region and scaled region are pre-rotated |
| if (pSrc->Rotation == VPHAL_ROTATION_IDENTITY || |
| pSrc->Rotation == VPHAL_ROTATION_180 || |
| pSrc->Rotation == VPHAL_MIRROR_HORIZONTAL || |
| pSrc->Rotation == VPHAL_MIRROR_VERTICAL) |
| { |
| fScaleX = (float)dwOutputRegionWidth / (float)dwSourceRegionWidth; |
| fScaleY = (float)dwOutputRegionHeight / (float)dwSourceRegionHeight; |
| } |
| else |
| { |
| // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 || VPHAL_ROTATE_90_MIRROR_VERTICAL || VPHAL_ROTATE_90_MIRROR_HORIZONTAL |
| fScaleX = (float)dwOutputRegionHeight / (float)dwSourceRegionWidth; |
| fScaleY = (float)dwOutputRegionWidth / (float)dwSourceRegionHeight; |
| } |
| |
| // Set RenderData flags |
| m_renderData.bScaling = ((fScaleX == 1.0F) && (fScaleY == 1.0F)) ? |
| false : true; |
| |
| m_renderData.bColorFill = (pColorFillParams && pSrc->InterlacedScalingType == ISCALING_NONE && |
| (!RECT1_CONTAINS_RECT2(pSrc->rcDst, pRenderTarget->rcDst))) ? |
| true : false; |
| |
| m_renderData.bIEF = (pSrc->pIEFParams && |
| pSrc->pIEFParams->bEnabled && |
| (pSrc->pIEFParams->fIEFFactor > 0.0f)) ? |
| true : false; |
| |
| // Determine if CSC is required in SFC pipe |
| DetermineCscParams( |
| pSrc, |
| pRenderTarget); |
| |
| // Determine SFC input surface format |
| DetermineInputFormat( |
| pSrc, |
| pRenderData); |
| |
| m_renderData.fScaleX = fScaleX; |
| m_renderData.fScaleY = fScaleY; |
| m_renderData.pColorFillParams = m_renderData.bColorFill ? pColorFillParams : nullptr; |
| m_renderData.pAvsParams = &m_AvsParameters; |
| m_renderData.pAlphaParams = pAlphaParams; |
| m_renderData.pSfcPipeOutSurface = pRenderTarget; |
| m_renderData.SfcRotation = pSrc->Rotation; |
| m_renderData.SfcScalingMode = pSrc->ScalingMode; |
| |
| // In SFC, we have a lot of HW restrictions on Chroma Sitting Programming. |
| // So prevent any invalid input for SFC to avoid HW problems. |
| // Prevent invalid input for input surface and format. |
| m_renderData.SfcSrcChromaSiting = pSrc->ChromaSiting; |
| if (m_renderData.SfcSrcChromaSiting == MHW_CHROMA_SITING_NONE) |
| { |
| m_renderData.SfcSrcChromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER); |
| } |
| switch (VpHal_GetSurfaceColorPack(m_renderData.SfcInputFormat)) |
| { |
| case VPHAL_COLORPACK_422: |
| m_renderData.SfcSrcChromaSiting = (m_renderData.SfcSrcChromaSiting & 0x7) | CHROMA_SITING_VERT_TOP; |
| break; |
| case VPHAL_COLORPACK_444: |
| m_renderData.SfcSrcChromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP; |
| break; |
| default: |
| break; |
| } |
| // Prevent invalid input for output surface and format |
| if (pRenderTarget->ChromaSiting == MHW_CHROMA_SITING_NONE) |
| { |
| pRenderTarget->ChromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER); |
| } |
| switch (dstColorPack) |
| { |
| case VPHAL_COLORPACK_422: |
| pRenderTarget->ChromaSiting = (pRenderTarget->ChromaSiting & 0x7) | CHROMA_SITING_VERT_TOP; |
| break; |
| case VPHAL_COLORPACK_444: |
| pRenderTarget->ChromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP; |
| break; |
| default: |
| break; |
| } |
| |
| m_renderData.bForcePolyPhaseCoefs = VpHal_IsChromaUpSamplingNeeded(pSrc, pRenderTarget); |
| |
| // Cache Render Target pointer |
| pRenderData->pRenderTarget = pRenderTarget; |
| |
| VPHAL_RENDER_NORMALMESSAGE( |
| "RenderData: bScaling %d, bColorFill %d, bIEF %d, SfcInputFormat %d, SfcRotation %d, SfcScalingMode %d, SfcSrcChromaSiting %d", |
| m_renderData.bScaling, |
| m_renderData.bColorFill, |
| m_renderData.bIEF, |
| m_renderData.SfcInputFormat, |
| m_renderData.SfcRotation, |
| m_renderData.SfcScalingMode, |
| m_renderData.SfcSrcChromaSiting); |
| |
| finish: |
| return; |
| } |
| |
| bool VphalSfcState::IsFormatSupported( |
| PVPHAL_SURFACE pSrcSurface, |
| PVPHAL_SURFACE pOutSurface, |
| PVPHAL_ALPHA_PARAMS pAlphaParams) |
| { |
| // Init to false for in case the input parameters are nullptr |
| bool ret = false; |
| |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrcSurface); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(pOutSurface); |
| |
| // Default to true |
| ret = true; |
| |
| // Check if Input Format is supported |
| if (!IsInputFormatSupported(pSrcSurface)) |
| { |
| VPHAL_RENDER_NORMALMESSAGE("Unsupported Source Format '0x%08x' for SFC.", pSrcSurface->Format); |
| ret = false; |
| return ret; |
| } |
| |
| // SFC can not support fp16 output. HDR path is the only way to handle any fp16 output. |
| // Before entering into HDR path, it is possible that we need to use SFC to do P010->ARGB10. |
| // As for SFC is needed or not, we use bHDRSfc to decide. |
| if (pOutSurface->Format == Format_A16R16G16B16F || |
| pOutSurface->Format == Format_A16B16G16R16F) |
| { |
| ret = false; |
| return ret; |
| } |
| |
| // Check if Output Format is supported |
| if (!IsOutputFormatSupported(pOutSurface)) |
| { |
| ret = false; |
| return ret; |
| } |
| |
| // Check if the input/output combination is supported, given certain alpha fill mode. |
| // So far SFC only supports filling constant alpha. |
| if (pAlphaParams && |
| pAlphaParams->AlphaMode == VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM) |
| { |
| if ((pOutSurface->Format == Format_A8R8G8B8 || |
| pOutSurface->Format == Format_A8B8G8R8 || |
| pOutSurface->Format == Format_R10G10B10A2 || |
| pOutSurface->Format == Format_B10G10R10A2 || |
| pOutSurface->Format == Format_Y410 || |
| pOutSurface->Format == Format_Y416 || |
| pOutSurface->Format == Format_AYUV) && |
| (pSrcSurface->Format == Format_A8B8G8R8 || |
| pSrcSurface->Format == Format_A8R8G8B8 || |
| pSrcSurface->Format == Format_Y410 || |
| pSrcSurface->Format == Format_Y416 || |
| pSrcSurface->Format == Format_AYUV)) |
| { |
| ret = false; |
| } |
| } |
| |
| finish: |
| return ret; |
| } |
| |
| void VphalSfcState::FreeResources() |
| { |
| // Free AVS Line Buffer surface for SFC |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_AVSLineBufferSurface.OsResource); |
| |
| // Free IEF Line Buffer surface for SFC |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_IEFLineBufferSurface.OsResource); |
| |
| // Free SFD Line Buffer surface for SFC |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_SFDLineBufferSurface.OsResource); |
| |
| return; |
| } |
| |
| MOS_STATUS VphalSfcState::AllocateResources() |
| { |
| MOS_STATUS eStatus; |
| uint32_t dwWidth; |
| uint32_t dwHeight; |
| uint32_t dwSize; |
| bool bAllocated; |
| PMHW_SFC_STATE_PARAMS pSfcStateParams; |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| bAllocated = false; |
| pSfcStateParams = m_renderData.SfcStateParams; |
| |
| VPHAL_RENDER_CHK_NULL(pSfcStateParams); |
| |
| // Allocate AVS Line Buffer surface---------------------------------------------- |
| dwWidth = 1; |
| dwHeight = pSfcStateParams->dwInputFrameHeight * SFC_AVS_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL; |
| dwSize = dwWidth * dwHeight; |
| |
| VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface( |
| m_osInterface, |
| &m_AVSLineBufferSurface, |
| "SfcAVSLineBufferSurface", |
| Format_Buffer, |
| MOS_GFXRES_BUFFER, |
| MOS_TILE_LINEAR, |
| dwSize, |
| 1, |
| false, |
| MOS_MMC_DISABLED, |
| &bAllocated)); |
| |
| // Allocate IEF Line Buffer surface---------------------------------------------- |
| dwWidth = 1; |
| dwHeight = pSfcStateParams->dwScaledRegionHeight * SFC_IEF_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL; |
| dwSize = dwWidth * dwHeight; |
| |
| VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface( |
| m_osInterface, |
| &m_IEFLineBufferSurface, |
| "SfcIEFLineBufferSurface", |
| Format_Buffer, |
| MOS_GFXRES_BUFFER, |
| MOS_TILE_LINEAR, |
| dwSize, |
| 1, |
| false, |
| MOS_MMC_DISABLED, |
| &bAllocated)); |
| |
| // Allocate SFD Line Buffer surface---------------------------------------------- |
| if (NEED_SFD_LINE_BUFFER(pSfcStateParams->dwScaledRegionHeight)) |
| { |
| dwSize = SFD_LINE_BUFFER_SIZE(pSfcStateParams->dwScaledRegionHeight); |
| |
| VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface( |
| m_osInterface, |
| &m_SFDLineBufferSurface, |
| "SfcSFDLineBufferSurface", |
| Format_Buffer, |
| MOS_GFXRES_BUFFER, |
| MOS_TILE_LINEAR, |
| dwSize, |
| 1, |
| false, |
| MOS_MMC_DISABLED, |
| &bAllocated)); |
| } |
| |
| finish: |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| FreeResources(); |
| } |
| |
| return eStatus; |
| } |
| |
| void VphalSfcState::GetOutputWidthHeightAlignUnit( |
| MOS_FORMAT outputFormat, |
| uint16_t &widthAlignUnit, |
| uint16_t &heightAlignUnit, |
| bool isInterlacedScaling) |
| { |
| widthAlignUnit = 1; |
| heightAlignUnit = 1; |
| |
| switch (VpHal_GetSurfaceColorPack(outputFormat)) |
| { |
| case VPHAL_COLORPACK_420: |
| widthAlignUnit = 2; |
| heightAlignUnit = 2; |
| break; |
| case VPHAL_COLORPACK_422: |
| widthAlignUnit = 2; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| void VphalSfcState::SetSfcStateInputOrderingMode( |
| PVPHAL_VEBOX_RENDER_DATA veboxRenderData, |
| PMHW_SFC_STATE_PARAMS sfcStateParams) |
| { |
| sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VE_4x8; |
| } |
| |
| MOS_STATUS VphalSfcState::SetSfcStateParams( |
| PVPHAL_VEBOX_RENDER_DATA pRenderData, |
| PVPHAL_SURFACE pSrcSurface, |
| PVPHAL_SURFACE pOutSurface) |
| { |
| MOS_STATUS eStatus; |
| PMOS_INTERFACE pOsInterface; |
| PMHW_SFC_STATE_PARAMS pSfcStateParams; |
| PVPHAL_ALPHA_PARAMS pAlphaParams; |
| VPHAL_COLOR_SAMPLE_8 Src; |
| VPHAL_CSPACE src_cspace, dst_cspace; |
| uint16_t wOutputWidthAlignUnit; |
| uint16_t wOutputHeightAlignUnit; |
| uint16_t wInputWidthAlignUnit; |
| uint16_t wInputHeightAlignUnit; |
| uint32_t dwSurfaceWidth; |
| uint32_t dwSurfaceHeight; |
| uint32_t dwVeboxBottom; |
| uint32_t dwVeboxRight; |
| VPHAL_GET_SURFACE_INFO Info; |
| VPHAL_COLORPACK dstColorPack; |
| |
| VPHAL_RENDER_CHK_NULL(pSrcSurface); |
| VPHAL_RENDER_CHK_NULL(pOutSurface); |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| pOsInterface = m_osInterface; |
| pSfcStateParams = m_renderData.SfcStateParams; |
| pAlphaParams = m_renderData.pAlphaParams; |
| wOutputWidthAlignUnit = 1; |
| wOutputHeightAlignUnit = 1; |
| wInputWidthAlignUnit = 1; |
| wInputHeightAlignUnit = 1; |
| dwVeboxBottom = (uint32_t)pSrcSurface->rcSrc.bottom; |
| dwVeboxRight = (uint32_t)pSrcSurface->rcSrc.right; |
| dstColorPack = VpHal_GetSurfaceColorPack(pOutSurface->Format); |
| |
| VPHAL_RENDER_CHK_NULL(pSfcStateParams); |
| MOS_ZeroMemory(pSfcStateParams, sizeof(*pSfcStateParams)); |
| |
| pSfcStateParams->sfcPipeMode = MEDIASTATE_SFC_PIPE_VE_TO_SFC; |
| |
| // Setup General params |
| // Set chroma subsampling type according to the Vebox output, but |
| // when Vebox is bypassed, set it according to the source surface format. |
| if (pRenderData->bIECP) |
| { |
| pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444; |
| m_renderData.SfcSrcChromaSiting = MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_TOP; |
| pSfcStateParams->b8tapChromafiltering = true; |
| } |
| else if (pRenderData->bDeinterlace) |
| { |
| pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H; |
| pSfcStateParams->b8tapChromafiltering = false; |
| } |
| else |
| { |
| if (m_renderData.SfcInputFormat == Format_NV12 || |
| (m_renderData.SfcInputFormat == Format_P010) || |
| (m_renderData.SfcInputFormat == Format_P016)) |
| { |
| pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_420; |
| pSfcStateParams->b8tapChromafiltering = false; |
| } |
| else if (VpHal_GetSurfaceColorPack(m_renderData.SfcInputFormat) == VPHAL_COLORPACK_422) |
| { |
| pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H; |
| pSfcStateParams->b8tapChromafiltering = false; |
| } |
| else if (VpHal_GetSurfaceColorPack(m_renderData.SfcInputFormat) == VPHAL_COLORPACK_444) |
| { |
| pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444; |
| pSfcStateParams->b8tapChromafiltering = true; |
| } |
| else |
| { |
| pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_400; |
| pSfcStateParams->b8tapChromafiltering = false; |
| } |
| } |
| |
| // Default to Horizontal Left, Vertical Top |
| pSfcStateParams->dwChromaDownSamplingVerticalCoef = (pOutSurface->ChromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? |
| MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : |
| MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8; |
| pSfcStateParams->dwChromaDownSamplingHorizontalCoef = (pOutSurface->ChromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? |
| MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : |
| MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8; |
| |
| // Set the Pre-AVS chroma downsampling param according to SFC i/o chroma subsampling type |
| switch (pSfcStateParams->dwInputChromaSubSampling) |
| { |
| case MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444: |
| if (dstColorPack == VPHAL_COLORPACK_420) |
| { |
| pSfcStateParams->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_444TO420; |
| } |
| else if (dstColorPack == VPHAL_COLORPACK_422) |
| { |
| pSfcStateParams->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_444TO422; |
| } |
| break; |
| |
| case MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H: |
| if (dstColorPack == VPHAL_COLORPACK_420) |
| { |
| pSfcStateParams->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_422TO420; |
| } |
| break; |
| |
| default: |
| pSfcStateParams->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_DISABLED; |
| break; |
| } |
| |
| VPHAL_RENDER_NORMALMESSAGE("SfcStateParams: dwInputChromaSubSampling %d, b8tapChromafiltering %d, dwChromaDownSamplingMode %d.", |
| pSfcStateParams->dwInputChromaSubSampling, |
| pSfcStateParams->b8tapChromafiltering, |
| pSfcStateParams->dwChromaDownSamplingMode); |
| |
| SetSfcStateInputOrderingMode(pRenderData, pSfcStateParams); |
| |
| pSfcStateParams->OutputFrameFormat = pOutSurface->Format; |
| |
| pSfcStateParams->fChromaSubSamplingXSiteOffset = 0.0F; |
| pSfcStateParams->fChromaSubSamplingYSiteOffset = 0.0F; |
| |
| // Setup all parameters in SFC_STATE related to Scaling and AVS |
| pSfcStateParams->dwAVSFilterMode = (m_renderData.SfcScalingMode == VPHAL_SCALING_BILINEAR) ? |
| MEDIASTATE_SFC_AVS_FILTER_BILINEAR : |
| MEDIASTATE_SFC_AVS_FILTER_8x8; |
| |
| // Get the SFC input surface size from Vebox |
| AdjustBoundary( |
| pSrcSurface, |
| &dwSurfaceWidth, |
| &dwSurfaceHeight); |
| |
| // This should be set to the height and width of the frame streaming from Vebox |
| pSfcStateParams->dwInputFrameHeight = dwSurfaceHeight; |
| pSfcStateParams->dwInputFrameWidth = dwSurfaceWidth; |
| |
| // Apply alignment restriction to the Region of the output frame. |
| GetOutputWidthHeightAlignUnit( |
| pSfcStateParams->OutputFrameFormat, |
| wOutputWidthAlignUnit, |
| wOutputHeightAlignUnit, |
| pSrcSurface->bInterlacedScaling); |
| |
| // Apply alignment restriction to Region of the input frame. |
| GetInputWidthHeightAlignUnit( |
| m_renderData.SfcInputFormat, |
| pSfcStateParams->OutputFrameFormat, |
| wInputWidthAlignUnit, |
| wInputHeightAlignUnit); |
| |
| if(pSrcSurface->bDirectionalScalar) |
| { |
| dwVeboxBottom *= 2; |
| dwVeboxRight *= 2; |
| } |
| |
| // This should be set to the height and width of the Render Target |
| pSfcStateParams->dwOutputFrameHeight = MOS_ALIGN_CEIL(pOutSurface->dwHeight, wOutputHeightAlignUnit); |
| pSfcStateParams->dwOutputFrameWidth = MOS_ALIGN_CEIL(pOutSurface->dwWidth, wOutputWidthAlignUnit); |
| |
| // Region of the input frame which needs to be processed by SFC |
| pSfcStateParams->dwSourceRegionVerticalOffset = MOS_ALIGN_CEIL((uint32_t)pSrcSurface->rcSrc.top, wInputHeightAlignUnit); |
| pSfcStateParams->dwSourceRegionHorizontalOffset = MOS_ALIGN_CEIL((uint32_t)pSrcSurface->rcSrc.left, wInputWidthAlignUnit); |
| pSfcStateParams->dwSourceRegionHeight = MOS_ALIGN_FLOOR( |
| MOS_MIN((uint32_t)(dwVeboxBottom - pSrcSurface->rcSrc.top), pSfcStateParams->dwInputFrameHeight), |
| wInputHeightAlignUnit); |
| pSfcStateParams->dwSourceRegionWidth = MOS_ALIGN_FLOOR( |
| MOS_MIN((uint32_t)(dwVeboxRight - pSrcSurface->rcSrc.left), pSfcStateParams->dwInputFrameWidth), |
| wInputWidthAlignUnit); |
| |
| // Size of the Scaled Region over the Render Target |
| pSfcStateParams->dwScaledRegionHeight = MOS_ALIGN_CEIL(MOS_UF_ROUND(m_renderData.fScaleY * pSfcStateParams->dwSourceRegionHeight), wOutputHeightAlignUnit); |
| pSfcStateParams->dwScaledRegionWidth = MOS_ALIGN_CEIL(MOS_UF_ROUND(m_renderData.fScaleX * pSfcStateParams->dwSourceRegionWidth), wOutputWidthAlignUnit); |
| |
| // Scaled region is pre-rotated. Adjust its width and height with those of the output frame |
| if (m_renderData.SfcRotation == VPHAL_ROTATION_IDENTITY || |
| m_renderData.SfcRotation == VPHAL_ROTATION_180 || |
| m_renderData.SfcRotation == VPHAL_MIRROR_HORIZONTAL || |
| m_renderData.SfcRotation == VPHAL_MIRROR_VERTICAL) |
| { |
| pSfcStateParams->dwScaledRegionHeight = MOS_MIN(pSfcStateParams->dwScaledRegionHeight, pSfcStateParams->dwOutputFrameHeight); |
| pSfcStateParams->dwScaledRegionWidth = MOS_MIN(pSfcStateParams->dwScaledRegionWidth, pSfcStateParams->dwOutputFrameWidth); |
| } |
| else |
| { |
| pSfcStateParams->dwScaledRegionHeight = MOS_MIN(pSfcStateParams->dwScaledRegionHeight, pSfcStateParams->dwOutputFrameWidth); |
| pSfcStateParams->dwScaledRegionWidth = MOS_MIN(pSfcStateParams->dwScaledRegionWidth, pSfcStateParams->dwOutputFrameHeight); |
| } |
| |
| // Refine the Scaling ratios in the X and Y direction. SFC output Scaled size may be changed based on the restriction of SFC alignment. |
| // The scaling ratio could be changed and not equal to the fScaleX/Y. |
| // Driver must make sure that the scaling ratio should be matched with the output/input size before send to HW |
| pSfcStateParams->fAVSXScalingRatio = (float)pSfcStateParams->dwScaledRegionWidth / (float)pSfcStateParams->dwSourceRegionWidth; |
| pSfcStateParams->fAVSYScalingRatio = (float)pSfcStateParams->dwScaledRegionHeight / (float)pSfcStateParams->dwSourceRegionHeight; |
| |
| pSfcStateParams->dwScaledRegionVerticalOffset = MOS_ALIGN_FLOOR((uint32_t)pSrcSurface->rcDst.top, wOutputHeightAlignUnit); |
| pSfcStateParams->dwScaledRegionHorizontalOffset = MOS_ALIGN_FLOOR((uint32_t)pSrcSurface->rcDst.left, wOutputWidthAlignUnit); |
| |
| // Enable Adaptive Filtering for YUV input only, if it is being upscaled |
| // in either direction. We must check for this before clamping the SF. |
| if (IS_YUV_FORMAT(m_renderData.SfcInputFormat) && |
| (m_renderData.fScaleX > 1.0F || |
| m_renderData.fScaleY > 1.0F)) |
| { |
| pSfcStateParams->bBypassXAdaptiveFilter = false; |
| pSfcStateParams->bBypassYAdaptiveFilter = false; |
| } |
| else |
| { |
| pSfcStateParams->bBypassXAdaptiveFilter = true; |
| pSfcStateParams->bBypassYAdaptiveFilter = true; |
| } |
| |
| if (IS_RGB_FORMAT(m_renderData.SfcInputFormat) && |
| pSfcStateParams->b8tapChromafiltering == true) |
| { |
| pSfcStateParams->bRGBAdaptive = true; |
| } |
| else |
| { |
| pSfcStateParams->bRGBAdaptive = false; |
| } |
| |
| pSfcStateParams->bAVSChromaUpsamplingEnable = (m_renderData.bScaling || m_renderData.bForcePolyPhaseCoefs); |
| |
| // Rotation params |
| if (m_renderData.SfcRotation <= VPHAL_ROTATION_270) |
| { |
| // Rotation only |
| pSfcStateParams->RotationMode = VpHal_GetMhwRotationParam(m_renderData.SfcRotation); |
| pSfcStateParams->bMirrorEnable = false; |
| } |
| else if (m_renderData.SfcRotation <= VPHAL_MIRROR_VERTICAL) |
| { |
| // Mirror only |
| pSfcStateParams->dwMirrorType = VpHal_GetMhwRotationParam(m_renderData.SfcRotation) - 4; |
| pSfcStateParams->RotationMode = MHW_ROTATION_IDENTITY; |
| pSfcStateParams->bMirrorEnable = true; |
| } |
| else |
| { |
| // Rotation + Mirror |
| pSfcStateParams->dwMirrorType = MHW_MIRROR_HORIZONTAL; |
| pSfcStateParams->RotationMode = VpHal_GetMhwRotationParam(m_renderData.SfcRotation); |
| pSfcStateParams->bMirrorEnable = true; |
| } |
| |
| VPHAL_RENDER_NORMALMESSAGE("SfcStateParams: dwMirrorType %d, RotationMode %d, bMirrorEnable %d.", |
| pSfcStateParams->dwMirrorType, |
| pSfcStateParams->RotationMode, |
| pSfcStateParams->bMirrorEnable); |
| |
| // ColorFill params |
| if (m_renderData.bColorFill) |
| { |
| pSfcStateParams->bColorFillEnable = true; |
| |
| Src.dwValue = m_renderData.pColorFillParams->Color; |
| src_cspace = m_renderData.pColorFillParams->CSpace; |
| dst_cspace = pOutSurface->ColorSpace; |
| |
| // Convert BG color only if not done so before. CSC is expensive! |
| if ((m_colorFillColorSrc.dwValue != Src.dwValue) || |
| (m_colorFillSrcCspace != src_cspace) || |
| (m_colorFillRTCspace != dst_cspace)) |
| { |
| // Clean history Dst BG Color if hit unsupported format |
| if (!VpHal_CSC_8(&m_colorFillColorDst, &Src, src_cspace, dst_cspace)) |
| { |
| MOS_ZeroMemory(&m_colorFillColorDst, sizeof(m_colorFillColorDst)); |
| } |
| |
| // store the values for next iteration |
| m_colorFillColorSrc = Src; |
| m_colorFillSrcCspace = src_cspace; |
| m_colorFillRTCspace = dst_cspace; |
| } |
| |
| if (IS_YUV_FORMAT(pOutSurface->Format) || IS_ALPHA_YUV_FORMAT(pOutSurface->Format)) |
| { |
| pSfcStateParams->fColorFillYRPixel = (float)m_colorFillColorDst.Y / 255.0F; |
| pSfcStateParams->fColorFillUGPixel = (float)m_colorFillColorDst.U / 255.0F; |
| pSfcStateParams->fColorFillVBPixel = (float)m_colorFillColorDst.V / 255.0F; |
| } |
| else |
| { |
| // Swap the channel here because HW only natively supports XBGR output |
| if ((pOutSurface->Format == Format_A8R8G8B8) || (pOutSurface->Format == Format_X8R8G8B8) || (pOutSurface->Format == Format_R10G10B10A2)) |
| { |
| pSfcStateParams->fColorFillYRPixel = (float)m_colorFillColorDst.B / 255.0F; |
| pSfcStateParams->fColorFillUGPixel = (float)m_colorFillColorDst.G / 255.0F; |
| pSfcStateParams->fColorFillVBPixel = (float)m_colorFillColorDst.R / 255.0F; |
| } |
| else |
| { |
| pSfcStateParams->fColorFillYRPixel = (float)m_colorFillColorDst.R / 255.0F; |
| pSfcStateParams->fColorFillUGPixel = (float)m_colorFillColorDst.G / 255.0F; |
| pSfcStateParams->fColorFillVBPixel = (float)m_colorFillColorDst.B / 255.0F; |
| } |
| } |
| pSfcStateParams->fColorFillAPixel = (float)Src.A / 255.0F; |
| } |
| |
| if (pAlphaParams) |
| { |
| switch (pAlphaParams->AlphaMode) |
| { |
| case VPHAL_ALPHA_FILL_MODE_NONE: |
| if (pOutSurface->Format == Format_A8R8G8B8 || |
| pOutSurface->Format == Format_A8B8G8R8 || |
| pOutSurface->Format == Format_R10G10B10A2 || |
| pOutSurface->Format == Format_B10G10R10A2 || |
| pOutSurface->Format == Format_AYUV || |
| pOutSurface->Format == Format_Y410 || |
| pOutSurface->Format == Format_Y416) |
| { |
| pSfcStateParams->fAlphaPixel = pAlphaParams->fAlpha; |
| pSfcStateParams->fColorFillAPixel = pAlphaParams->fAlpha; |
| } |
| else |
| { |
| pSfcStateParams->fAlphaPixel = 1.0F; |
| } |
| break; |
| |
| case VPHAL_ALPHA_FILL_MODE_BACKGROUND: |
| pSfcStateParams->fAlphaPixel = m_renderData.bColorFill ? |
| pSfcStateParams->fColorFillAPixel : 1.0F; |
| break; |
| |
| case VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM: |
| case VPHAL_ALPHA_FILL_MODE_OPAQUE: |
| default: |
| pSfcStateParams->fAlphaPixel = 1.0F; |
| pSfcStateParams->fColorFillAPixel = 1.0F; |
| } |
| } |
| else |
| { |
| pSfcStateParams->fAlphaPixel = 1.0F; |
| } |
| |
| // CSC params |
| pSfcStateParams->bCSCEnable = m_renderData.bCSC; |
| |
| // ARGB8,ABGR10 output format need to enable swap |
| if (pOutSurface->Format == Format_X8R8G8B8 || |
| pOutSurface->Format == Format_A8R8G8B8 || |
| pOutSurface->Format == Format_R10G10B10A2) |
| { |
| pSfcStateParams->bRGBASwapEnable = true; |
| } |
| else |
| { |
| pSfcStateParams->bRGBASwapEnable = false; |
| } |
| |
| if (IS_RGB_CSPACE(pSrcSurface->ColorSpace)) |
| { |
| pSfcStateParams->bInputColorSpace = true; |
| } |
| else |
| { |
| pSfcStateParams->bInputColorSpace = false; |
| } |
| |
| VPHAL_RENDER_NORMALMESSAGE("SfcStateParams: bCSCEnable %d, bRGBASwapEnable %d, bMirrorEnable %d.", |
| pSfcStateParams->bCSCEnable, |
| pSfcStateParams->bRGBASwapEnable, |
| pSfcStateParams->bMirrorEnable); |
| |
| // Set MMC status |
| VPHAL_RENDER_CHK_STATUS(SetSfcMmcStatus( |
| pRenderData, |
| pOutSurface, |
| pSfcStateParams)); |
| |
| VPHAL_RENDER_CHK_STATUS(AllocateResources()); |
| |
| // Set OS resources used by SFC state |
| pSfcStateParams->pOsResAVSLineBuffer = &m_AVSLineBufferSurface.OsResource; |
| pSfcStateParams->pOsResIEFLineBuffer = &m_IEFLineBufferSurface.OsResource; |
| pSfcStateParams->pOsResOutputSurface = &pOutSurface->OsResource; |
| |
| MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO)); |
| |
| Info.S3dChannel = pOutSurface->Channel; |
| Info.ArraySlice = m_currentChannel; |
| |
| VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo( |
| pOsInterface, |
| &Info, |
| pOutSurface)); |
| |
| pSfcStateParams->dwOutputSurfaceOffset = pOutSurface->YPlaneOffset.iSurfaceOffset; |
| pSfcStateParams->wOutputSurfaceUXOffset = (uint16_t) pOutSurface->UPlaneOffset.iXOffset; |
| pSfcStateParams->wOutputSurfaceUYOffset = (uint16_t) pOutSurface->UPlaneOffset.iYOffset; |
| pSfcStateParams->wOutputSurfaceVXOffset = (uint16_t) pOutSurface->VPlaneOffset.iXOffset; |
| pSfcStateParams->wOutputSurfaceVYOffset = (uint16_t) pOutSurface->VPlaneOffset.iYOffset; |
| |
| finish: |
| return eStatus; |
| } |
| |
| MOS_STATUS VphalSfcState::SetSfcMmcStatus( |
| PVPHAL_VEBOX_RENDER_DATA renderData, |
| PVPHAL_SURFACE outSurface, |
| PMHW_SFC_STATE_PARAMS sfcStateParams) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (IsFormatMMCSupported(outSurface->Format) && // SFC output MMC only support several format |
| (renderData->Component == COMPONENT_VPreP) && // SFC output MMC only enable in Vprep |
| (renderData->bEnableMMC == true) && |
| (outSurface->bCompressible == true) && |
| (outSurface->TileType == MOS_TILE_Y)) |
| { |
| if ((m_renderData.fScaleX >= 0.5F) && |
| (m_renderData.fScaleY >= 0.5F)) |
| { |
| sfcStateParams->bMMCEnable = true; |
| sfcStateParams->MMCMode = MOS_MMC_HORIZONTAL; |
| } |
| else if ((m_renderData.fScaleX < 0.5F) && |
| (m_renderData.fScaleY < 0.5F)) |
| { |
| sfcStateParams->bMMCEnable = true; |
| sfcStateParams->MMCMode = MOS_MMC_VERTICAL; |
| } |
| else |
| { |
| sfcStateParams->bMMCEnable = false; |
| sfcStateParams->MMCMode = MOS_MMC_DISABLED; |
| } |
| |
| VPHAL_RENDER_NORMALMESSAGE("SfcStateParams: bMMCEnable %d, MMCMode %d.", |
| sfcStateParams->bMMCEnable, |
| sfcStateParams->MMCMode); |
| |
| // Set mmc status output surface for output surface |
| m_osInterface->pfnSetMemoryCompressionMode(m_osInterface, &outSurface->OsResource, MOS_MEMCOMP_STATE(sfcStateParams->MMCMode)); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS VphalSfcState::SetAvsStateParams() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| PMHW_SFC_AVS_STATE pMhwAvsState = nullptr; |
| |
| MHW_SCALING_MODE scalingMode = MHW_SCALING_AVS; |
| bool bUse8x8Filter = false; |
| |
| VPHAL_RENDER_CHK_NULL(m_sfcInterface); |
| |
| pMhwAvsState = &m_avsState.AvsStateParams; |
| MOS_ZeroMemory(pMhwAvsState, sizeof(MHW_SFC_AVS_STATE)); |
| |
| if (m_renderData.bScaling || |
| m_renderData.bForcePolyPhaseCoefs) |
| { |
| pMhwAvsState->dwInputHorizontalSiting = (m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8); |
| |
| pMhwAvsState->dwInputVerticalSitting = (m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8); |
| |
| if (m_renderData.SfcSrcChromaSiting == MHW_CHROMA_SITING_NONE) |
| { |
| m_renderData.SfcSrcChromaSiting = MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_TOP; |
| |
| if (VpHal_GetSurfaceColorPack(m_renderData.SfcInputFormat) == VPHAL_COLORPACK_420) // For 420, default is Left & Center, else default is Left & Top |
| { |
| pMhwAvsState->dwInputVerticalSitting = SFC_AVS_INPUT_SITING_COEF_4_OVER_8; |
| } |
| } |
| |
| m_renderData.pAvsParams->bForcePolyPhaseCoefs = m_renderData.bForcePolyPhaseCoefs; |
| |
| scalingMode = VpHal_GetMhwScalingModeParam(m_renderData.SfcScalingMode); |
| VPHAL_RENDER_CHK_STATUS(m_sfcInterface->SetSfcAVSScalingMode(scalingMode)); |
| |
| if (m_renderData.SfcStateParams) |
| { |
| pMhwAvsState->dwAVSFilterMode = m_renderData.SfcStateParams->dwAVSFilterMode; |
| } |
| else |
| { |
| pMhwAvsState->dwAVSFilterMode = MEDIASTATE_SFC_AVS_FILTER_8x8; |
| } |
| |
| if (pMhwAvsState->dwAVSFilterMode == MEDIASTATE_SFC_AVS_FILTER_8x8) |
| { |
| bUse8x8Filter = true; |
| } |
| |
| VPHAL_RENDER_CHK_STATUS(m_sfcInterface->SetSfcSamplerTable( |
| &m_avsState.LumaCoeffs, |
| &m_avsState.ChromaCoeffs, |
| m_renderData.pAvsParams, |
| m_renderData.SfcInputFormat, |
| m_renderData.fScaleX, |
| m_renderData.fScaleY, |
| m_renderData.SfcSrcChromaSiting, |
| bUse8x8Filter, |
| 0, |
| 0)); |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| void VphalSfcState::SetIefStateCscParams( |
| PMHW_SFC_STATE_PARAMS sfcStateParams, |
| PMHW_SFC_IEF_STATE_PARAMS iefStateParams) |
| { |
| |
| // Setup CSC params |
| if (m_renderData.bCSC) |
| { |
| sfcStateParams->bCSCEnable = true; |
| iefStateParams->bCSCEnable = true; |
| |
| // Calculate matrix if not done so before. CSC is expensive! |
| if ((m_cscInputCspace != m_renderData.SfcInputCspace) || |
| (m_cscRTCspace != m_renderData.pSfcPipeOutSurface->ColorSpace)) |
| { |
| // Get the matrix to use for conversion |
| VpHal_GetCscMatrix( |
| m_renderData.SfcInputCspace, |
| m_renderData.pSfcPipeOutSurface->ColorSpace, |
| m_cscCoeff, |
| m_cscInOffset, |
| m_cscOutOffset); |
| |
| // Store it for next BLT |
| m_cscInputCspace = m_renderData.SfcInputCspace; |
| m_cscRTCspace = m_renderData.pSfcPipeOutSurface->ColorSpace; |
| } |
| |
| // Copy the values into IEF Params |
| iefStateParams->pfCscCoeff = m_cscCoeff; |
| iefStateParams->pfCscInOffset = m_cscInOffset; |
| iefStateParams->pfCscOutOffset = m_cscOutOffset; |
| } |
| |
| } |
| |
| void VphalSfcState::SetIefStateParams( |
| PVPHAL_VEBOX_RENDER_DATA veboxRenderData, |
| PMHW_SFC_STATE_PARAMS sfcStateParams, |
| PVPHAL_SURFACE inputSurface) |
| { |
| PMHW_SFC_IEF_STATE_PARAMS iefStateParams; |
| |
| MOS_UNUSED(veboxRenderData); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(sfcStateParams); |
| VPHAL_RENDER_CHK_NULL_NO_STATUS(inputSurface); |
| |
| iefStateParams = &m_renderData.IEFStateParams; |
| MOS_ZeroMemory(iefStateParams, sizeof(*iefStateParams)); |
| |
| // Setup IEF and STE params |
| if (m_renderData.bIEF) |
| { |
| Ief ief( |
| inputSurface); |
| |
| ief.SetHwState( |
| sfcStateParams, |
| iefStateParams); |
| } // end of setup IEF and STE params |
| |
| // Setup CSC params |
| SetIefStateCscParams( |
| sfcStateParams, |
| iefStateParams); |
| |
| finish: |
| return; |
| } |
| |
| MOS_STATUS VphalSfcState::UpdateRenderingFlags( |
| PVPHAL_SURFACE pSrcSurface, |
| PVPHAL_SURFACE pOutSurface, |
| PVPHAL_VEBOX_RENDER_DATA pRenderData) |
| { |
| MOS_STATUS eStatus; |
| |
| MOS_UNUSED(pSrcSurface); |
| MOS_UNUSED(pOutSurface); |
| MOS_UNUSED(pRenderData); |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS VphalSfcState::SetupSfcState( |
| PVPHAL_SURFACE pSrcSurface, |
| PVPHAL_SURFACE pOutSurface, |
| PVPHAL_VEBOX_RENDER_DATA pRenderData) |
| { |
| MOS_STATUS eStatus; |
| PMOS_INTERFACE pOsInterface; |
| PRENDERHAL_INTERFACE pRenderHal; |
| |
| VPHAL_RENDER_CHK_NULL(pSrcSurface); |
| VPHAL_RENDER_CHK_NULL(pOutSurface); |
| VPHAL_RENDER_CHK_NULL(pRenderData); |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| pOsInterface = m_osInterface; |
| pRenderHal = m_renderHal; |
| |
| // Update SFC rendering flags if any |
| VPHAL_RENDER_CHK_STATUS(UpdateRenderingFlags( |
| pSrcSurface, |
| pOutSurface, |
| pRenderData)); |
| |
| // Setup params related to SFC_STATE |
| VPHAL_RENDER_CHK_STATUS(SetSfcStateParams( |
| pRenderData, |
| pSrcSurface, |
| pOutSurface)); |
| |
| // Setup params related to SFC_AVS_STATE |
| VPHAL_RENDER_CHK_STATUS(SetAvsStateParams()); |
| |
| // Setup params related to SFC_IEF_STATE |
| if (m_renderData.bIEF || |
| m_renderData.bCSC) |
| { |
| SetIefStateParams( |
| pRenderData, |
| m_renderData.SfcStateParams, |
| pSrcSurface); |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| MOS_STATUS VphalSfcState::SendSfcCmd( |
| PVPHAL_VEBOX_RENDER_DATA pRenderData, |
| PMOS_COMMAND_BUFFER pCmdBuffer) |
| { |
| PMHW_SFC_INTERFACE pSfcInterface; |
| MHW_SFC_LOCK_PARAMS SfcLockParams; |
| MOS_STATUS eStatus; |
| MHW_SFC_OUT_SURFACE_PARAMS OutSurfaceParam; |
| |
| VPHAL_RENDER_CHK_NULL(m_sfcInterface); |
| VPHAL_RENDER_CHK_NULL(m_osInterface); |
| VPHAL_RENDER_CHK_NULL(pRenderData); |
| VPHAL_RENDER_CHK_NULL(pCmdBuffer); |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| pSfcInterface = m_sfcInterface; |
| |
| // Ensure VEBOX can write |
| m_osInterface->pfnSyncOnResource( |
| m_osInterface, |
| &m_renderData.pSfcPipeOutSurface->OsResource, |
| MOS_GPU_CONTEXT_VEBOX, |
| true); |
| |
| if (m_renderData.pSfcPipeOutSurface->bOverlay) |
| { |
| m_osInterface->pfnSyncOnOverlayResource( |
| m_osInterface, |
| &m_renderData.pSfcPipeOutSurface->OsResource, |
| MOS_GPU_CONTEXT_VEBOX); |
| } |
| |
| // Setup params for SFC Lock command |
| SfcLockParams.sfcPipeMode = MhwSfcInterface::SFC_PIPE_MODE_VEBOX; |
| SfcLockParams.bOutputToMemory = (pRenderData->bDeinterlace || pRenderData->bDenoise); |
| |
| // Send SFC_LOCK command to acquire SFC pipe for Vebox |
| VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcLock( |
| pCmdBuffer, |
| &SfcLockParams)); |
| |
| VPHAL_RENDER_CHK_STATUS(VpHal_InitMhwOutSurfParams( |
| m_renderData.pSfcPipeOutSurface, |
| &OutSurfaceParam)); |
| |
| // Send SFC MMCD cmd |
| VPHAL_RENDER_CHK_STATUS(RenderSfcMmcCMD( |
| pSfcInterface, |
| m_renderHal->pMhwMiInterface, |
| m_osInterface, |
| &OutSurfaceParam, |
| pCmdBuffer)); |
| |
| // Send SFC_STATE command |
| VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcState( |
| pCmdBuffer, |
| m_renderData.SfcStateParams, |
| &OutSurfaceParam)); |
| |
| // Send SFC_AVS_STATE command |
| VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcAvsState( |
| pCmdBuffer, |
| &m_avsState.AvsStateParams)); |
| |
| if (m_renderData.bScaling || |
| m_renderData.bForcePolyPhaseCoefs) |
| { |
| |
| // Send SFC_AVS_LUMA_TABLE command |
| VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcAvsLumaTable( |
| pCmdBuffer, |
| &m_avsState.LumaCoeffs)); |
| |
| // Send SFC_AVS_CHROMA_TABLE command |
| VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcAvsChromaTable( |
| pCmdBuffer, |
| &m_avsState.ChromaCoeffs)); |
| } |
| |
| // Send SFC_IEF_STATE command |
| if (m_renderData.bIEF || m_renderData.bCSC) |
| { |
| VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcIefState( |
| pCmdBuffer, |
| &m_renderData.IEFStateParams)); |
| } |
| |
| // Send SFC_FRAME_START command to start processing a frame |
| VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcFrameStart( |
| pCmdBuffer, |
| MhwSfcInterface::SFC_PIPE_MODE_VEBOX)); |
| |
| finish: |
| return eStatus; |
| } |
| |
| #endif // __VPHAL_SFC_SUPPORTED |