blob: b25b166df05534f91405fb6756c817df4860494e [file] [log] [blame]
/*
* Copyright (c) 2017-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 codechal_utilities.cpp
//! \brief Implements the common functions for codec.
//! \details This modules implements utilities which are shared by encoder and decoder
//!
#include "codechal_hw.h"
#include "codeckrnheader.h"
#include "codechal_utilities.h"
MOS_STATUS CodecHalInitMediaObjectWalkerParams(
CodechalHwInterface *hwInterface,
PMHW_WALKER_PARAMS walkerParams,
PCODECHAL_WALKER_CODEC_PARAMS walkerCodecParams)
{
CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface);
CODECHAL_PUBLIC_CHK_NULL_RETURN(walkerParams);
CODECHAL_PUBLIC_CHK_NULL_RETURN(walkerCodecParams);
MOS_ZeroMemory(walkerParams, sizeof(MHW_WALKER_PARAMS));
walkerParams->WalkerMode =
(MHW_WALKER_MODE)walkerCodecParams->WalkerMode;
walkerParams->UseScoreboard = walkerCodecParams->bUseScoreboard;
walkerParams->BlockResolution.x = walkerCodecParams->dwResolutionX;
walkerParams->BlockResolution.y = walkerCodecParams->dwResolutionY;
walkerParams->GlobalResolution.x = walkerCodecParams->dwResolutionX;
walkerParams->GlobalResolution.y = walkerCodecParams->dwResolutionY;
walkerParams->GlobalOutlerLoopStride.x = walkerCodecParams->dwResolutionX;
walkerParams->GlobalOutlerLoopStride.y = 0;
walkerParams->GlobalInnerLoopUnit.x = 0;
walkerParams->GlobalInnerLoopUnit.y = walkerCodecParams->dwResolutionY;
// Gen7.5 & Gen8: 0x3FF, Gen9: 0x7FF
walkerParams->dwLocalLoopExecCount = 0xFFFF; //MAX VALUE
walkerParams->dwGlobalLoopExecCount = 0xFFFF; //MAX VALUE
if (walkerCodecParams->bMbEncIFrameDistInUse || walkerCodecParams->bNoDependency)
{
walkerParams->ScoreboardMask = 0;
// Raster scan walking pattern
walkerParams->LocalOutLoopStride.x = 0;
walkerParams->LocalOutLoopStride.y = 1;
walkerParams->LocalInnerLoopUnit.x = 1;
walkerParams->LocalInnerLoopUnit.y = 0;
walkerParams->LocalEnd.x = walkerCodecParams->dwResolutionX - 1;
walkerParams->LocalEnd.y = 0;
}
else if (walkerCodecParams->bUseVerticalRasterScan)
{
walkerParams->ScoreboardMask = 0x1;
walkerParams->LocalOutLoopStride.x = 1;
walkerParams->LocalOutLoopStride.y = 0;
walkerParams->LocalInnerLoopUnit.x = 0;
walkerParams->LocalInnerLoopUnit.y = 1;
walkerParams->LocalEnd.x = 0;
walkerParams->LocalEnd.y = walkerCodecParams->dwResolutionY - 1;
}
else
{
walkerParams->LocalEnd.x = 0;
walkerParams->LocalEnd.y = 0;
if (walkerCodecParams->WalkerDegree == CODECHAL_46_DEGREE) // Gen6 only VP8 HybridPak2Pattern
{
// 46 degree walking pattern
walkerParams->ScoreboardMask = walkerCodecParams->ScoreboardMask;
walkerParams->LocalOutLoopStride.x = 1;
walkerParams->LocalOutLoopStride.y = 0;
walkerParams->LocalInnerLoopUnit.x = 0x3FF; // -1
walkerParams->LocalInnerLoopUnit.y = 1;
}
else if (walkerCodecParams->WalkerDegree == CODECHAL_45Z_DEGREE)
{
// 45z degree pattern
walkerParams->ScoreboardMask = 0x0F;
walkerParams->dwGlobalLoopExecCount = 0x3FF;
walkerParams->dwLocalLoopExecCount = 0x3FF;
walkerParams->GlobalResolution.x = uint32_t(walkerCodecParams->dwResolutionX / 2.f) + 1;
walkerParams->GlobalResolution.y = 2 * walkerCodecParams->dwResolutionY;
walkerParams->GlobalStart.x = 0;
walkerParams->GlobalStart.y = 0;
walkerParams->GlobalOutlerLoopStride.x = walkerParams->GlobalResolution.x;
walkerParams->GlobalOutlerLoopStride.y = 0;
walkerParams->GlobalInnerLoopUnit.x = 0;
walkerParams->GlobalInnerLoopUnit.y = walkerParams->GlobalResolution.y;
walkerParams->BlockResolution.x = walkerParams->GlobalResolution.x;
walkerParams->BlockResolution.y = walkerParams->GlobalResolution.y;
walkerParams->LocalStart.x = 0;
walkerParams->LocalStart.y = 0;
walkerParams->LocalOutLoopStride.x = 1;
walkerParams->LocalOutLoopStride.y = 0;
walkerParams->LocalInnerLoopUnit.x = MOS_BITFIELD_VALUE((uint32_t)-1, 16);
walkerParams->LocalInnerLoopUnit.y = 4;
walkerParams->MiddleLoopExtraSteps = 3;
walkerParams->MidLoopUnitX = 0;
walkerParams->MidLoopUnitY = 1;
}
else if ( walkerCodecParams->WalkerDegree == CODECHAL_45_DEGREE || // Gen8,9
( ( walkerCodecParams->wPictureCodingType == I_TYPE || (walkerCodecParams->wPictureCodingType == B_TYPE && !walkerCodecParams->bDirectSpatialMVPredFlag) ) // CHECK B_TYPE ALWAYS
&& walkerCodecParams->WalkerDegree != CODECHAL_26_DEGREE ) )
{
// 45 degree walking pattern
walkerParams->ScoreboardMask = 0x03;
walkerParams->LocalOutLoopStride.x = 1;
walkerParams->LocalOutLoopStride.y = 0;
walkerParams->LocalInnerLoopUnit.x = MOS_BITFIELD_VALUE((uint32_t)-1, 16); // Gen9: 0xFFF Gen6,8: 0x3FF
walkerParams->LocalInnerLoopUnit.y = 1;
}
else if ( walkerCodecParams->WalkerDegree == CODECHAL_26Z_DEGREE )
{
// 26z degree walking pattern used for HEVC
walkerParams->ScoreboardMask = 0x7f;
// z-order in the local loop
walkerParams->LocalOutLoopStride.x = 0;
walkerParams->LocalOutLoopStride.y = 1;
walkerParams->LocalInnerLoopUnit.x = 1;
walkerParams->LocalInnerLoopUnit.y = 0;
// dispatch 4 threads together in one LCU
walkerParams->BlockResolution.x = 2;
walkerParams->BlockResolution.y = 2;
// 26 degree in the global loop
walkerParams->GlobalOutlerLoopStride.x = 2;
walkerParams->GlobalOutlerLoopStride.y = 0;
walkerParams->GlobalInnerLoopUnit.x = 0xFFF -4 + 1; // -4 in 2's compliment format
walkerParams->GlobalInnerLoopUnit.y = 2;
}
else
{
// 26 degree walking pattern
walkerParams->ScoreboardMask = 0x0F;
walkerParams->LocalOutLoopStride.x = 1;
walkerParams->LocalOutLoopStride.y = 0;
walkerParams->LocalInnerLoopUnit.x = MOS_BITFIELD_VALUE((uint32_t)-2, 16); // Gen9: 0xFFE Gen6,8: 0x3FE
walkerParams->LocalInnerLoopUnit.y = 1;
}
}
if (walkerCodecParams->bMbaff)
{
walkerParams->ScoreboardMask = 0xFF;
walkerParams->MiddleLoopExtraSteps = 1;
walkerParams->MidLoopUnitY = 1;
walkerParams->LocalInnerLoopUnit.y = 2;
}
// In case of multiple Slice scenarios, every slice can be processed parallelly
// to enhance the performance. This is accomplished by launching the slices concurrently,
// providing the X and Y position of the thread along with Color bit. The AVC MBEnc kernel
// uses the color bit sent in the header to identify the Slice and calculates the MBY index
// accordingly.The color bit literally conveys the slice number of the MB.
if (walkerCodecParams->bColorbitSupported && walkerCodecParams->dwNumSlices <= CODECHAL_MEDIA_WALKER_MAX_COLORS)
{
walkerParams->ColorCountMinusOne = walkerCodecParams->dwNumSlices - 1;
walkerParams->BlockResolution.y = walkerCodecParams->usSliceHeight;
walkerParams->GlobalResolution.y = walkerCodecParams->usSliceHeight;
walkerParams->GlobalInnerLoopUnit.y = walkerCodecParams->usSliceHeight;
}
if(walkerCodecParams->bGroupIdSelectSupported)
{
walkerParams->GroupIdLoopSelect = walkerCodecParams->ucGroupId;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodecHalGetKernelBinaryAndSize(
uint8_t* kernelBase,
uint32_t kernelUID,
uint8_t** kernelBinary,
uint32_t* size)
{
#ifdef ENABLE_KERNELS
CODECHAL_PUBLIC_CHK_NULL_RETURN(kernelBase);
CODECHAL_PUBLIC_CHK_NULL_RETURN(kernelBinary);
CODECHAL_PUBLIC_CHK_NULL_RETURN(size);
if (kernelUID >= IDR_CODEC_TOTAL_NUM_KERNELS)
{
return MOS_STATUS_INVALID_PARAMETER;
}
auto kernelOffsetTable = (uint32_t*)kernelBase;
auto binaryBase = (uint8_t*)(kernelOffsetTable + IDR_CODEC_TOTAL_NUM_KERNELS + 1);
*size = kernelOffsetTable[kernelUID + 1] - kernelOffsetTable[kernelUID];
*kernelBinary = (*size) > 0 ? binaryBase + kernelOffsetTable[kernelUID] : nullptr;
#else
*size = 0;
*kernelBinary = nullptr;
#endif
return MOS_STATUS_SUCCESS;
}
void CodecHal_GetSurfaceWidthInBytes(
PMOS_SURFACE surface,
uint32_t *widthInBytes)
{
uint32_t width;
switch (surface->Format)
{
case Format_IMC1:
case Format_IMC3:
case Format_IMC2:
case Format_IMC4:
case Format_NV12:
case Format_YV12:
case Format_I420:
case Format_IYUV:
case Format_400P:
case Format_411P:
case Format_422H:
case Format_422V:
case Format_444P:
case Format_RGBP:
case Format_BGRP:
width = surface->dwWidth;
break;
case Format_YUY2:
case Format_YUYV:
case Format_YVYU:
case Format_UYVY:
case Format_VYUY:
case Format_P010:
width = surface->dwWidth << 1;
break;
case Format_Y210:
case Format_Y216:
case Format_A8R8G8B8:
case Format_X8R8G8B8:
case Format_A8B8G8R8:
case Format_R32U:
case Format_R32F:
width = surface->dwWidth << 2;
break;
default:
width = surface->dwWidth;
break;
}
*widthInBytes = width;
}
MOS_STATUS CodecHalSetRcsSurfaceState(
CodechalHwInterface *hwInterface,
PMOS_COMMAND_BUFFER cmdBuffer,
PCODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams,
PMHW_KERNEL_STATE kernelState)
{
CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface);
CODECHAL_PUBLIC_CHK_NULL_RETURN(surfaceCodecParams);
CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface->GetRenderInterface());
CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface->GetRenderInterface()->m_stateHeapInterface);
CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface->GetOsInterface());
PMHW_STATE_HEAP_INTERFACE stateHeapInterface = hwInterface->GetRenderInterface()->m_stateHeapInterface;
PMOS_INTERFACE osInterface = hwInterface->GetOsInterface();
MHW_RCS_SURFACE_PARAMS surfaceRcsParams;
MOS_ZeroMemory(&surfaceRcsParams, sizeof(MHW_RCS_SURFACE_PARAMS));
// default initial values
surfaceRcsParams.dwNumPlanes = 1; // MHW_GENERIC_PLANE = MHW_Y_PLANE
surfaceRcsParams.dwCacheabilityControl = surfaceCodecParams->dwCacheabilityControl;
surfaceRcsParams.bRenderTarget = surfaceCodecParams->bRenderTarget;
surfaceRcsParams.bIsWritable = surfaceCodecParams->bIsWritable;
surfaceRcsParams.dwBaseAddrOffset[MHW_Y_PLANE] = surfaceCodecParams->dwOffset;
uint32_t surfaceFormat;
MOS_SURFACE bufferSurface;
if (surfaceCodecParams->bIs2DSurface) // 2D
{
if (surfaceCodecParams->bUse32UnormSurfaceFormat)
{
surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R32_UNORM;
}
else if (surfaceCodecParams->bUse16UnormSurfaceFormat)
{
surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R16_UNORM;
}
else if (surfaceCodecParams->bUseARGB8Format)
{
// Ds+Copy kernel requires input surface set to ARGB8
surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R8G8B8A8_UNORM;
}
else if (surfaceCodecParams->bUse32UINTSurfaceFormat)
{
surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R32_UINT;
}
else if (surfaceCodecParams->psSurface->Format == Format_YUY2)
{
surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_YCRCB_NORMAL;
}
else if (surfaceCodecParams->psSurface->Format == Format_UYVY)
{
surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_YCRCB_SWAPY;
}
else if (surfaceCodecParams->psSurface->Format == Format_P010)
{
surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R16_UNORM;
}
else //NV12
{
surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM;
}
surfaceRcsParams.ForceSurfaceFormat[MHW_Y_PLANE] = surfaceFormat;
surfaceRcsParams.dwSurfaceType = GFX3DSTATE_SURFACETYPE_2D;
// MMC info passed with psSurface->CompressionMode
surfaceRcsParams.psSurface = surfaceCodecParams->psSurface;
uint32_t widthInBytes;
if( surfaceCodecParams->bMediaBlockRW )
{
CodecHal_GetSurfaceWidthInBytes(surfaceCodecParams->psSurface, &widthInBytes);
surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] = WIDTH_IN_DW(widthInBytes);
}
else
{
surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] = surfaceCodecParams->psSurface->dwWidth;
}
surfaceRcsParams.dwHeightToUse[MHW_Y_PLANE] = (surfaceCodecParams->dwHeightInUse == 0) ?
((surfaceCodecParams->bUseHalfHeight) ? (surfaceCodecParams->psSurface->dwHeight / 2) : surfaceCodecParams->psSurface->dwHeight)
: surfaceCodecParams->dwHeightInUse;
if (surfaceCodecParams->bCheckCSC8Format &&
(surfaceCodecParams->psSurface->Format == Format_AYUV || surfaceCodecParams->psSurface->Format == Format_Y410 ||
surfaceCodecParams->psSurface->Format == Format_R10G10B10A2 || surfaceCodecParams->psSurface->Format == Format_B10G10R10A2))
{
surfaceRcsParams.ForceSurfaceFormat[MHW_Y_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM;
surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] = surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] * 4;
}
surfaceRcsParams.dwBindingTableOffset[MHW_Y_PLANE] = surfaceCodecParams->dwBindingTableOffset;
surfaceRcsParams.dwYOffset[MHW_Y_PLANE] = surfaceCodecParams->psSurface->YPlaneOffset.iYOffset;
surfaceRcsParams.bVertLineStride = surfaceCodecParams->dwVerticalLineStride;
surfaceRcsParams.bVertLineStrideOffs = surfaceCodecParams->dwVerticalLineStrideOffset;
surfaceRcsParams.psSurface->dwDepth = 1; // depth needs to be 0 for codec 2D surface
if (surfaceCodecParams->bUseUVPlane) // UV
{
surfaceRcsParams.dwNumPlanes = 2; // Y, UV
if (surfaceCodecParams->bForceChromaFormat)
{
surfaceRcsParams.ForceSurfaceFormat[MHW_U_PLANE] = surfaceCodecParams->ChromaType;
}
else
{
MOS_MEMCOMP_STATE mmcstate;
CODECHAL_PUBLIC_CHK_STATUS_RETURN(osInterface->pfnGetMemoryCompressionMode(
osInterface, &surfaceRcsParams.psSurface->OsResource, &mmcstate));
// MMC HW requires GFX3DSTATE_SURFACEFORMAT_YCRCB_SWAPUVY format for P010 UV planes.
surfaceRcsParams.ForceSurfaceFormat[MHW_U_PLANE] = (surfaceCodecParams->psSurface->Format == Format_P010) ?
((mmcstate != MOS_MEMCOMP_DISABLED) ? MHW_GFX3DSTATE_SURFACEFORMAT_YCRCB_SWAPUVY : MHW_GFX3DSTATE_SURFACEFORMAT_R16G16_UNORM) :
MHW_GFX3DSTATE_SURFACEFORMAT_R16_UINT;
}
surfaceRcsParams.dwBindingTableOffset[MHW_U_PLANE] = surfaceCodecParams->dwUVBindingTableOffset;
widthInBytes = surfaceCodecParams->psSurface->dwWidth;
if (surfaceCodecParams->psSurface->Format == Format_P010)
{
widthInBytes *= 2;
}
surfaceRcsParams.dwWidthToUse[MHW_U_PLANE] = (surfaceCodecParams->bMediaBlockRW) ?
WIDTH_IN_DW(widthInBytes) : (surfaceCodecParams->psSurface->dwWidth / 2);
surfaceRcsParams.dwHeightToUse[MHW_U_PLANE] = (surfaceCodecParams->bUseHalfHeight) ?
(surfaceCodecParams->psSurface->dwHeight / 4) : (surfaceCodecParams->psSurface->dwHeight / 2);
if (surfaceCodecParams->psSurface->Format == Format_YUY2V || surfaceCodecParams->psSurface->Format == Format_Y216V || surfaceCodecParams->psSurface->Format == Format_P208)
{
surfaceRcsParams.dwHeightToUse[MHW_U_PLANE] = surfaceRcsParams.dwHeightToUse[MHW_U_PLANE] * 2;
}
if (IS_Y_MAJOR_TILE_FORMAT(surfaceRcsParams.psSurface->TileType))
{
uint32_t tileHeightAlignment =
(MOS_TILE_YS == surfaceRcsParams.psSurface->TileType) ? MOS_YSTILE_H_ALIGNMENT : MOS_YTILE_H_ALIGNMENT;
surfaceRcsParams.dwBaseAddrOffset[MHW_U_PLANE] =
surfaceCodecParams->psSurface->dwPitch *
MOS_ALIGN_FLOOR(surfaceCodecParams->psSurface->UPlaneOffset.iYOffset, tileHeightAlignment);
surfaceRcsParams.dwYOffset[MHW_U_PLANE] =
(surfaceCodecParams->psSurface->UPlaneOffset.iYOffset % tileHeightAlignment);
}
else if( MOS_TILE_LINEAR == surfaceRcsParams.psSurface->TileType )
{
surfaceRcsParams.dwBaseAddrOffset[MHW_U_PLANE] =
surfaceCodecParams->psSurface->dwPitch * surfaceCodecParams->psSurface->UPlaneOffset.iYOffset;
surfaceRcsParams.dwYOffset[MHW_U_PLANE] = 0;
}
else if( MOS_TILE_X == surfaceRcsParams.psSurface->TileType )
{
CODECHAL_PUBLIC_ASSERTMESSAGE("X_TILE surface not supported yet!");
return MOS_STATUS_INVALID_PARAMETER;
}
else
{
CODECHAL_PUBLIC_ASSERTMESSAGE("Invalid surface TileType");
return MOS_STATUS_INVALID_PARAMETER;
}
}
if (surfaceCodecParams->bUseHalfHeight)
{
surfaceRcsParams.MediaBoundaryPixelMode = GFX3DSTATE_BOUNDARY_INTERLACED_FRAME;
}
}
else if (surfaceCodecParams->bUseAdvState) // AdvState
{
surfaceRcsParams.bUseAdvState = surfaceCodecParams->bUseAdvState;
// MMC info passed with psSurface->CompressionMode
surfaceRcsParams.psSurface = surfaceCodecParams->psSurface;
surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] = surfaceCodecParams->dwWidthInUse;
surfaceRcsParams.dwWidthToUse[MHW_U_PLANE] = surfaceRcsParams.dwWidthToUse[MHW_V_PLANE] = surfaceCodecParams->dwWidthInUse / 2;
surfaceRcsParams.dwHeightToUse[MHW_Y_PLANE] = surfaceCodecParams->dwHeightInUse;
surfaceRcsParams.dwHeightToUse[MHW_U_PLANE] = surfaceRcsParams.dwHeightToUse[MHW_V_PLANE] =
(surfaceCodecParams->psSurface->Format == Format_YUY2V || surfaceCodecParams->psSurface->Format == Format_Y216V) ?
surfaceCodecParams->dwHeightInUse :
surfaceCodecParams->dwHeightInUse / 2;
surfaceRcsParams.ForceSurfaceFormat[MHW_Y_PLANE] = MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_420_8;
surfaceRcsParams.dwBindingTableOffset[MHW_Y_PLANE] = surfaceCodecParams->dwBindingTableOffset;
surfaceRcsParams.bInterleaveChroma = true;
surfaceRcsParams.Direction = (MHW_CHROMA_SITING_VDIRECTION) surfaceCodecParams->ucVDirection;
surfaceRcsParams.dwYOffset[MHW_U_PLANE] = surfaceCodecParams->psSurface->UPlaneOffset.iYOffset;
}
else // 1D Buffer
{
MOS_ZeroMemory(&bufferSurface, sizeof(MOS_SURFACE));
MOS_SecureMemcpy(&bufferSurface.OsResource, sizeof(MOS_RESOURCE), surfaceCodecParams->presBuffer, sizeof(MOS_RESOURCE));
surfaceRcsParams.psSurface = &bufferSurface;
surfaceRcsParams.ForceSurfaceFormat[MHW_Y_PLANE] = surfaceCodecParams->bRawSurface ?
MHW_GFX3DSTATE_SURFACEFORMAT_RAW : MHW_GFX3DSTATE_SURFACEFORMAT_R32_UINT;
surfaceRcsParams.dwBindingTableOffset[MHW_Y_PLANE] = surfaceCodecParams->dwBindingTableOffset;
surfaceRcsParams.psSurface->Type = MOS_GFXRES_BUFFER;
surfaceRcsParams.psSurface->Format = Format_Buffer;
surfaceRcsParams.psSurface->TileType = MOS_TILE_LINEAR;
surfaceRcsParams.psSurface->dwSize = surfaceCodecParams->dwSize;
surfaceRcsParams.psSurface->dwWidth = (surfaceCodecParams->dwSize - 1) & 0x7F;
surfaceRcsParams.psSurface->dwHeight = ((surfaceCodecParams->dwSize - 1) & 0x1FFF80) >> 7;
surfaceRcsParams.psSurface->dwDepth = ((surfaceCodecParams->dwSize - 1) & 0xFE00000) >> 21;
// GMM doesn't provide pitch info from surface
surfaceRcsParams.psSurface->dwPitch = surfaceCodecParams->bRawSurface ? sizeof(uint8_t) : sizeof(uint32_t);
surfaceRcsParams.psSurface->bArraySpacing = true;
}
CODECHAL_PUBLIC_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState(
stateHeapInterface,
kernelState,
cmdBuffer,
1,
&surfaceRcsParams));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodecHalGetResourceInfo(
PMOS_INTERFACE osInterface,
PMOS_SURFACE surface)
{
CODECHAL_PUBLIC_CHK_NULL_RETURN(surface);
MOS_SURFACE details;
MOS_ZeroMemory(&details, sizeof(details));
details.Format = Format_Invalid;
CODECHAL_PUBLIC_CHK_STATUS_RETURN(osInterface->pfnGetResourceInfo(osInterface, &surface->OsResource, &details));
surface->Format = details.Format;
surface->dwWidth = details.dwWidth;
surface->dwHeight = details.dwHeight;
surface->dwPitch = details.dwPitch;
surface->dwDepth = details.dwDepth;
surface->dwQPitch = details.dwQPitch;
surface->bArraySpacing = details.bArraySpacing;
surface->TileType = details.TileType;
surface->TileModeGMM = details.TileModeGMM;
surface->bGMMTileEnabled = details.bGMMTileEnabled;
surface->dwOffset = details.RenderOffset.YUV.Y.BaseOffset;
surface->YPlaneOffset.iSurfaceOffset = details.RenderOffset.YUV.Y.BaseOffset;
surface->YPlaneOffset.iXOffset = details.RenderOffset.YUV.Y.XOffset;
surface->YPlaneOffset.iYOffset =
(surface->YPlaneOffset.iSurfaceOffset - surface->dwOffset) / surface->dwPitch +
details.RenderOffset.YUV.Y.YOffset;
surface->UPlaneOffset.iSurfaceOffset = details.RenderOffset.YUV.U.BaseOffset;
surface->UPlaneOffset.iXOffset = details.RenderOffset.YUV.U.XOffset;
surface->UPlaneOffset.iYOffset =
(surface->UPlaneOffset.iSurfaceOffset - surface->dwOffset) / surface->dwPitch +
details.RenderOffset.YUV.U.YOffset;
surface->UPlaneOffset.iLockSurfaceOffset = details.LockOffset.YUV.U;
surface->VPlaneOffset.iSurfaceOffset = details.RenderOffset.YUV.V.BaseOffset;
surface->VPlaneOffset.iXOffset = details.RenderOffset.YUV.V.XOffset;
surface->VPlaneOffset.iYOffset =
(surface->VPlaneOffset.iSurfaceOffset - surface->dwOffset) / surface->dwPitch +
details.RenderOffset.YUV.V.YOffset;
surface->VPlaneOffset.iLockSurfaceOffset = details.LockOffset.YUV.V;
surface->bCompressible = details.bCompressible;
surface->CompressionMode = details.CompressionMode;
surface->bIsCompressed = details.bIsCompressed;
return MOS_STATUS_SUCCESS;
}