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