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