1 /*
2 * Copyright (c) 2017-2019, 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_g12.cpp
24 //! \brief Hme kernel implementation using MDF RT for Gen12 platform
25 //!
26 #include "codechal_kernel_hme_mdf_g12.h"
27 #include "Gen12LP_hme_genx.h"
28
29 // clang-format off
30 const uint32_t CodechalKernelHmeMdfG12::Curbe::m_initCurbe[40] =
31 {
32 0x00000000, 0x00200010, 0x00003939, 0x77a43000, 0x00000000, 0x28300000, 0x00000000, 0x00000000,
33 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000200,
34 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
35 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
36 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
37 };
38 // clang-format on
39
CodechalKernelHmeMdfG12(CodechalEncoderState * encoder,bool me4xDistBufferSupported)40 CodechalKernelHmeMdfG12::CodechalKernelHmeMdfG12(
41 CodechalEncoderState *encoder,
42 bool me4xDistBufferSupported)
43 : CodechalKernelHme(encoder, me4xDistBufferSupported)
44 {
45 }
46
~CodechalKernelHmeMdfG12()47 CodechalKernelHmeMdfG12::~CodechalKernelHmeMdfG12()
48 {
49 }
50
ReleaseResources()51 MOS_STATUS CodechalKernelHmeMdfG12::ReleaseResources()
52 {
53 CODECHAL_ENCODE_FUNCTION_ENTER;
54
55 DestroyYUVSurfaces(m_HME4xYUVInfo);
56 DestroyYUVSurfaces(m_HME16xYUVInfo);
57 DestroyYUVSurfaces(m_HME32xYUVInfo);
58
59 CmDevice* &cmDev = m_encoder->m_cmDev;
60
61 if (m_HME4xDistortionSurface)
62 {
63 cmDev->DestroySurface(m_HME4xDistortionSurface);
64 m_HME4xDistortionSurface = nullptr;
65 }
66
67 if (m_HME4xMVSurface)
68 {
69 cmDev->DestroySurface(m_HME4xMVSurface);
70 m_HME4xMVSurface = nullptr;
71 }
72
73 if (m_HME16xMVSurface)
74 {
75 cmDev->DestroySurface(m_HME16xMVSurface);
76 m_HME16xMVSurface = nullptr;
77 }
78
79 if (m_HME32xMVSurface)
80 {
81 cmDev->DestroySurface(m_HME32xMVSurface);
82 m_HME32xMVSurface = nullptr;
83 }
84
85 if (m_VdencStreamInBuffer)
86 {
87 cmDev->DestroySurface(m_VdencStreamInBuffer);
88 m_VdencStreamInBuffer = nullptr;
89 }
90
91 if (m_SumMvandDistortionBuffer)
92 {
93 cmDev->DestroySurface(m_SumMvandDistortionBuffer);
94 m_SumMvandDistortionBuffer = nullptr;
95 }
96
97 if (m_threadSpace4x)
98 {
99 cmDev->DestroyThreadSpace(m_threadSpace4x);
100 m_threadSpace4x = nullptr;
101 }
102
103 if (m_threadSpace16x)
104 {
105 cmDev->DestroyThreadSpace(m_threadSpace16x);
106 m_threadSpace16x = nullptr;
107 }
108
109 if (m_threadSpace32x)
110 {
111 cmDev->DestroyThreadSpace(m_threadSpace32x);
112 m_threadSpace32x = nullptr;
113 }
114
115 if (m_cmKrnME4xP)
116 {
117 (cmDev->DestroyKernel(m_cmKrnME4xP));
118 m_cmKrnME4xP = nullptr;
119 }
120
121 if (m_cmKrnME16xP)
122 {
123 (cmDev->DestroyKernel(m_cmKrnME16xP));
124 m_cmKrnME16xP = nullptr;
125 }
126
127 if (m_cmKrnME32xP)
128 {
129 (cmDev->DestroyKernel(m_cmKrnME32xP));
130 m_cmKrnME32xP = nullptr;
131 }
132
133 if (m_cmKrnME4xB)
134 {
135 (cmDev->DestroyKernel(m_cmKrnME4xB));
136 m_cmKrnME4xB = nullptr;
137 }
138
139 if (m_cmKrnME16xB)
140 {
141 (cmDev->DestroyKernel(m_cmKrnME16xB));
142 m_cmKrnME16xB = nullptr;
143 }
144
145 if (m_cmKrnME32xB)
146 {
147 (cmDev->DestroyKernel(m_cmKrnME32xB));
148 m_cmKrnME32xB = nullptr;
149 }
150
151 if (m_cmProgramME)
152 {
153 (cmDev->DestroyProgram(m_cmProgramME));
154 m_cmProgramME = nullptr;
155 }
156
157 return MOS_STATUS_SUCCESS;
158 }
DestroyYUVSurfaces(HmeYUVInfo & YUVInfo)159 MOS_STATUS CodechalKernelHmeMdfG12::DestroyYUVSurfaces(HmeYUVInfo& YUVInfo)
160 {
161 CmDevice* &cmDev = m_encoder->m_cmDev;
162 if (YUVInfo.SrcSurface)
163 {
164 YUVInfo.SrcSurface->NotifyUmdResourceChanged(nullptr);
165 cmDev->DestroySurface(YUVInfo.SrcSurface);
166 YUVInfo.SrcSurface = nullptr;
167 }
168
169 for (uint8_t i = 0; i < MAX_HME_BWD_REF; i++)
170 {
171 if (YUVInfo.BwdReference[i])
172 {
173 YUVInfo.BwdReference[i]->NotifyUmdResourceChanged(nullptr);
174 cmDev->DestroySurface(YUVInfo.BwdReference[i]);
175 YUVInfo.BwdReference[i] = nullptr;
176 }
177 }
178
179 for (uint8_t i = 0; i < MAX_HME_FWD_REF; i++)
180 {
181 if (YUVInfo.FwdReference[i])
182 {
183 YUVInfo.FwdReference[i]->NotifyUmdResourceChanged(nullptr);
184 cmDev->DestroySurface(YUVInfo.FwdReference[i]);
185 YUVInfo.FwdReference[i] = nullptr;
186 }
187 }
188
189 return MOS_STATUS_SUCCESS;
190 }
191
192
Execute(CurbeParam & curbeParam,SurfaceParams & surfaceParam,HmeLevel hmeLevel)193 MOS_STATUS CodechalKernelHmeMdfG12::Execute(CurbeParam &curbeParam, SurfaceParams &surfaceParam, HmeLevel hmeLevel)
194 {
195 CODECHAL_ENCODE_FUNCTION_ENTER;
196
197 m_4xMeInUse = Is4xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel4x) != 0 : false;
198 m_16xMeInUse = Is16xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel16x) != 0 : false;
199 m_32xMeInUse = Is32xMeEnabled() ? (hmeLevel & HmeLevel::hmeLevel32x) != 0 : false;
200
201 CmDevice* &cmDev = m_encoder->m_cmDev;
202
203 MOS_SecureMemcpy(&m_curbeParam, sizeof(m_curbeParam), &curbeParam, sizeof(m_curbeParam));
204 MOS_SecureMemcpy(&m_surfaceParam, sizeof(m_surfaceParam), &surfaceParam, sizeof(m_surfaceParam));
205
206 InitKernelState((void *)GEN12LP_HME_GENX, GEN12LP_HME_GENX_SIZE);
207
208 SetupSurfaces();
209
210 AddPerfTag();
211
212 uint32_t scalingFactor = m_32xMeInUse ? scalingFactor32X : m_16xMeInUse ? scalingFactor16X : scalingFactor4X;
213 uint32_t xResolution = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / scalingFactor);
214 uint32_t yResolution = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / scalingFactor);
215
216 CmThreadSpace *threadSpace = nullptr;
217 CmKernel *cmKrn = nullptr;
218
219 uint32_t threadCount = xResolution * yResolution;
220
221 if (m_16xMeInUse)
222 {
223 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateThreadSpace(
224 xResolution,
225 yResolution,
226 m_threadSpace16x));
227 threadSpace = m_threadSpace16x;
228 cmKrn = m_cmKrnME16x;
229 }
230 else if (m_32xMeInUse)
231 {
232 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateThreadSpace(
233 xResolution,
234 yResolution,
235 m_threadSpace32x));
236 threadSpace = m_threadSpace32x;
237 cmKrn = m_cmKrnME32x;
238 }
239 else
240 {
241 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateThreadSpace(
242 xResolution,
243 yResolution,
244 m_threadSpace4x));
245 threadSpace = m_threadSpace4x;
246 cmKrn = m_cmKrnME4x;
247 }
248
249 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKrn->SetThreadCount(threadCount));
250
251 if (m_groupIdSelectSupported)
252 {
253 threadSpace->SetMediaWalkerGroupSelect((CM_MW_GROUP_SELECT)m_groupId);
254 }
255
256 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKrn->AssociateThreadSpace(threadSpace));
257
258 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupKernelArgs(cmKrn));
259
260 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmTask->AddKernel(cmKrn));
261
262 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
263 {
264 CmEvent * event = CM_NO_EVENT;
265 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmQueue->EnqueueFast(m_encoder->m_cmTask, event));
266
267 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmTask->Reset());
268
269 m_lastTaskInPhase = false;
270 }
271 else
272 {
273 m_encoder->m_cmTask->AddSync();
274 }
275
276 return MOS_STATUS_SUCCESS;
277 }
278
GetCmSurface(uint32_t surfaceId)279 CmSurface2D* CodechalKernelHmeMdfG12::GetCmSurface(uint32_t surfaceId)
280 {
281 switch (surfaceId)
282 {
283 case SurfaceId::me4xMvDataBuffer:
284 return m_HME4xMVSurface;
285 break;
286 case SurfaceId::me16xMvDataBuffer:
287 return m_HME16xMVSurface;
288 break;
289 case SurfaceId::me32xMvDataBuffer:
290 return m_HME32xMVSurface;
291 break;
292 case SurfaceId::me4xDistortionBuffer:
293 return m_HME4xDistortionSurface;
294 break;
295 };
296 return nullptr;
297 }
298
AllocateResources()299 MOS_STATUS CodechalKernelHmeMdfG12::AllocateResources()
300 {
301 MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
302 PMOS_SURFACE allocSurface = nullptr;
303 CmDevice* &cmDev = m_encoder->m_cmDev;
304
305 if (m_4xMeSupported)
306 {
307 if (!m_HME4xMVSurface)
308 {
309 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateSurface2D(
310 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64), // MediaBlockRW requires pitch multiple of 64 bytes when linear.,
311 (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER),
312 CM_SURFACE_FORMAT_A8,
313 m_HME4xMVSurface));
314 }
315
316 if (m_4xMeDistortionBufferSupported)
317 {
318 uint32_t ajustedHeight =
319 m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT * SCALE_FACTOR_4x;
320 uint32_t downscaledFieldHeightInMB4x =
321 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(((ajustedHeight + 1) >> 1) / 4);
322 if (!m_HME4xDistortionSurface)
323 {
324 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateSurface2D(
325 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64),
326 (2 * MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x * 4 * 10), 8)),
327 CM_SURFACE_FORMAT_A8,
328 m_HME4xDistortionSurface));
329 }
330 }
331 }
332
333 if (m_16xMeSupported)
334 {
335 if (!m_HME16xMVSurface)
336 {
337 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateSurface2D(
338 MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64), // MediaBlockRW requires pitch multiple of 64 bytes when linear,
339 (m_downscaledHeightInMb16x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER),
340 CM_SURFACE_FORMAT_A8,
341 m_HME16xMVSurface));
342 }
343 }
344
345 if (m_32xMeSupported)
346 {
347 if (!m_HME32xMVSurface)
348 {
349 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateSurface2D(
350 MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64), // MediaBlockRW requires pitch multiple of 64 bytes when linear
351 (m_downscaledHeightInMb32x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER),
352 CM_SURFACE_FORMAT_A8,
353 m_HME32xMVSurface));
354 }
355 }
356 return MOS_STATUS_SUCCESS;
357 }
358
359
InitKernelState(void * kernelIsa,uint32_t kernelIsaSize)360 MOS_STATUS CodechalKernelHmeMdfG12::InitKernelState(void *kernelIsa, uint32_t kernelIsaSize)
361 {
362 CODECHAL_ENCODE_FUNCTION_ENTER;
363
364 if (!m_cmProgramME)
365 {
366 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->LoadProgram(kernelIsa,
367 kernelIsaSize,
368 m_cmProgramME,
369 "-nojitter"));
370
371 if (m_vdencEnabled)
372 {
373 if (m_standard == CODECHAL_AVC)
374 {
375 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_VDENC_STREAMIN", m_cmKrnME4xP));
376 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_VDENC_STREAMIN", m_cmKrnME4xB));
377 }
378 else
379 {
380 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_VDENC_STREAMIN_HEVC", m_cmKrnME4xP));
381 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_VDENC_STREAMIN_HEVC", m_cmKrnME4xB));
382 }
383 }
384 else
385 {
386 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_P", m_cmKrnME4xP));
387 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_B", m_cmKrnME4xB));
388 }
389
390 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_B", m_cmKrnME16xB));
391 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_B", m_cmKrnME32xB));
392
393 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_P", m_cmKrnME16xP));
394 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgramME, "HME_P", m_cmKrnME32xP));
395 }
396
397 if ((m_pictureCodingType == B_TYPE) && (!m_noMEKernelForPFrame))
398 {
399 m_cmKrnME4x = m_cmKrnME4xB;
400 m_cmKrnME16x = m_cmKrnME16xB;
401 m_cmKrnME32x = m_cmKrnME32xB;
402 }
403 else
404 {
405 m_cmKrnME4x = m_cmKrnME4xP;
406 m_cmKrnME16x = m_cmKrnME16xP;
407 m_cmKrnME32x = m_cmKrnME32xP;
408 }
409
410 return MOS_STATUS_SUCCESS;
411 }
412
SetMECurbe(Curbe & curbe)413 MOS_STATUS CodechalKernelHmeMdfG12::SetMECurbe(Curbe& curbe)
414 {
415
416 uint32_t mvShiftFactor = 0;
417 uint32_t prevMvReadPosFactor = 0;
418 uint32_t scaleFactor;
419 bool useMvFromPrevStep;
420 bool writeDistortions;
421
422 if (m_32xMeInUse)
423 {
424 useMvFromPrevStep = false;
425 writeDistortions = false;
426 scaleFactor = scalingFactor32X;
427 mvShiftFactor = 1;
428 prevMvReadPosFactor = 0;
429 }
430 else if (m_16xMeInUse)
431 {
432 useMvFromPrevStep = Is32xMeEnabled() ? true : false;
433 writeDistortions = false;
434 scaleFactor = scalingFactor16X;
435 mvShiftFactor = 2;
436 prevMvReadPosFactor = 1;
437 }
438 else if (m_4xMeInUse)
439 {
440 useMvFromPrevStep = Is16xMeEnabled() ? true : false;
441 writeDistortions = true;
442 scaleFactor = scalingFactor4X;
443 mvShiftFactor = 2;
444 prevMvReadPosFactor = 0;
445 }
446 else
447 {
448 return MOS_STATUS_INVALID_PARAMETER;
449 }
450
451 curbe.m_data.DW3.SubPelMode = m_curbeParam.subPelMode;
452
453 if (m_fieldScalingOutputInterleaved)
454 {
455 curbe.m_data.DW3.SrcAccess = curbe.m_data.DW3.RefAccess = CodecHal_PictureIsField(m_curbeParam.currOriginalPic);
456 curbe.m_data.DW7.SrcFieldPolarity = CodecHal_PictureIsBottomField(m_curbeParam.currOriginalPic);
457 }
458 curbe.m_data.DW4.PictureHeightMinus1 = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scaleFactor) - 1;
459 curbe.m_data.DW4.PictureWidth = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth / scaleFactor);
460 curbe.m_data.DW5.QpPrimeY = m_curbeParam.qpPrimeY;
461 curbe.m_data.DW6.WriteDistortions = writeDistortions;
462 curbe.m_data.DW6.UseMvFromPrevStep = useMvFromPrevStep;
463 curbe.m_data.DW6.SuperCombineDist = SuperCombineDist[m_curbeParam.targetUsage];
464 curbe.m_data.DW6.MaxVmvR = CodecHal_PictureIsFrame(m_curbeParam.currOriginalPic) ? m_curbeParam.maxMvLen * 4 : (m_curbeParam.maxMvLen >> 1) * 4;
465
466 if (m_pictureCodingType == B_TYPE)
467 {
468 curbe.m_data.DW1.BiWeight = 32;
469 curbe.m_data.DW13.NumRefIdxL1MinusOne = m_curbeParam.numRefIdxL1Minus1;
470 }
471
472 if (m_pictureCodingType == B_TYPE || m_pictureCodingType == P_TYPE)
473 {
474 if (m_vdencEnabled && Is16xMeEnabled())
475 {
476 curbe.m_data.DW30.ActualMBHeight = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight);
477 curbe.m_data.DW30.ActualMBWidth = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth);
478 }
479 curbe.m_data.DW13.NumRefIdxL0MinusOne = m_curbeParam.numRefIdxL0Minus1;
480 }
481
482 curbe.m_data.DW13.RefStreaminCost = 5;
483 // This flag is to indicate the ROI source type instead of indicating ROI is enabled or not
484 curbe.m_data.DW13.ROIEnable = 0;
485
486 if (!CodecHal_PictureIsFrame(m_curbeParam.currOriginalPic))
487 {
488 if (m_pictureCodingType != I_TYPE)
489 {
490 curbe.m_data.DW14.List0RefID0FieldParity = m_curbeParam.list0RefID0FieldParity;
491 curbe.m_data.DW14.List0RefID1FieldParity = m_curbeParam.list0RefID1FieldParity;
492 curbe.m_data.DW14.List0RefID2FieldParity = m_curbeParam.list0RefID2FieldParity;
493 curbe.m_data.DW14.List0RefID3FieldParity = m_curbeParam.list0RefID3FieldParity;
494 curbe.m_data.DW14.List0RefID4FieldParity = m_curbeParam.list0RefID4FieldParity;
495 curbe.m_data.DW14.List0RefID5FieldParity = m_curbeParam.list0RefID5FieldParity;
496 curbe.m_data.DW14.List0RefID6FieldParity = m_curbeParam.list0RefID6FieldParity;
497 curbe.m_data.DW14.List0RefID7FieldParity = m_curbeParam.list0RefID7FieldParity;
498 }
499 if (m_pictureCodingType == B_TYPE)
500 {
501 curbe.m_data.DW14.List1RefID0FieldParity = m_curbeParam.list1RefID0FieldParity;
502 curbe.m_data.DW14.List1RefID1FieldParity = m_curbeParam.list1RefID1FieldParity;
503 }
504 }
505 curbe.m_data.DW15.MvShiftFactor = mvShiftFactor;
506 curbe.m_data.DW15.PrevMvReadPosFactor = prevMvReadPosFactor;
507
508 if (m_4xMeInUse && m_curbeParam.brcEnable) // HME kernel generates Sum MV and Distortion for Hevc dual pipe
509 {
510 curbe.m_data.DW5.SumMVThreshold = m_curbeParam.sumMVThreshold; // As per kernel requirement, used only when BRC is on/LTR is on
511 curbe.m_data.DW6.BRCEnable = m_curbeParam.brcEnable;
512 }
513
514 // r3 & r4
515 uint8_t methodIndex = 0; // kernel requirement
516 uint8_t tableIndex = (m_pictureCodingType == B_TYPE) ? 1 : 0;
517
518 MOS_SecureMemcpy(&curbe.m_data.SpDelta, 14 * sizeof(uint32_t), codechalEncodeSearchPath[tableIndex][methodIndex], 14 * sizeof(uint32_t));
519
520 return MOS_STATUS_SUCCESS;
521 }
522
SetupSurfaces()523 MOS_STATUS CodechalKernelHmeMdfG12::SetupSurfaces()
524 {
525 if (!(m_4xMeInUse || m_16xMeInUse || m_32xMeInUse))
526 {
527 return MOS_STATUS_INVALID_PARAMETER;
528 }
529
530 if (m_surfaceParam.vdencStreamInEnabled)
531 {
532 CODECHAL_ENCODE_CHK_NULL_RETURN(m_surfaceParam.meVdencStreamInBuffer);
533 }
534 else
535 {
536 CODECHAL_ENCODE_CHK_NULL_RETURN(m_surfaceParam.meBrcDistortionBuffer);
537 }
538
539 CmDevice* &cmDev = m_encoder->m_cmDev;
540
541 PMOS_SURFACE currScaledSurface;
542
543 uint32_t refScaledBottomFieldOffset = 0;
544 bool currFieldPicture = CodecHal_PictureIsField(*(m_surfaceParam.currOriginalPic)) ? true : false;
545 bool currBottomField = CodecHal_PictureIsBottomField(*(m_surfaceParam.currOriginalPic)) ? true : false;
546 uint8_t currVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
547
548 HmeYUVInfo *YuvInfo = nullptr;
549 PMOS_SURFACE psurface = nullptr;
550
551 if (m_32xMeInUse)
552 {
553 currScaledSurface = m_encoder->m_trackedBuf->Get32xDsSurface(CODEC_CURR_TRACKED_BUFFER);
554 YuvInfo = &m_HME32xYUVInfo;
555 }
556 else if (m_16xMeInUse)
557 {
558 currScaledSurface = m_encoder->m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER);
559 YuvInfo = &m_HME16xYUVInfo;
560 }
561 else
562 {
563 currScaledSurface = m_encoder->m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER);
564 YuvInfo = &m_HME4xYUVInfo;
565 }
566
567 // Current Picture Y - VME
568 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->UpdateSurface2D(
569 &currScaledSurface->OsResource,
570 YuvInfo->SrcSurface));
571
572 // Setup references 1...n
573 // LIST 0 references
574 CODEC_PICTURE refPic;
575 // NOTE; keeping some of the legacy comments below. This may help if MDF RT is extended to AVC
576
577 // Reference height and width information should be taken from the current scaled surface rather
578 // than from the reference scaled surface in the case of PAFF.
579 MOS_SURFACE refScaledSurface = *currScaledSurface;
580 for (uint8_t refIdx = 0; refIdx <= m_surfaceParam.numRefIdxL0ActiveMinus1; refIdx++)
581 {
582 refPic = m_surfaceParam.refL0List[refIdx];
583
584 if (!CodecHal_PictureIsInvalid(refPic) && m_surfaceParam.picIdx[refPic.FrameIdx].bValid)
585 {
586 bool refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
587 uint8_t refPicIdx = m_surfaceParam.picIdx[refPic.FrameIdx].ucPicIdx;
588 uint8_t scaledIdx = m_surfaceParam.refList[refPicIdx]->ucScalingIdx;
589 if (m_32xMeInUse)
590 {
591 MOS_SURFACE* p32xSurface = m_encoder->m_trackedBuf->Get32xDsSurface(scaledIdx);
592 if (p32xSurface != nullptr)
593 {
594 refScaledSurface.OsResource = p32xSurface->OsResource;
595 }
596 else
597 {
598 CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
599 }
600 }
601 else if (m_16xMeInUse)
602 {
603 MOS_SURFACE* p16xSurface = m_encoder->m_trackedBuf->Get16xDsSurface(scaledIdx);
604 if (p16xSurface != nullptr)
605 {
606 refScaledSurface.OsResource = p16xSurface->OsResource;
607 }
608 else
609 {
610 CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
611 }
612 }
613 else
614 {
615 MOS_SURFACE* p4xSurface = m_encoder->m_trackedBuf->Get4xDsSurface(scaledIdx);
616 if (p4xSurface != nullptr)
617 {
618 refScaledSurface.OsResource = p4xSurface->OsResource;
619 }
620 else
621 {
622 CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
623 }
624 }
625 // L0 Reference Picture Y - VME
626 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->UpdateSurface2D(
627 &refScaledSurface.OsResource,
628 YuvInfo->FwdReference[refIdx]));
629 }
630 }
631
632 if (YuvInfo->VMEFwdIdx)
633 {
634 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->DestroyVmeSurfaceG7_5(YuvInfo->VMEFwdIdx));
635 YuvInfo->VMEFwdIdx = nullptr;
636 }
637 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateVmeSurfaceG7_5(
638 YuvInfo->SrcSurface,
639 YuvInfo->FwdReference,
640 YuvInfo->FwdReference,
641 (m_surfaceParam.numRefIdxL0ActiveMinus1 + 1),
642 (m_surfaceParam.numRefIdxL0ActiveMinus1 + 1),
643 YuvInfo->VMEFwdIdx));
644 // Setup references 1...n
645 // LIST 1 references
646 for (uint8_t refIdx = 0; refIdx <= m_surfaceParam.numRefIdxL1ActiveMinus1; refIdx++)
647 {
648 refPic = m_surfaceParam.refL1List[refIdx];
649 if (!CodecHal_PictureIsInvalid(refPic) && m_surfaceParam.picIdx[refPic.FrameIdx].bValid)
650 {
651 bool refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false;
652 uint8_t refPicIdx = m_surfaceParam.picIdx[refPic.FrameIdx].ucPicIdx;
653 uint8_t scaledIdx = m_surfaceParam.refList[refPicIdx]->ucScalingIdx;
654 if (m_32xMeInUse)
655 {
656 MOS_SURFACE* p32xSurface = m_encoder->m_trackedBuf->Get32xDsSurface(scaledIdx);
657 if (p32xSurface != nullptr)
658 {
659 refScaledSurface.OsResource = p32xSurface->OsResource;
660 }
661 else
662 {
663 CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
664 }
665 }
666 else if (m_16xMeInUse)
667 {
668 MOS_SURFACE* p16xSurface = m_encoder->m_trackedBuf->Get16xDsSurface(scaledIdx);
669 if (p16xSurface != nullptr)
670 {
671 refScaledSurface.OsResource = p16xSurface->OsResource;
672 }
673 else
674 {
675 CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
676 }
677 }
678 else
679 {
680 MOS_SURFACE* p4xSurface = m_encoder->m_trackedBuf->Get4xDsSurface(scaledIdx);
681 if (p4xSurface != nullptr)
682 {
683 refScaledSurface.OsResource = p4xSurface->OsResource;
684 }
685 else
686 {
687 CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
688 }
689 }
690 // L1 Reference Picture Y - VME
691 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->UpdateSurface2D(
692 &refScaledSurface.OsResource,
693 YuvInfo->BwdReference[refIdx]));
694 }
695 }
696 if (YuvInfo->VMEBwdIdx)
697 {
698 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->DestroyVmeSurfaceG7_5(YuvInfo->VMEBwdIdx));
699 YuvInfo->VMEBwdIdx = nullptr;
700 }
701 // HME L1, L1 references are provided to kernel/VME as L0
702 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateVmeSurfaceG7_5(
703 YuvInfo->SrcSurface,
704 YuvInfo->BwdReference,
705 YuvInfo->BwdReference,
706 (m_surfaceParam.numRefIdxL1ActiveMinus1 + 1),
707 (m_surfaceParam.numRefIdxL1ActiveMinus1 + 1),
708 YuvInfo->VMEBwdIdx));
709
710 CODECHAL_MEDIA_STATE_TYPE mediaStateType = (m_32xMeInUse) ? CODECHAL_MEDIA_STATE_32X_ME :
711 m_16xMeInUse ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME;
712
713 if ( m_surfaceParam.vdencStreamInEnabled && mediaStateType == CODECHAL_MEDIA_STATE_4X_ME)
714 {
715 mediaStateType = CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN;
716 }
717
718 if (mediaStateType == CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN)
719 {
720 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->UpdateBuffer(
721 m_surfaceParam.meVdencStreamInBuffer,
722 m_VdencStreamInBuffer));
723 }
724
725 if (m_curbeParam.brcEnable && m_4xMeInUse)
726 {
727 if (!m_SumMvandDistortionBuffer)
728 {
729 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateBuffer(
730 &m_surfaceParam.meSumMvandDistortionBuffer.sResource,
731 m_SumMvandDistortionBuffer));
732 }
733 }
734
735 return MOS_STATUS_SUCCESS;
736 }
737
SetupKernelArgs(CmKernel * cmKrn)738 MOS_STATUS CodechalKernelHmeMdfG12::SetupKernelArgs(CmKernel *cmKrn)
739 {
740 int idx = 0;
741 Curbe curbe;
742 if (!(m_4xMeInUse || m_16xMeInUse || m_32xMeInUse))
743 {
744 return MOS_STATUS_INVALID_PARAMETER;
745 }
746 SetMECurbe(curbe);
747 cmKrn->SetKernelArg(idx++, sizeof(Curbe), &curbe);
748 HmeYUVInfo *YuvInfo = nullptr;
749 SurfaceIndex * pSurfIndex = nullptr;
750
751 CODECHAL_DEBUG_TOOL(
752 CODECHAL_MEDIA_STATE_TYPE mediaStateType = (m_32xMeInUse) ? CODECHAL_MEDIA_STATE_32X_ME :
753 m_16xMeInUse ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME;
754 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpMDFCurbe(
755 mediaStateType,
756 (uint8_t *)&curbe,
757 sizeof(curbe)));)
758
759 if (m_32xMeInUse)
760 {
761 m_HME32xMVSurface->GetIndex(pSurfIndex);
762 YuvInfo = &m_HME32xYUVInfo;
763 }
764 else if (m_16xMeInUse)
765 {
766 m_HME16xMVSurface->GetIndex(pSurfIndex);
767 YuvInfo = &m_HME16xYUVInfo;
768 }
769 else
770 {
771 m_HME4xMVSurface->GetIndex(pSurfIndex);
772 YuvInfo = &m_HME4xYUVInfo;
773 }
774 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
775
776 if (m_16xMeInUse && Is32xMeEnabled())
777 {
778 // Pass 32x MV to 16x ME operation
779 m_HME32xMVSurface->GetIndex(pSurfIndex);
780
781 }
782 else if (Is16xMeEnabled() && !m_32xMeInUse)
783 {
784 // Pass 16x MV to 4x ME
785 m_HME16xMVSurface->GetIndex(pSurfIndex);
786 }
787 // else pass same surface index as dummy
788 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
789
790 // Insert Distortion buffers only for 4xMe case
791 if (m_4xMeInUse && m_4xMeDistortionBufferSupported)
792 {
793 m_HME4xDistortionSurface->GetIndex(pSurfIndex);
794 }
795 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
796
797 if (m_4xMeInUse && !m_surfaceParam.vdencStreamInEnabled)
798 {
799 m_surfaceParam.meBrcDistortionSurface->GetIndex(pSurfIndex);
800 }
801 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
802
803 CODECHAL_ENCODE_CHK_NULL_RETURN(YuvInfo->VMEFwdIdx)
804
805 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), YuvInfo->VMEFwdIdx);
806
807 if (m_pictureCodingType == B_TYPE)
808 {
809 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), YuvInfo->VMEBwdIdx);
810 }
811 else
812 {
813 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), (SurfaceIndex *)CM_NULL_SURFACE);
814 }
815
816 if (m_surfaceParam.vdencStreamInEnabled && m_4xMeInUse)
817 {
818 m_VdencStreamInBuffer->GetIndex(pSurfIndex);
819 }
820 //set surface for vdenc streamin
821 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
822
823 // hevc vdenc streamin. no separate buffer created for now
824 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
825
826
827 if (m_curbeParam.brcEnable && m_4xMeInUse)
828 {
829 m_SumMvandDistortionBuffer->GetIndex(pSurfIndex);
830 }
831 //set surface for Sum MV distortion buffer
832 cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
833
834
835 return MOS_STATUS_SUCCESS;
836 }
837