1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     codechal_kernel_hme.cpp
24 //! \brief    Defines the hme kernel base
25 //! \details  Hme kernel base includes all common functions and definitions for HME on all platforms
26 //!
27 
28 #include "codechal_kernel_hme.h"
29 #if USE_CODECHAL_DEBUG_TOOL
30 #include "codechal_debug.h"
31 #endif
32 
CodechalKernelHme(CodechalEncoderState * encoder,bool me4xDistBufferSupported)33 CodechalKernelHme::CodechalKernelHme(
34     CodechalEncoderState *encoder,
35     bool                 me4xDistBufferSupported)
36         : CodechalKernelBase(encoder),
37           m_4xMeSupported(encoder->m_hmeSupported),
38           m_16xMeSupported(encoder->m_16xMeSupported),
39           m_32xMeSupported(encoder->m_32xMeSupported),
40           m_noMEKernelForPFrame(encoder->m_noMeKernelForPFrame),
41           m_useNonLegacyStreamIn(encoder->m_useNonLegacyStreamin),
42           m_4xMeDistortionBufferSupported(me4xDistBufferSupported)
43 {
44     memset((void*)&m_curbeParam, 0, sizeof(m_curbeParam));
45     memset((void*)&m_surfaceParam, 0, sizeof(m_surfaceParam));
46 }
47 
~CodechalKernelHme()48 CodechalKernelHme::~CodechalKernelHme()
49 {
50     ReleaseResources();
51 }
52 
AllocateResources()53 MOS_STATUS CodechalKernelHme::AllocateResources()
54 {
55     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D = {};
56 
57     MEDIA_WA_TABLE* waTable = m_osInterface->pfnGetWaTable(m_osInterface);
58     uint32_t memType = (MEDIA_IS_WA(waTable, WaForceAllocateLML4)) ? MOS_MEMPOOL_DEVICEMEMORY : 0;
59 
60     PMOS_SURFACE allocSurface = nullptr;
61     if (m_4xMeSupported)
62     {
63         memset((void*)&allocParamsForBuffer2D, 0, sizeof(MOS_ALLOC_GFXRES_PARAMS));
64         allocParamsForBuffer2D.Type     = MOS_GFXRES_2D;
65         allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
66         allocParamsForBuffer2D.Format   = Format_Buffer_2D;
67 
68         CODECHAL_ENCODE_CHK_NULL_RETURN(allocSurface = MOS_New(MOS_SURFACE));
69         memset((void*)allocSurface, 0, sizeof(MOS_SURFACE));
70 
71         allocSurface->TileType      = MOS_TILE_LINEAR;
72         allocSurface->bArraySpacing = true;
73         allocSurface->Format        = Format_Buffer_2D;
74         allocSurface->dwWidth       = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64);  // MediaBlockRW requires pitch multiple of 64 bytes when linear.
75         allocSurface->dwHeight      = (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
76         allocSurface->dwPitch       = allocSurface->dwWidth;
77 
78         allocParamsForBuffer2D.dwWidth  = allocSurface->dwWidth;
79         allocParamsForBuffer2D.dwHeight = allocSurface->dwHeight;
80         allocParamsForBuffer2D.pBufName = "4xME MV Data Buffer";
81         allocParamsForBuffer2D.dwMemType = memType;
82 
83         CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurface(&allocParamsForBuffer2D, allocSurface, SurfaceId::me4xMvDataBuffer));
84 
85         if (m_4xMeDistortionBufferSupported)
86         {
87             uint32_t ajustedHeight =
88                 m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT * SCALE_FACTOR_4x;
89             uint32_t downscaledFieldHeightInMB4x =
90                 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(((ajustedHeight + 1) >> 1) / 4);
91             CODECHAL_ENCODE_CHK_NULL_RETURN(allocSurface = MOS_New(MOS_SURFACE));
92             memset((void*)allocSurface, 0, sizeof(MOS_SURFACE));
93             MOS_ZeroMemory(allocSurface, sizeof(MOS_SURFACE));
94             allocSurface->TileType      = MOS_TILE_LINEAR;
95             allocSurface->bArraySpacing = true;
96             allocSurface->Format        = Format_Buffer_2D;
97             allocSurface->dwWidth       = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
98             allocSurface->dwHeight      = 2 * MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x * 4 * 10), 8);
99             allocSurface->dwPitch       = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
100 
101             allocParamsForBuffer2D.dwWidth  = allocSurface->dwWidth;
102             allocParamsForBuffer2D.dwHeight = allocSurface->dwHeight;
103             allocParamsForBuffer2D.pBufName = "4xME Distortion Buffer";
104             allocParamsForBuffer2D.dwMemType = memType;
105 
106             CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurface(&allocParamsForBuffer2D, allocSurface, SurfaceId::me4xDistortionBuffer));
107         }
108     }
109 
110     if (m_16xMeSupported)
111     {
112         CODECHAL_ENCODE_CHK_NULL_RETURN(allocSurface = MOS_New(MOS_SURFACE));
113         memset((void*)allocSurface, 0, sizeof(MOS_SURFACE));
114         MOS_ZeroMemory(allocSurface, sizeof(MOS_SURFACE));
115 
116         allocSurface->TileType      = MOS_TILE_LINEAR;
117         allocSurface->bArraySpacing = true;
118         allocSurface->Format        = Format_Buffer_2D;
119         allocSurface->dwWidth       = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64);  // MediaBlockRW requires pitch multiple of 64 bytes when linear
120         allocSurface->dwHeight      = (m_downscaledHeightInMb16x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
121         allocSurface->dwPitch       = allocSurface->dwWidth;
122 
123         allocParamsForBuffer2D.dwWidth  = allocSurface->dwWidth;
124         allocParamsForBuffer2D.dwHeight = allocSurface->dwHeight;
125         allocParamsForBuffer2D.pBufName = "16xME MV Data Buffer";
126         allocParamsForBuffer2D.dwMemType = memType;
127 
128         CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurface(&allocParamsForBuffer2D, allocSurface, SurfaceId::me16xMvDataBuffer));
129     }
130 
131     if (m_32xMeSupported)
132     {
133         CODECHAL_ENCODE_CHK_NULL_RETURN(allocSurface = MOS_New(MOS_SURFACE));
134         memset((void*)allocSurface, 0, sizeof(MOS_SURFACE));
135         MOS_ZeroMemory(allocSurface, sizeof(MOS_SURFACE));
136 
137         allocSurface->TileType      = MOS_TILE_LINEAR;
138         allocSurface->bArraySpacing = true;
139         allocSurface->Format        = Format_Buffer_2D;
140         allocSurface->dwWidth       = MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64);  // MediaBlockRW requires pitch multiple of 64 bytes when linear
141         allocSurface->dwHeight      = (m_downscaledHeightInMb32x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
142         allocSurface->dwPitch       = allocSurface->dwWidth;
143 
144         allocParamsForBuffer2D.dwWidth  = allocSurface->dwWidth;
145         allocParamsForBuffer2D.dwHeight = allocSurface->dwHeight;
146         allocParamsForBuffer2D.pBufName = "32xME MV Data Buffer";
147         allocParamsForBuffer2D.dwMemType = memType;
148 
149         CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurface(&allocParamsForBuffer2D, allocSurface, SurfaceId::me32xMvDataBuffer));
150 
151     }
152     return MOS_STATUS_SUCCESS;
153 }
154 
ReleaseResources()155 MOS_STATUS CodechalKernelHme::ReleaseResources()
156 {
157     return MOS_STATUS_SUCCESS;
158 }
159 
AddPerfTag()160 MOS_STATUS CodechalKernelHme::AddPerfTag()
161 {
162     PerfTagSetting perfTag;
163     perfTag.Value             = 0;
164     perfTag.Mode              = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
165     perfTag.CallType          = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL;
166     perfTag.PictureCodingType = m_pictureCodingType;
167     m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
168     // Each ME kernel buffer counts as a separate perf task
169     m_osInterface->pfnResetPerfBufferID(m_osInterface);
170 
171     return MOS_STATUS_SUCCESS;
172 }
173 
GetActiveKernelState()174 MHW_KERNEL_STATE *CodechalKernelHme::GetActiveKernelState()
175 {
176     uint32_t kernelIndex = (m_pictureCodingType == P_TYPE) ? KernelIndex::hmeP : KernelIndex::hmeB;
177     auto it = m_kernelStatePool.find(kernelIndex);
178     if (it != m_kernelStatePool.end())
179     {
180         return it->second;
181     }
182     MHW_KERNEL_STATE *kernelState = nullptr;
183     uint32_t kernelOffset = 0;
184     if (m_pictureCodingType != P_TYPE)
185     {
186         kernelOffset = 1;
187     }
188 
189     CreateKernelState(&kernelState, kernelIndex, ENC_ME, kernelOffset);
190     return kernelState;
191 }
192 
GetMediaStateType()193 CODECHAL_MEDIA_STATE_TYPE CodechalKernelHme::GetMediaStateType()
194 {
195     return  m_32xMeInUse ? CODECHAL_MEDIA_STATE_32X_ME : m_16xMeInUse ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME;
196 }
197 
InitWalkerCodecParams(CODECHAL_WALKER_CODEC_PARAMS & walkerParam)198 MOS_STATUS CodechalKernelHme::InitWalkerCodecParams(CODECHAL_WALKER_CODEC_PARAMS &walkerParam)
199 {
200     uint32_t scalingFactor = m_32xMeInUse ? scalingFactor32X : m_16xMeInUse ? scalingFactor16X : scalingFactor4X;
201     uint32_t xResolution   = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / scalingFactor);
202     uint32_t yResolution   = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scalingFactor);
203 
204     walkerParam.WalkerMode              = m_walkerMode;
205     walkerParam.dwResolutionX           = xResolution;
206     walkerParam.dwResolutionY           = yResolution;
207     walkerParam.bNoDependency           = true;
208     walkerParam.bMbaff                  = m_surfaceParam.mbaffEnabled;
209     walkerParam.bGroupIdSelectSupported = m_groupIdSelectSupported;
210     walkerParam.ucGroupId               = m_groupId;
211 
212     return MOS_STATUS_SUCCESS;
213 }
214 
SendSurfaces(PMOS_COMMAND_BUFFER cmd,MHW_KERNEL_STATE * kernelState)215 MOS_STATUS CodechalKernelHme::SendSurfaces(PMOS_COMMAND_BUFFER cmd, MHW_KERNEL_STATE *kernelState)
216 {
217     if (!(m_4xMeInUse || m_16xMeInUse || m_32xMeInUse))
218     {
219         return MOS_STATUS_INVALID_PARAMETER;
220     }
221 
222     if (m_surfaceParam.vdencStreamInEnabled)
223     {
224         CODECHAL_ENCODE_CHK_NULL_RETURN(m_surfaceParam.meVdencStreamInBuffer);
225     }
226     else
227     {
228         CODECHAL_ENCODE_CHK_NULL_RETURN(m_surfaceParam.meBrcDistortionBuffer);
229     }
230 
231     PMOS_SURFACE currScaledSurface;
232     uint32_t     refScaledBottomFieldOffset = 0;
233     bool         currFieldPicture           = CodecHal_PictureIsField(*(m_surfaceParam.currOriginalPic)) ? true : false;
234     bool         currBottomField            = CodecHal_PictureIsBottomField(*(m_surfaceParam.currOriginalPic)) ? true : false;
235     uint8_t      currVDirection             = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
236 
237     CODECHAL_SURFACE_CODEC_PARAMS surfaceParams;
238     MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
239 
240     surfaceParams.bIs2DSurface          = true;
241     surfaceParams.bMediaBlockRW         = true;
242     surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
243     surfaceParams.dwBindingTableOffset  = BindingTableOffset::meOutputMvDataSurface;
244     surfaceParams.bIsWritable           = true;
245     surfaceParams.bRenderTarget         = true;
246 
247     if (m_32xMeInUse)
248     {
249         currScaledSurface       = m_encoder->m_trackedBuf->Get32xDsSurface(CODEC_CURR_TRACKED_BUFFER);
250         surfaceParams.psSurface = GetSurface(SurfaceId::me32xMvDataBuffer);
251         surfaceParams.dwOffset  = m_32xMeMvBottomFieldOffset;
252     }
253     else if (m_16xMeInUse)
254     {
255         currScaledSurface       = m_encoder->m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER);
256         surfaceParams.psSurface = GetSurface(SurfaceId::me16xMvDataBuffer);
257         surfaceParams.dwOffset  = m_16xMeMvBottomFieldOffset;
258     }
259     else
260     {
261         currScaledSurface       = m_encoder->m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER);
262         surfaceParams.psSurface = GetSurface(SurfaceId::me4xMvDataBuffer);
263         surfaceParams.dwOffset  = m_4xMeMvBottomFieldOffset;
264     }
265 
266     // Force the values
267     CODECHAL_ENCODE_CHK_NULL_RETURN(surfaceParams.psSurface);
268     surfaceParams.psSurface->dwWidth  = MOS_ALIGN_CEIL(m_surfaceParam.downScaledWidthInMb * 32, 64);
269     surfaceParams.psSurface->dwHeight = m_surfaceParam.downScaledHeightInMb * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER;
270     surfaceParams.psSurface->dwPitch = surfaceParams.psSurface->dwWidth;
271 
272     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
273         m_hwInterface,
274         cmd,
275         &surfaceParams,
276         kernelState));
277 
278     if (m_16xMeInUse && Is32xMeEnabled())
279     {
280         // Pass 32x MV to 16x ME operation
281         MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
282         surfaceParams.bIs2DSurface          = true;
283         surfaceParams.bMediaBlockRW         = true;
284         surfaceParams.psSurface             = GetSurface(SurfaceId::me32xMvDataBuffer);
285         surfaceParams.dwOffset              = currBottomField ? m_32xMeMvBottomFieldOffset : 0;
286         surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE].Value;
287         surfaceParams.dwBindingTableOffset  = BindingTableOffset::meInputMvDataSurface;
288         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
289             m_hwInterface,
290             cmd,
291             &surfaceParams,
292             kernelState));
293     }
294     else if (Is16xMeEnabled() && !m_32xMeInUse)
295     {
296         // Pass 16x MV to 4x ME operation
297         MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
298         surfaceParams.bIs2DSurface          = true;
299         surfaceParams.bMediaBlockRW         = true;
300         surfaceParams.psSurface             = GetSurface(SurfaceId::me16xMvDataBuffer);
301         surfaceParams.dwOffset              = currBottomField ? m_16xMeMvBottomFieldOffset : 0;
302         surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE].Value;
303         surfaceParams.dwBindingTableOffset  = BindingTableOffset::meInputMvDataSurface;
304         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
305             m_hwInterface,
306             cmd,
307             &surfaceParams,
308             kernelState));
309     }
310 
311     // Insert Distortion buffers only for 4xMe case
312     if (m_4xMeInUse)
313     {
314         if (!m_surfaceParam.vdencStreamInEnabled)
315         {
316             MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
317             surfaceParams.bIs2DSurface = true;
318             surfaceParams.bMediaBlockRW = true;
319             surfaceParams.psSurface = m_surfaceParam.meBrcDistortionBuffer;
320             surfaceParams.dwOffset = m_surfaceParam.meBrcDistortionBottomFieldOffset;
321             surfaceParams.dwBindingTableOffset = BindingTableOffset::meBrcDistortion;
322             surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE].Value;
323             surfaceParams.bIsWritable = true;
324             surfaceParams.bRenderTarget = true;
325             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
326                 m_hwInterface,
327                 cmd,
328                 &surfaceParams,
329                 kernelState));
330         }
331 
332         if (m_4xMeDistortionBufferSupported)
333         {
334             MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
335             surfaceParams.bIs2DSurface = true;
336             surfaceParams.bMediaBlockRW = true;
337             surfaceParams.psSurface = GetSurface(SurfaceId::me4xDistortionBuffer);
338             CODECHAL_ENCODE_CHK_NULL_RETURN(surfaceParams.psSurface);
339             surfaceParams.psSurface->dwHeight = m_surfaceParam.downScaledHeightInMb * 4 * 10;
340             surfaceParams.dwOffset = m_meDistortionBottomFieldOffset;
341             surfaceParams.dwBindingTableOffset = BindingTableOffset::meDistortionSurface;
342             surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
343             surfaceParams.bIsWritable = true;
344             surfaceParams.bRenderTarget = true;
345             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
346                 m_hwInterface,
347                 cmd,
348                 &surfaceParams,
349                 kernelState));
350         }
351     }
352 
353     // Setup references 1...n
354     // LIST 0 references
355     CODEC_PICTURE refPic;
356     // Reference height and width information should be taken from the current scaled surface rather
357     // than from the reference scaled surface in the case of PAFF.
358     MOS_SURFACE refScaledSurface = *currScaledSurface;
359 
360     uint8_t fwdRefBTOffset[8];
361     fwdRefBTOffset[0] = BindingTableOffset::meFwdRefIdx0;
362     fwdRefBTOffset[1] = BindingTableOffset::meFwdRefIdx1;
363     fwdRefBTOffset[2] = BindingTableOffset::meFwdRefIdx2;
364     fwdRefBTOffset[3] = BindingTableOffset::meFwdRefIdx3;
365     fwdRefBTOffset[4] = BindingTableOffset::meFwdRefIdx4;
366     fwdRefBTOffset[5] = BindingTableOffset::meFwdRefIdx5;
367     fwdRefBTOffset[6] = BindingTableOffset::meFwdRefIdx6;
368     fwdRefBTOffset[7] = BindingTableOffset::meFwdRefIdx7;
369 
370     for (uint8_t refIdx = 0; refIdx <= m_surfaceParam.numRefIdxL0ActiveMinus1; refIdx++)
371     {
372         refPic = m_surfaceParam.refL0List[refIdx];
373 
374         if (!CodecHal_PictureIsInvalid(refPic) && m_surfaceParam.picIdx[refPic.FrameIdx].bValid)
375         {
376             if (refIdx == 0)
377             {
378                 // Current Picture Y - VME
379                 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
380                 surfaceParams.bUseAdvState          = true;
381                 surfaceParams.psSurface             = currScaledSurface;
382                 surfaceParams.dwOffset              = currBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
383                 surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
384                 surfaceParams.dwBindingTableOffset  = BindingTableOffset::meCurrForFwdRef;
385                 surfaceParams.ucVDirection          = currVDirection;
386                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
387                     m_hwInterface,
388                     cmd,
389                     &surfaceParams,
390                     kernelState));
391             }
392 
393             bool    refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
394             uint8_t refPicIdx      = m_surfaceParam.picIdx[refPic.FrameIdx].ucPicIdx;
395             uint8_t scaledIdx      = m_surfaceParam.refList[refPicIdx]->ucScalingIdx;
396 
397             if (m_32xMeInUse)
398             {
399                 MOS_SURFACE* p32xSurface = m_encoder->m_trackedBuf->Get32xDsSurface(scaledIdx);
400                 if (p32xSurface != nullptr)
401                 {
402                     refScaledSurface.OsResource = p32xSurface->OsResource;
403                 }
404                 else
405                 {
406                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
407                 }
408                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
409             }
410             else if (m_16xMeInUse)
411             {
412                 MOS_SURFACE* p16xSurface = m_encoder->m_trackedBuf->Get16xDsSurface(scaledIdx);
413                 if (p16xSurface != nullptr)
414                 {
415                     refScaledSurface.OsResource = p16xSurface->OsResource;
416                 }
417                 else
418                 {
419                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
420                 }
421                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
422             }
423             else
424             {
425                 MOS_SURFACE* p4xSurface = m_encoder->m_trackedBuf->Get4xDsSurface(scaledIdx);
426                 if (p4xSurface != nullptr)
427                 {
428                     refScaledSurface.OsResource = p4xSurface->OsResource;
429                 }
430                 else
431                 {
432                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
433                 }
434                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
435             }
436             // L0 Reference Picture Y - VME
437             MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
438             surfaceParams.bUseAdvState          = true;
439             surfaceParams.psSurface             = &refScaledSurface;
440             surfaceParams.dwOffset              = refBottomField ? refScaledBottomFieldOffset : 0;
441             surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
442             surfaceParams.dwBindingTableOffset  = fwdRefBTOffset[refIdx];
443             surfaceParams.ucVDirection          = !currFieldPicture ? CODECHAL_VDIRECTION_FRAME :
444                                                   ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
445             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
446                 m_hwInterface,
447                 cmd,
448                 &surfaceParams,
449                 kernelState));
450         }
451     }
452 
453     // Setup references 1...n
454     // LIST 1 references
455     uint8_t bwdRefBTOffset[2];
456     bwdRefBTOffset[0] = BindingTableOffset::meBwdRefIdx0;
457     bwdRefBTOffset[1] = BindingTableOffset::meBwdRefIdx1;
458 
459     for (uint8_t refIdx = 0; refIdx <= m_surfaceParam.numRefIdxL1ActiveMinus1; refIdx++)
460     {
461         refPic = m_surfaceParam.refL1List[refIdx];
462 
463         if (!CodecHal_PictureIsInvalid(refPic) && m_surfaceParam.picIdx[refPic.FrameIdx].bValid)
464         {
465             if (refIdx == 0)
466             {
467                 // Current Picture Y - VME
468                 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
469                 surfaceParams.bUseAdvState          = true;
470                 surfaceParams.psSurface             = currScaledSurface;
471                 surfaceParams.dwOffset              = currBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
472                 surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
473                 surfaceParams.dwBindingTableOffset  = BindingTableOffset::meCurrForBwdRef;
474                 surfaceParams.ucVDirection          = currVDirection;
475                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
476                     m_hwInterface,
477                     cmd,
478                     &surfaceParams,
479                     kernelState));
480             }
481 
482             bool    refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false;
483             uint8_t refPicIdx      = m_surfaceParam.picIdx[refPic.FrameIdx].ucPicIdx;
484             uint8_t scaledIdx      = m_surfaceParam.refList[refPicIdx]->ucScalingIdx;
485             if (m_32xMeInUse)
486             {
487                 MOS_SURFACE* p32xSurface = m_encoder->m_trackedBuf->Get32xDsSurface(scaledIdx);
488                 if (p32xSurface != nullptr)
489                 {
490                     refScaledSurface.OsResource = p32xSurface->OsResource;
491                 }
492                 else
493                 {
494                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
495                 }
496                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
497             }
498             else if (m_16xMeInUse)
499             {
500                 MOS_SURFACE* p16xSurface = m_encoder->m_trackedBuf->Get16xDsSurface(scaledIdx);
501                 if (p16xSurface != nullptr)
502                 {
503                     refScaledSurface.OsResource = p16xSurface->OsResource;
504                 }
505                 else
506                 {
507                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
508                 }
509                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
510             }
511             else
512             {
513                 MOS_SURFACE* p4xSurface = m_encoder->m_trackedBuf->Get4xDsSurface(scaledIdx);
514                 if (p4xSurface != nullptr)
515                 {
516                     refScaledSurface.OsResource = p4xSurface->OsResource;
517                 }
518                 else
519                 {
520                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
521                 }
522                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
523             }
524             // L1 Reference Picture Y - VME
525             MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
526             surfaceParams.bUseAdvState          = true;
527             surfaceParams.psSurface             = &refScaledSurface;
528             surfaceParams.dwOffset              = refBottomField ? refScaledBottomFieldOffset : 0;
529             surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
530             surfaceParams.dwBindingTableOffset  = bwdRefBTOffset[refIdx];
531             surfaceParams.ucVDirection          = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
532             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
533                 m_hwInterface,
534                 cmd,
535                 &surfaceParams,
536                 kernelState));
537         }
538     }
539 
540     return MOS_STATUS_SUCCESS;
541 }
542 
Execute(CurbeParam & curbeParam,SurfaceParams & surfaceParam,HmeLevel hmeLevel)543 MOS_STATUS CodechalKernelHme::Execute(CurbeParam &curbeParam, SurfaceParams &surfaceParam, HmeLevel hmeLevel)
544 {
545     m_4xMeInUse = Is4xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel4x) != 0 : false;
546     m_16xMeInUse = Is16xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel16x) != 0  : false;
547     m_32xMeInUse = Is32xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel32x) != 0 : false;
548 
549     MOS_SecureMemcpy(&m_curbeParam, sizeof(m_curbeParam), &curbeParam, sizeof(m_curbeParam));
550     MOS_SecureMemcpy(&m_surfaceParam, sizeof(m_surfaceParam), &surfaceParam, sizeof(m_surfaceParam));
551 
552     CODECHAL_ENCODE_CHK_STATUS_RETURN(Run());
553     return MOS_STATUS_SUCCESS;
554 }
555 
556 #if USE_CODECHAL_DEBUG_TOOL
DumpKernelOutput()557 MOS_STATUS CodechalKernelHme::DumpKernelOutput()
558 {
559     if (!Is4xMeEnabled())
560     {
561         return MOS_STATUS_SUCCESS;
562     }
563     PMOS_SURFACE surface = nullptr;
564     CODECHAL_MEDIA_STATE_TYPE mediaState = GetMediaStateType();
565     surface = GetSurface(SurfaceId::me4xMvDataBuffer);
566     if (surface)
567     {
568         m_debugInterface->DumpBuffer(&surface->OsResource,
569             CodechalDbgAttr::attrOutput,
570             "_MvData",
571             surface->dwWidth*surface->dwPitch,
572             m_4xMeMvBottomFieldOffset,
573             mediaState);
574     }
575     surface = GetSurface(SurfaceId::me16xMvDataBuffer);
576     if (surface)
577     {
578         m_debugInterface->DumpBuffer(&surface->OsResource,
579             CodechalDbgAttr::attrOutput,
580             "_MvData",
581             surface->dwWidth*surface->dwPitch,
582             m_16xMeMvBottomFieldOffset,
583             mediaState);
584     }
585     surface = GetSurface(SurfaceId::me32xMvDataBuffer);
586     if (surface)
587     {
588         m_debugInterface->DumpBuffer(&surface->OsResource,
589             CodechalDbgAttr::attrOutput,
590             "_MvData",
591             surface->dwWidth*surface->dwPitch,
592             m_32xMeMvBottomFieldOffset,
593             mediaState);
594     }
595     surface = GetSurface(SurfaceId::me4xDistortionBuffer);
596     if (surface)
597     {
598         m_debugInterface->DumpBuffer(&surface->OsResource,
599             CodechalDbgAttr::attrOutput,
600             "_Distortion",
601             surface->dwWidth*surface->dwPitch,
602             m_meDistortionBottomFieldOffset,
603             mediaState);
604     }
605 
606     if (m_surfaceParam.meBrcDistortionBuffer)
607     {
608         m_debugInterface->DumpBuffer(&m_surfaceParam.meBrcDistortionBuffer->OsResource,
609             CodechalDbgAttr::attrOutput,
610             "_BrcDistortion",
611             m_surfaceParam.meBrcDistortionBuffer->dwWidth*m_surfaceParam.meBrcDistortionBuffer->dwPitch,
612             m_surfaceParam.meBrcDistortionBottomFieldOffset,
613             mediaState);
614     }
615     return MOS_STATUS_SUCCESS;
616 }
617 #endif
618