| /* |
| * Copyright (c) 2014-2018, Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| //! |
| //! \file mhw_sfc_g10_X.cpp |
| //! \brief Constructs sfc commands on Gen10-based platforms |
| //! \details Each client facing function both creates a HW command and adds |
| //! that command to a command or batch buffer. |
| //! |
| |
| #include "mhw_sfc.h" |
| #include "mhw_sfc_g10_X.h" |
| |
| MOS_STATUS MhwSfcInterfaceG10::AddSfcState( |
| PMOS_COMMAND_BUFFER pCmdBuffer, |
| PMHW_SFC_STATE_PARAMS pSfcStateParams, |
| PMHW_SFC_OUT_SURFACE_PARAMS pOutSurface) |
| { |
| PMOS_INTERFACE pOsInterface; |
| bool bHalfPitchForChroma; |
| bool bInterleaveChroma; |
| uint16_t wUXOffset; |
| uint16_t wUYOffset; |
| uint16_t wVXOffset; |
| uint16_t wVYOffset; |
| MHW_RESOURCE_PARAMS ResourceParams; |
| MEDIA_WA_TABLE * pWaTable = nullptr; |
| mhw_sfc_g10_X::SFC_STATE_CMD cmd; |
| MHW_MEMORY_OBJECT_CONTROL_PARAMS outputSurfCtrl; |
| |
| MHW_CHK_NULL_RETURN(pCmdBuffer); |
| MHW_CHK_NULL_RETURN(pSfcStateParams); |
| MHW_CHK_NULL_RETURN(pOutSurface); |
| |
| pOsInterface = m_osInterface; |
| |
| MHW_CHK_NULL_RETURN(pOsInterface); |
| pWaTable = pOsInterface->pfnGetWaTable(pOsInterface); |
| MHW_CHK_NULL_RETURN(pWaTable); |
| |
| bHalfPitchForChroma = false; |
| bInterleaveChroma = false; |
| wUXOffset = 0; |
| wUYOffset = 0; |
| wVXOffset = 0; |
| wVYOffset = 0; |
| |
| outputSurfCtrl.Value = m_outputSurfCtrl.Value; |
| if (pOsInterface->osCpInterface && pOsInterface->osCpInterface->IsHMEnabled()) |
| { |
| outputSurfCtrl.Value = pOsInterface->pfnCachePolicyGetMemoryObject( |
| MOS_MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface_PartialEncSurface, |
| pOsInterface->pfnGetGmmClientContext(pOsInterface)).DwordValue; |
| } |
| |
| // Check input/output size |
| MHW_ASSERT(pSfcStateParams->dwInputFrameWidth >= MHW_SFC_MIN_WIDTH); |
| MHW_ASSERT(pSfcStateParams->dwInputFrameHeight >= MHW_SFC_MIN_HEIGHT); |
| MHW_ASSERT(pSfcStateParams->dwOutputFrameWidth <= MHW_SFC_MAX_WIDTH); |
| MHW_ASSERT(pSfcStateParams->dwOutputFrameHeight <= MHW_SFC_MAX_HEIGHT); |
| |
| cmd.DW1.SfcPipeMode = pSfcStateParams->sfcPipeMode; |
| cmd.DW1.SfcInputChromaSubSampling = pSfcStateParams->dwInputChromaSubSampling; |
| cmd.DW1.VdVeInputOrderingMode = pSfcStateParams->dwVDVEInputOrderingMode; |
| |
| // Set DW2 |
| cmd.DW2.InputFrameResolutionWidth = pSfcStateParams->dwInputFrameWidth - 1; |
| cmd.DW2.InputFrameResolutionHeight = pSfcStateParams->dwInputFrameHeight - 1; |
| |
| switch (pSfcStateParams->OutputFrameFormat) |
| { |
| case Format_AYUV: //AYUV 4:4:4 (8:8:8:8 MSB-A:Y:U:V) |
| cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_AYUV; |
| break; |
| case Format_X8R8G8B8: |
| case Format_A8R8G8B8: |
| case Format_X8B8G8R8: |
| case Format_A8B8G8R8: |
| cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_A8B8G8R8; |
| break; |
| case Format_R10G10B10A2: |
| case Format_B10G10R10A2: |
| cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_A2R10G10B10; |
| break; |
| case Format_R5G6B5: |
| cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_R5G6B5; |
| break; |
| case Format_NV12: |
| cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_NV12; |
| bInterleaveChroma = true; |
| wUYOffset = (uint16_t)pOutSurface->dwHeight; |
| break; |
| case Format_YUY2: |
| cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_YUYV; |
| break; |
| case Format_UYVY: |
| cmd.DW3.OutputSurfaceFormatType = cmd.OUTPUT_SURFACE_FORMAT_TYPE_UYVY; |
| break; |
| default: |
| MHW_ASSERTMESSAGE("Unknown Output Format."); |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| // RGBASwapEnable is true when the OutputSurfaceFormatType is set as A8B8G8R8 for X8R8G8B8 and A8R8G8B8 output, |
| // the OutputSurfaceFormatType is set as A2R10G10B10 for R10G10B10A2 output, |
| cmd.DW3.RgbaChannelSwapEnable = pSfcStateParams->bRGBASwapEnable; |
| // Set DW4 |
| cmd.DW4.IefEnable = pSfcStateParams->bIEFEnable; |
| cmd.DW4.SkinToneTunedIefEnable = pSfcStateParams->bSkinToneTunedIEFEnable; |
| cmd.DW4.AvsFilterMode = pSfcStateParams->dwAVSFilterMode; |
| cmd.DW4.AdaptiveFilterForAllChannels = (pSfcStateParams->dwAVSFilterMode == cmd.AVS_FILTER_MODE_8X8POLY_PHASEFILTERBILINEAR_ADAPTIVE) ? true : false; |
| cmd.DW4.AvsScalingEnable = ((pSfcStateParams->fAVSXScalingRatio == 1.0F) && |
| (pSfcStateParams->fAVSYScalingRatio == 1.0F)) ? false : true; |
| |
| cmd.DW4.BypassYAdaptiveFiltering = pSfcStateParams->bBypassYAdaptiveFilter; |
| cmd.DW4.BypassXAdaptiveFiltering = pSfcStateParams->bBypassXAdaptiveFilter; |
| cmd.DW4.ChromaUpsamplingEnable = pSfcStateParams->bAVSChromaUpsamplingEnable; |
| cmd.DW4.RotationMode = pSfcStateParams->RotationMode; |
| cmd.DW4.ColorFillEnable = pSfcStateParams->bColorFillEnable; |
| cmd.DW4.CscEnable = pSfcStateParams->bCSCEnable; |
| |
| // Set DW5, DW6, DW7, DW8, DW9 |
| cmd.DW5.SourceRegionWidth = pSfcStateParams->dwSourceRegionWidth - 1; |
| cmd.DW5.SourceRegionHeight = pSfcStateParams->dwSourceRegionHeight - 1; |
| cmd.DW6.SourceRegionHorizontalOffset = pSfcStateParams->dwSourceRegionHorizontalOffset; |
| cmd.DW6.SourceRegionVerticalOffset = pSfcStateParams->dwSourceRegionVerticalOffset; |
| cmd.DW7.OutputFrameWidth = pSfcStateParams->dwOutputFrameWidth + pOutSurface->dwSurfaceXOffset - 1; |
| cmd.DW7.OutputFrameHeight = pSfcStateParams->dwOutputFrameHeight + pOutSurface->dwSurfaceYOffset - 1; |
| cmd.DW8.ScaledRegionSizeWidth = pSfcStateParams->dwScaledRegionWidth - 1; |
| cmd.DW8.ScaledRegionSizeHeight = pSfcStateParams->dwScaledRegionHeight - 1; |
| cmd.DW9.ScaledRegionHorizontalOffset = pSfcStateParams->dwScaledRegionHorizontalOffset + pOutSurface->dwSurfaceXOffset; |
| cmd.DW9.ScaledRegionVerticalOffset = pSfcStateParams->dwScaledRegionVerticalOffset + pOutSurface->dwSurfaceYOffset; |
| |
| // Vertical line issue for SFC 270 degree rotation & NV12 output |
| // HW requires Scaled Region Size Width < Output Frame Width && Scaled Region Size Height < Output Frame Height. |
| // HW Design team recommends to program both Output Frame Width/Height to the maximum value of both for the new SW WA. |
| if (MEDIA_IS_WA(pWaTable, WaSFC270DegreeRotation) && |
| cmd.DW4.RotationMode == MHW_ROTATION_270 && |
| cmd.DW3.OutputSurfaceFormatType == cmd.OUTPUT_SURFACE_FORMAT_TYPE_NV12) |
| { |
| MHW_NORMALMESSAGE("SW WA vertical line issue for SFC 270 degree rotation & NV12 output."); |
| MHW_NORMALMESSAGE("SFC_STATE before SW WA: OutputFrameWidth = %d, OutputFrameHeight = %d, ScaledRegionSizeWidth = %d, ScaledRegionSizeHeight = %d.", |
| cmd.DW7.OutputFrameWidth, cmd.DW7.OutputFrameHeight, |
| cmd.DW8.ScaledRegionSizeWidth, cmd.DW8.ScaledRegionSizeHeight); |
| if (cmd.DW7.OutputFrameWidth > cmd.DW7.OutputFrameHeight) |
| { |
| cmd.DW7.OutputFrameHeight = cmd.DW7.OutputFrameWidth; |
| } |
| else |
| { |
| cmd.DW7.OutputFrameWidth = cmd.DW7.OutputFrameHeight; |
| } |
| MHW_NORMALMESSAGE("SFC_STATE after SW WA: OutputFrameWidth = %d, OutputFrameHeight = %d, ScaledRegionSizeWidth = %d, ScaledRegionSizeHeight = %d.", |
| cmd.DW7.OutputFrameWidth, cmd.DW7.OutputFrameHeight, |
| cmd.DW8.ScaledRegionSizeWidth, cmd.DW8.ScaledRegionSizeHeight); |
| } |
| |
| // Set DW10 |
| cmd.DW10.GrayBarPixelUG = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fColorFillUGPixel * 1024.0F), 0, 1023); // U10 |
| cmd.DW10.GrayBarPixelYR = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fColorFillYRPixel * 1024.0F), 0, 1023); // U10 |
| |
| // Set DW11 |
| cmd.DW11.GrayBarPixelA = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fColorFillAPixel * 1024.0F), 0, 1023); // U10 |
| cmd.DW11.GrayBarPixelVB = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fColorFillVBPixel * 1024.0F), 0, 1023); // U10 |
| |
| // Set DW13 |
| cmd.DW13.AlphaDefaultValue = MOS_CLAMP_MIN_MAX(MOS_F_ROUND(pSfcStateParams->fAlphaPixel * 1024.0F), 0, 1023); // U10 |
| |
| // Set DW14 |
| cmd.DW14.ScalingFactorHeight = MOS_UF_ROUND((1.0F / pSfcStateParams->fAVSYScalingRatio) * 131072.0F); // U4.17 |
| |
| // Set DW15 |
| cmd.DW15.ScalingFactorWidth = MOS_UF_ROUND((1.0F / pSfcStateParams->fAVSXScalingRatio) * 131072.0f); // U4.17 |
| |
| // Set DW19 |
| cmd.DW19.OutputFrameSurfaceBaseAddressMemoryCompressionEnable = pSfcStateParams->bMMCEnable; |
| cmd.DW19.OutputFrameSurfaceBaseAddressIndexToMemoryObjectControlStateMocsTables = outputSurfCtrl.Gen9.Index; |
| |
| if (pSfcStateParams->MMCMode == MOS_MMC_VERTICAL) |
| { |
| cmd.DW19.OutputFrameSurfaceBaseAddressMemoryCompressionMode = 1; |
| } |
| |
| // Set DW22 |
| cmd.DW22.AvsLineBufferBaseAddressIndexToMemoryObjectControlStateMocsTables = (uint32_t)m_avsLineBufferCtrl.Gen9.Index; |
| // Set DW25 |
| cmd.DW25.IefLineBufferBaseAddressIndexToMemoryObjectControlStateMocsTables = m_iefLineBufferCtrl.Gen9.Index; |
| |
| // Set DW29 |
| cmd.DW29.OutputSurfaceTileWalk = (pOutSurface->TileType == MOS_TILE_Y) ? true : false; |
| cmd.DW29.OutputSurfaceTiled = (pOutSurface->TileType != MOS_TILE_LINEAR) ? true : false; |
| cmd.DW29.OutputSurfaceHalfPitchForChroma = bHalfPitchForChroma; |
| cmd.DW29.OutputSurfacePitch = pOutSurface->dwPitch - 1; |
| cmd.DW29.OutputSurfaceInterleaveChromaEnable = bInterleaveChroma; |
| cmd.DW29.OutputSurfaceFormat = cmd.DW3.OutputSurfaceFormatType; |
| |
| // Set DW30, DW31 |
| cmd.DW30.OutputSurfaceYOffsetForU = wUYOffset; |
| cmd.DW30.OutputSurfaceXOffsetForU = wUXOffset; |
| cmd.DW31.OutputSurfaceYOffsetForV = wVYOffset; |
| cmd.DW31.OutputSurfaceXOffsetForV = wVXOffset; |
| |
| if (pSfcStateParams->pOsResOutputSurface) |
| { |
| MOS_ZeroMemory(&ResourceParams, sizeof(ResourceParams)); |
| ResourceParams.presResource = pSfcStateParams->pOsResOutputSurface; |
| ResourceParams.pdwCmd = &(cmd.DW17.Value); |
| ResourceParams.dwLocationInCmd = 17; |
| ResourceParams.HwCommandType = MOS_SFC_STATE; |
| ResourceParams.bIsWritable = true; |
| ResourceParams.dwOffset = pSfcStateParams->dwOutputSurfaceOffset; |
| |
| MHW_CHK_STATUS_RETURN(pfnAddResourceToCmd( |
| pOsInterface, |
| pCmdBuffer, |
| &ResourceParams)); |
| } |
| |
| if (pSfcStateParams->pOsResAVSLineBuffer) |
| { |
| MOS_ZeroMemory(&ResourceParams, sizeof(ResourceParams)); |
| ResourceParams.presResource = pSfcStateParams->pOsResAVSLineBuffer; |
| ResourceParams.pdwCmd = &(cmd.DW20.Value); |
| ResourceParams.dwLocationInCmd = 20; |
| ResourceParams.HwCommandType = MOS_SFC_STATE; |
| ResourceParams.bIsWritable = true; |
| |
| MHW_CHK_STATUS_RETURN(pfnAddResourceToCmd( |
| pOsInterface, |
| pCmdBuffer, |
| &ResourceParams)); |
| } |
| |
| if (pSfcStateParams->pOsResIEFLineBuffer) |
| { |
| MOS_ZeroMemory(&ResourceParams, sizeof(ResourceParams)); |
| ResourceParams.presResource = pSfcStateParams->pOsResIEFLineBuffer; |
| ResourceParams.pdwCmd = &(cmd.DW23.Value); |
| ResourceParams.dwLocationInCmd = 23; |
| ResourceParams.HwCommandType = MOS_SFC_STATE; |
| ResourceParams.bIsWritable = true; |
| |
| MHW_CHK_STATUS_RETURN(pfnAddResourceToCmd( |
| pOsInterface, |
| pCmdBuffer, |
| &ResourceParams)); |
| } |
| |
| cmd.DW3.PreAvsChromaDownsamplingEnable = pSfcStateParams->dwChromaDownSamplingMode; |
| cmd.DW3.PreAvsChromaDownsamplingCoSitingPositionVerticalDirection = pSfcStateParams->dwChromaDownSamplingVerticalCoef; |
| cmd.DW3.PreAvsChromaDownsamplingCoSitingPositionHorizontalDirection = pSfcStateParams->dwChromaDownSamplingHorizontalCoef; |
| |
| |
| MHW_CHK_STATUS_RETURN(Mos_AddCommand(pCmdBuffer, &cmd, cmd.byteSize)); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MhwSfcInterfaceG10::MhwSfcInterfaceG10(PMOS_INTERFACE pOsInterface) |
| : MhwSfcInterfaceGeneric(pOsInterface) |
| { |
| // Get Memory control object directly from MOS. |
| // If any override is needed, something like pfnOverrideMemoryObjectCtrl() / pfnComposeSurfaceCacheabilityControl() |
| // will need to be implemented. |
| // Caching policy if any of below modes are true |
| if (m_osInterface == nullptr) |
| { |
| MHW_ASSERTMESSAGE("Invalid Input Parameter: m_osInterface"); |
| return; |
| } |
| |
| m_outputSurfCtrl.Value = m_osInterface->pfnCachePolicyGetMemoryObject( |
| MOS_MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface, |
| m_osInterface->pfnGetGmmClientContext(m_osInterface)).DwordValue; |
| |
| m_avsLineBufferCtrl.Value = m_osInterface->pfnCachePolicyGetMemoryObject( |
| MOS_MHW_RESOURCE_USAGE_Sfc_AvsLineBufferSurface, |
| m_osInterface->pfnGetGmmClientContext(m_osInterface)).DwordValue; |
| m_iefLineBufferCtrl.Value = m_osInterface->pfnCachePolicyGetMemoryObject( |
| MOS_MHW_RESOURCE_USAGE_Sfc_IefLineBufferSurface, |
| m_osInterface->pfnGetGmmClientContext(m_osInterface)).DwordValue; |
| } |