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