blob: 0429cb0e4cce7a3cd027dcd4aa0a128b08e22d12 [file] [log] [blame]
/*
* 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;
}