| /* |
| * 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; |
| } |