/* * Copyright (c) 2017, 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_kernel_hme.cpp //! \brief Defines the hme kernel base //! \details Hme kernel base includes all common functions and definitions for HME on all platforms //! #include "codechal_kernel_hme.h" #if USE_CODECHAL_DEBUG_TOOL #include "codechal_debug.h" #endif CodechalKernelHme::CodechalKernelHme( CodechalEncoderState *encoder, bool me4xDistBufferSupported) : CodechalKernelBase(encoder), m_4xMeSupported(encoder->m_hmeSupported), m_16xMeSupported(encoder->m_16xMeSupported), m_32xMeSupported(encoder->m_32xMeSupported), m_noMEKernelForPFrame(encoder->m_noMeKernelForPFrame), m_useNonLegacyStreamIn(encoder->m_useNonLegacyStreamin), m_4xMeDistortionBufferSupported(me4xDistBufferSupported) { memset((void*)&m_curbeParam, 0, sizeof(m_curbeParam)); memset((void*)&m_surfaceParam, 0, sizeof(m_surfaceParam)); } CodechalKernelHme::~CodechalKernelHme() { ReleaseResources(); } MOS_STATUS CodechalKernelHme::AllocateResources() { MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D = {}; MEDIA_WA_TABLE* waTable = m_osInterface->pfnGetWaTable(m_osInterface); uint32_t memType = (MEDIA_IS_WA(waTable, WaForceAllocateLML4)) ? MOS_MEMPOOL_DEVICEMEMORY : 0; PMOS_SURFACE allocSurface = nullptr; if (m_4xMeSupported) { memset((void*)&allocParamsForBuffer2D, 0, sizeof(MOS_ALLOC_GFXRES_PARAMS)); allocParamsForBuffer2D.Type = MOS_GFXRES_2D; allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR; allocParamsForBuffer2D.Format = Format_Buffer_2D; CODECHAL_ENCODE_CHK_NULL_RETURN(allocSurface = MOS_New(MOS_SURFACE)); memset((void*)allocSurface, 0, sizeof(MOS_SURFACE)); allocSurface->TileType = MOS_TILE_LINEAR; allocSurface->bArraySpacing = true; allocSurface->Format = Format_Buffer_2D; allocSurface->dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64); // MediaBlockRW requires pitch multiple of 64 bytes when linear. allocSurface->dwHeight = (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER); allocSurface->dwPitch = allocSurface->dwWidth; allocParamsForBuffer2D.dwWidth = allocSurface->dwWidth; allocParamsForBuffer2D.dwHeight = allocSurface->dwHeight; allocParamsForBuffer2D.pBufName = "4xME MV Data Buffer"; allocParamsForBuffer2D.dwMemType = memType; CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurface(&allocParamsForBuffer2D, allocSurface, SurfaceId::me4xMvDataBuffer)); if (m_4xMeDistortionBufferSupported) { uint32_t ajustedHeight = m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT * SCALE_FACTOR_4x; uint32_t downscaledFieldHeightInMB4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(((ajustedHeight + 1) >> 1) / 4); CODECHAL_ENCODE_CHK_NULL_RETURN(allocSurface = MOS_New(MOS_SURFACE)); memset((void*)allocSurface, 0, sizeof(MOS_SURFACE)); MOS_ZeroMemory(allocSurface, sizeof(MOS_SURFACE)); allocSurface->TileType = MOS_TILE_LINEAR; allocSurface->bArraySpacing = true; allocSurface->Format = Format_Buffer_2D; allocSurface->dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64); allocSurface->dwHeight = 2 * MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x * 4 * 10), 8); allocSurface->dwPitch = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64); allocParamsForBuffer2D.dwWidth = allocSurface->dwWidth; allocParamsForBuffer2D.dwHeight = allocSurface->dwHeight; allocParamsForBuffer2D.pBufName = "4xME Distortion Buffer"; allocParamsForBuffer2D.dwMemType = memType; CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurface(&allocParamsForBuffer2D, allocSurface, SurfaceId::me4xDistortionBuffer)); } } if (m_16xMeSupported) { CODECHAL_ENCODE_CHK_NULL_RETURN(allocSurface = MOS_New(MOS_SURFACE)); memset((void*)allocSurface, 0, sizeof(MOS_SURFACE)); MOS_ZeroMemory(allocSurface, sizeof(MOS_SURFACE)); allocSurface->TileType = MOS_TILE_LINEAR; allocSurface->bArraySpacing = true; allocSurface->Format = Format_Buffer_2D; allocSurface->dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64); // MediaBlockRW requires pitch multiple of 64 bytes when linear allocSurface->dwHeight = (m_downscaledHeightInMb16x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER); allocSurface->dwPitch = allocSurface->dwWidth; allocParamsForBuffer2D.dwWidth = allocSurface->dwWidth; allocParamsForBuffer2D.dwHeight = allocSurface->dwHeight; allocParamsForBuffer2D.pBufName = "16xME MV Data Buffer"; allocParamsForBuffer2D.dwMemType = memType; CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurface(&allocParamsForBuffer2D, allocSurface, SurfaceId::me16xMvDataBuffer)); } if (m_32xMeSupported) { CODECHAL_ENCODE_CHK_NULL_RETURN(allocSurface = MOS_New(MOS_SURFACE)); memset((void*)allocSurface, 0, sizeof(MOS_SURFACE)); MOS_ZeroMemory(allocSurface, sizeof(MOS_SURFACE)); allocSurface->TileType = MOS_TILE_LINEAR; allocSurface->bArraySpacing = true; allocSurface->Format = Format_Buffer_2D; allocSurface->dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64); // MediaBlockRW requires pitch multiple of 64 bytes when linear allocSurface->dwHeight = (m_downscaledHeightInMb32x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER); allocSurface->dwPitch = allocSurface->dwWidth; allocParamsForBuffer2D.dwWidth = allocSurface->dwWidth; allocParamsForBuffer2D.dwHeight = allocSurface->dwHeight; allocParamsForBuffer2D.pBufName = "32xME MV Data Buffer"; allocParamsForBuffer2D.dwMemType = memType; CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurface(&allocParamsForBuffer2D, allocSurface, SurfaceId::me32xMvDataBuffer)); } return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalKernelHme::ReleaseResources() { return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalKernelHme::AddPerfTag() { PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); // Each ME kernel buffer counts as a separate perf task m_osInterface->pfnResetPerfBufferID(m_osInterface); return MOS_STATUS_SUCCESS; } MHW_KERNEL_STATE *CodechalKernelHme::GetActiveKernelState() { uint32_t kernelIndex = (m_pictureCodingType == P_TYPE) ? KernelIndex::hmeP : KernelIndex::hmeB; auto it = m_kernelStatePool.find(kernelIndex); if (it != m_kernelStatePool.end()) { return it->second; } MHW_KERNEL_STATE *kernelState = nullptr; uint32_t kernelOffset = 0; if (m_pictureCodingType != P_TYPE) { kernelOffset = 1; } CreateKernelState(&kernelState, kernelIndex, ENC_ME, kernelOffset); return kernelState; } CODECHAL_MEDIA_STATE_TYPE CodechalKernelHme::GetMediaStateType() { return m_32xMeInUse ? CODECHAL_MEDIA_STATE_32X_ME : m_16xMeInUse ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME; } MOS_STATUS CodechalKernelHme::InitWalkerCodecParams(CODECHAL_WALKER_CODEC_PARAMS &walkerParam) { uint32_t scalingFactor = m_32xMeInUse ? scalingFactor32X : m_16xMeInUse ? scalingFactor16X : scalingFactor4X; uint32_t xResolution = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / scalingFactor); uint32_t yResolution = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scalingFactor); walkerParam.WalkerMode = m_walkerMode; walkerParam.dwResolutionX = xResolution; walkerParam.dwResolutionY = yResolution; walkerParam.bNoDependency = true; walkerParam.bMbaff = m_surfaceParam.mbaffEnabled; walkerParam.bGroupIdSelectSupported = m_groupIdSelectSupported; walkerParam.ucGroupId = m_groupId; return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalKernelHme::SendSurfaces(PMOS_COMMAND_BUFFER cmd, MHW_KERNEL_STATE *kernelState) { if (!(m_4xMeInUse || m_16xMeInUse || m_32xMeInUse)) { return MOS_STATUS_INVALID_PARAMETER; } if (m_surfaceParam.vdencStreamInEnabled) { CODECHAL_ENCODE_CHK_NULL_RETURN(m_surfaceParam.meVdencStreamInBuffer); } else { CODECHAL_ENCODE_CHK_NULL_RETURN(m_surfaceParam.meBrcDistortionBuffer); } PMOS_SURFACE currScaledSurface; uint32_t refScaledBottomFieldOffset = 0; bool currFieldPicture = CodecHal_PictureIsField(*(m_surfaceParam.currOriginalPic)) ? true : false; bool currBottomField = CodecHal_PictureIsBottomField(*(m_surfaceParam.currOriginalPic)) ? true : false; uint8_t currVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); CODECHAL_SURFACE_CODEC_PARAMS surfaceParams; MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; surfaceParams.dwBindingTableOffset = BindingTableOffset::meOutputMvDataSurface; surfaceParams.bIsWritable = true; surfaceParams.bRenderTarget = true; if (m_32xMeInUse) { currScaledSurface = m_encoder->m_trackedBuf->Get32xDsSurface(CODEC_CURR_TRACKED_BUFFER); surfaceParams.psSurface = GetSurface(SurfaceId::me32xMvDataBuffer); surfaceParams.dwOffset = m_32xMeMvBottomFieldOffset; } else if (m_16xMeInUse) { currScaledSurface = m_encoder->m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER); surfaceParams.psSurface = GetSurface(SurfaceId::me16xMvDataBuffer); surfaceParams.dwOffset = m_16xMeMvBottomFieldOffset; } else { currScaledSurface = m_encoder->m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER); surfaceParams.psSurface = GetSurface(SurfaceId::me4xMvDataBuffer); surfaceParams.dwOffset = m_4xMeMvBottomFieldOffset; } // Force the values CODECHAL_ENCODE_CHK_NULL_RETURN(surfaceParams.psSurface); surfaceParams.psSurface->dwWidth = MOS_ALIGN_CEIL(m_surfaceParam.downScaledWidthInMb * 32, 64); surfaceParams.psSurface->dwHeight = m_surfaceParam.downScaledHeightInMb * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER; surfaceParams.psSurface->dwPitch = surfaceParams.psSurface->dwWidth; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); if (m_16xMeInUse && Is32xMeEnabled()) { // Pass 32x MV to 16x ME operation MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = GetSurface(SurfaceId::me32xMvDataBuffer); surfaceParams.dwOffset = currBottomField ? m_32xMeMvBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE].Value; surfaceParams.dwBindingTableOffset = BindingTableOffset::meInputMvDataSurface; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); } else if (Is16xMeEnabled() && !m_32xMeInUse) { // Pass 16x MV to 4x ME operation MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = GetSurface(SurfaceId::me16xMvDataBuffer); surfaceParams.dwOffset = currBottomField ? m_16xMeMvBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE].Value; surfaceParams.dwBindingTableOffset = BindingTableOffset::meInputMvDataSurface; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); } // Insert Distortion buffers only for 4xMe case if (m_4xMeInUse) { if (!m_surfaceParam.vdencStreamInEnabled) { MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = m_surfaceParam.meBrcDistortionBuffer; surfaceParams.dwOffset = m_surfaceParam.meBrcDistortionBottomFieldOffset; surfaceParams.dwBindingTableOffset = BindingTableOffset::meBrcDistortion; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE].Value; surfaceParams.bIsWritable = true; surfaceParams.bRenderTarget = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); } if (m_4xMeDistortionBufferSupported) { MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = GetSurface(SurfaceId::me4xDistortionBuffer); CODECHAL_ENCODE_CHK_NULL_RETURN(surfaceParams.psSurface); surfaceParams.psSurface->dwHeight = m_surfaceParam.downScaledHeightInMb * 4 * 10; surfaceParams.dwOffset = m_meDistortionBottomFieldOffset; surfaceParams.dwBindingTableOffset = BindingTableOffset::meDistortionSurface; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value; surfaceParams.bIsWritable = true; surfaceParams.bRenderTarget = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); } } // Setup references 1...n // LIST 0 references CODEC_PICTURE refPic; // Reference height and width information should be taken from the current scaled surface rather // than from the reference scaled surface in the case of PAFF. MOS_SURFACE refScaledSurface = *currScaledSurface; uint8_t fwdRefBTOffset[8]; fwdRefBTOffset[0] = BindingTableOffset::meFwdRefIdx0; fwdRefBTOffset[1] = BindingTableOffset::meFwdRefIdx1; fwdRefBTOffset[2] = BindingTableOffset::meFwdRefIdx2; fwdRefBTOffset[3] = BindingTableOffset::meFwdRefIdx3; fwdRefBTOffset[4] = BindingTableOffset::meFwdRefIdx4; fwdRefBTOffset[5] = BindingTableOffset::meFwdRefIdx5; fwdRefBTOffset[6] = BindingTableOffset::meFwdRefIdx6; fwdRefBTOffset[7] = BindingTableOffset::meFwdRefIdx7; for (uint8_t refIdx = 0; refIdx <= m_surfaceParam.numRefIdxL0ActiveMinus1; refIdx++) { refPic = m_surfaceParam.refL0List[refIdx]; if (!CodecHal_PictureIsInvalid(refPic) && m_surfaceParam.picIdx[refPic.FrameIdx].bValid) { if (refIdx == 0) { // Current Picture Y - VME MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bUseAdvState = true; surfaceParams.psSurface = currScaledSurface; surfaceParams.dwOffset = currBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value; surfaceParams.dwBindingTableOffset = BindingTableOffset::meCurrForFwdRef; surfaceParams.ucVDirection = currVDirection; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); } bool refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0; uint8_t refPicIdx = m_surfaceParam.picIdx[refPic.FrameIdx].ucPicIdx; uint8_t scaledIdx = m_surfaceParam.refList[refPicIdx]->ucScalingIdx; if (m_32xMeInUse) { MOS_SURFACE* p32xSurface = m_encoder->m_trackedBuf->Get32xDsSurface(scaledIdx); if (p32xSurface != nullptr) { refScaledSurface.OsResource = p32xSurface->OsResource; } else { CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); } refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0; } else if (m_16xMeInUse) { MOS_SURFACE* p16xSurface = m_encoder->m_trackedBuf->Get16xDsSurface(scaledIdx); if (p16xSurface != nullptr) { refScaledSurface.OsResource = p16xSurface->OsResource; } else { CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); } refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0; } else { MOS_SURFACE* p4xSurface = m_encoder->m_trackedBuf->Get4xDsSurface(scaledIdx); if (p4xSurface != nullptr) { refScaledSurface.OsResource = p4xSurface->OsResource; } else { CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); } refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0; } // L0 Reference Picture Y - VME MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bUseAdvState = true; surfaceParams.psSurface = &refScaledSurface; surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value; surfaceParams.dwBindingTableOffset = fwdRefBTOffset[refIdx]; surfaceParams.ucVDirection = !currFieldPicture ? CODECHAL_VDIRECTION_FRAME : ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); } } // Setup references 1...n // LIST 1 references uint8_t bwdRefBTOffset[2]; bwdRefBTOffset[0] = BindingTableOffset::meBwdRefIdx0; bwdRefBTOffset[1] = BindingTableOffset::meBwdRefIdx1; for (uint8_t refIdx = 0; refIdx <= m_surfaceParam.numRefIdxL1ActiveMinus1; refIdx++) { refPic = m_surfaceParam.refL1List[refIdx]; if (!CodecHal_PictureIsInvalid(refPic) && m_surfaceParam.picIdx[refPic.FrameIdx].bValid) { if (refIdx == 0) { // Current Picture Y - VME MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bUseAdvState = true; surfaceParams.psSurface = currScaledSurface; surfaceParams.dwOffset = currBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value; surfaceParams.dwBindingTableOffset = BindingTableOffset::meCurrForBwdRef; surfaceParams.ucVDirection = currVDirection; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); } bool refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false; uint8_t refPicIdx = m_surfaceParam.picIdx[refPic.FrameIdx].ucPicIdx; uint8_t scaledIdx = m_surfaceParam.refList[refPicIdx]->ucScalingIdx; if (m_32xMeInUse) { MOS_SURFACE* p32xSurface = m_encoder->m_trackedBuf->Get32xDsSurface(scaledIdx); if (p32xSurface != nullptr) { refScaledSurface.OsResource = p32xSurface->OsResource; } else { CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); } refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0; } else if (m_16xMeInUse) { MOS_SURFACE* p16xSurface = m_encoder->m_trackedBuf->Get16xDsSurface(scaledIdx); if (p16xSurface != nullptr) { refScaledSurface.OsResource = p16xSurface->OsResource; } else { CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); } refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0; } else { MOS_SURFACE* p4xSurface = m_encoder->m_trackedBuf->Get4xDsSurface(scaledIdx); if (p4xSurface != nullptr) { refScaledSurface.OsResource = p4xSurface->OsResource; } else { CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); } refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0; } // L1 Reference Picture Y - VME MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bUseAdvState = true; surfaceParams.psSurface = &refScaledSurface; surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value; surfaceParams.dwBindingTableOffset = bwdRefBTOffset[refIdx]; surfaceParams.ucVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmd, &surfaceParams, kernelState)); } } return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalKernelHme::Execute(CurbeParam &curbeParam, SurfaceParams &surfaceParam, HmeLevel hmeLevel) { m_4xMeInUse = Is4xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel4x) != 0 : false; m_16xMeInUse = Is16xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel16x) != 0 : false; m_32xMeInUse = Is32xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel32x) != 0 : false; MOS_SecureMemcpy(&m_curbeParam, sizeof(m_curbeParam), &curbeParam, sizeof(m_curbeParam)); MOS_SecureMemcpy(&m_surfaceParam, sizeof(m_surfaceParam), &surfaceParam, sizeof(m_surfaceParam)); CODECHAL_ENCODE_CHK_STATUS_RETURN(Run()); return MOS_STATUS_SUCCESS; } #if USE_CODECHAL_DEBUG_TOOL MOS_STATUS CodechalKernelHme::DumpKernelOutput() { if (!Is4xMeEnabled()) { return MOS_STATUS_SUCCESS; } PMOS_SURFACE surface = nullptr; CODECHAL_MEDIA_STATE_TYPE mediaState = GetMediaStateType(); surface = GetSurface(SurfaceId::me4xMvDataBuffer); if (surface) { m_debugInterface->DumpBuffer(&surface->OsResource, CodechalDbgAttr::attrOutput, "_MvData", surface->dwWidth*surface->dwPitch, m_4xMeMvBottomFieldOffset, mediaState); } surface = GetSurface(SurfaceId::me16xMvDataBuffer); if (surface) { m_debugInterface->DumpBuffer(&surface->OsResource, CodechalDbgAttr::attrOutput, "_MvData", surface->dwWidth*surface->dwPitch, m_16xMeMvBottomFieldOffset, mediaState); } surface = GetSurface(SurfaceId::me32xMvDataBuffer); if (surface) { m_debugInterface->DumpBuffer(&surface->OsResource, CodechalDbgAttr::attrOutput, "_MvData", surface->dwWidth*surface->dwPitch, m_32xMeMvBottomFieldOffset, mediaState); } surface = GetSurface(SurfaceId::me4xDistortionBuffer); if (surface) { m_debugInterface->DumpBuffer(&surface->OsResource, CodechalDbgAttr::attrOutput, "_Distortion", surface->dwWidth*surface->dwPitch, m_meDistortionBottomFieldOffset, mediaState); } if (m_surfaceParam.meBrcDistortionBuffer) { m_debugInterface->DumpBuffer(&m_surfaceParam.meBrcDistortionBuffer->OsResource, CodechalDbgAttr::attrOutput, "_BrcDistortion", m_surfaceParam.meBrcDistortionBuffer->dwWidth*m_surfaceParam.meBrcDistortionBuffer->dwPitch, m_surfaceParam.meBrcDistortionBottomFieldOffset, mediaState); } return MOS_STATUS_SUCCESS; } #endif