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_g9.cpp
24 //! \brief    Hme kernel implementation for Gen9 platform
25 //!
26 
27 #include "codechal_kernel_hme_g9.h"
28 
29 // clang-format off
30 const uint32_t CodechalKernelHmeG9::Curbe::m_initCurbe[39] =
31 {
32     0x00000000, 0x00200008, 0x00003939, 0x77a43000, 0x00000000, 0x28300000, 0x00000000, 0x00000000,
33     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
34     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
35     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
36     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
37 };
38 // clang-format on
39 
CodechalKernelHmeG9(CodechalEncoderState * encoder,bool me4xDistBufferSupported)40 CodechalKernelHmeG9::CodechalKernelHmeG9(
41     CodechalEncoderState *encoder,
42     bool     me4xDistBufferSupported)
43         : CodechalKernelHme(encoder, me4xDistBufferSupported)
44 {
45 }
46 
SetCurbe(MHW_KERNEL_STATE * kernelState)47 MOS_STATUS CodechalKernelHmeG9::SetCurbe(MHW_KERNEL_STATE *kernelState)
48 {
49     CODECHAL_ENCODE_CHK_NULL_RETURN(kernelState);
50 
51     Curbe     curbe;
52     uint32_t  mvShiftFactor       = 0;
53     uint32_t  prevMvReadPosFactor = 0;
54     uint32_t  scaleFactor;
55     bool      useMvFromPrevStep;
56     bool      writeDistortions;
57 
58     if (m_32xMeInUse)
59     {
60         useMvFromPrevStep   = false;
61         writeDistortions    = false;
62         scaleFactor         = scalingFactor32X;
63         mvShiftFactor       = 1;
64         prevMvReadPosFactor = 0;
65     }
66     else if (m_16xMeInUse)
67     {
68         useMvFromPrevStep   = Is32xMeEnabled() ? true : false;
69         writeDistortions    = false;
70         scaleFactor         = scalingFactor16X;
71         mvShiftFactor       = 2;
72         prevMvReadPosFactor = 1;
73     }
74     else if (m_4xMeInUse)
75     {
76         useMvFromPrevStep   = Is16xMeEnabled() ? true : false;
77         writeDistortions    = true;
78         scaleFactor         = scalingFactor4X;
79         mvShiftFactor       = 2;
80         prevMvReadPosFactor = 0;
81     }
82     else
83     {
84         return MOS_STATUS_INVALID_PARAMETER;
85     }
86 
87     curbe.m_data.DW3.SubPelMode = m_curbeParam.subPelMode;
88 
89     if (m_fieldScalingOutputInterleaved)
90     {
91         curbe.m_data.DW3.SrcAccess = curbe.m_data.DW3.RefAccess = CodecHal_PictureIsField(m_curbeParam.currOriginalPic);
92         curbe.m_data.DW7.SrcFieldPolarity                = CodecHal_PictureIsBottomField(m_curbeParam.currOriginalPic);
93     }
94     curbe.m_data.DW4.PictureHeightMinus1 = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scaleFactor) - 1;
95     curbe.m_data.DW4.PictureWidth        = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth / scaleFactor);
96     curbe.m_data.DW5.QpPrimeY            = m_curbeParam.qpPrimeY;
97     curbe.m_data.DW6.WriteDistortions    = writeDistortions;
98     curbe.m_data.DW6.UseMvFromPrevStep   = useMvFromPrevStep;
99     curbe.m_data.DW6.SuperCombineDist    = SuperCombineDist[m_curbeParam.targetUsage];
100     curbe.m_data.DW6.MaxVmvR             = 512;// For HEVC G9 CModel match
101 
102     if (m_pictureCodingType == B_TYPE)
103     {
104         curbe.m_data.DW1.BiWeight             = 32;
105         curbe.m_data.DW13.NumRefIdxL1MinusOne = m_curbeParam.numRefIdxL1Minus1;
106     }
107 
108     if (m_pictureCodingType == B_TYPE ||
109         m_pictureCodingType == P_TYPE)
110     {
111         curbe.m_data.DW13.NumRefIdxL0MinusOne = m_curbeParam.numRefIdxL0Minus1;
112 
113         if (Is16xMeEnabled() && m_surfaceParam.vdencStreamInEnabled)
114         {
115             curbe.m_data.DW30.ActualMBHeight = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight);
116             curbe.m_data.DW30.ActualMBWidth  = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth);
117         }
118     }
119 
120     curbe.m_data.DW13.RefStreaminCost = 0;
121     // This flag is to indicate the ROI source type instead of indicating ROI is enabled or not
122     curbe.m_data.DW13.ROIEnable = 0;
123 
124     if (!CodecHal_PictureIsFrame(m_curbeParam.currOriginalPic))
125     {
126         if (m_pictureCodingType != I_TYPE)
127         {
128             curbe.m_data.DW14.List0RefID0FieldParity = m_curbeParam.list0RefID0FieldParity;
129             curbe.m_data.DW14.List0RefID1FieldParity = m_curbeParam.list0RefID1FieldParity;
130             curbe.m_data.DW14.List0RefID2FieldParity = m_curbeParam.list0RefID2FieldParity;
131             curbe.m_data.DW14.List0RefID3FieldParity = m_curbeParam.list0RefID3FieldParity;
132             curbe.m_data.DW14.List0RefID4FieldParity = m_curbeParam.list0RefID4FieldParity;
133             curbe.m_data.DW14.List0RefID5FieldParity = m_curbeParam.list0RefID5FieldParity;
134             curbe.m_data.DW14.List0RefID6FieldParity = m_curbeParam.list0RefID6FieldParity;
135             curbe.m_data.DW14.List0RefID7FieldParity = m_curbeParam.list0RefID7FieldParity;
136         }
137         if (m_pictureCodingType == B_TYPE)
138         {
139             curbe.m_data.DW14.List1RefID0FieldParity = m_curbeParam.list1RefID0FieldParity;
140             curbe.m_data.DW14.List1RefID1FieldParity = m_curbeParam.list1RefID1FieldParity;
141         }
142     }
143     curbe.m_data.DW15.MvShiftFactor       = mvShiftFactor;
144     curbe.m_data.DW15.PrevMvReadPosFactor = prevMvReadPosFactor;
145 
146     // r3 & r4
147     uint8_t methodIndex;
148     if (m_pictureCodingType == B_TYPE)
149     {
150         CODECHAL_ENCODE_CHK_NULL_RETURN(m_bmeMethodTable);
151         methodIndex = m_curbeParam.bmeMethodTable ?
152             m_curbeParam.bmeMethodTable[m_curbeParam.targetUsage] : m_bmeMethodTable[m_curbeParam.targetUsage];
153     }
154     else
155     {
156         CODECHAL_ENCODE_CHK_NULL_RETURN(m_meMethodTable);
157         methodIndex = m_curbeParam.meMethodTable ?
158             m_curbeParam.meMethodTable[m_curbeParam.targetUsage] : m_meMethodTable[m_curbeParam.targetUsage];
159     }
160 
161     uint8_t tableIndex = (m_pictureCodingType == B_TYPE) ? 1 : 0;
162     MOS_SecureMemcpy(&curbe.m_data.SpDelta, 14 * sizeof(uint32_t), codechalEncodeSearchPath[tableIndex][methodIndex], 14 * sizeof(uint32_t));
163 
164     //r5
165     curbe.m_data.DW32._4xMeMvOutputDataSurfIndex      = BindingTableOffset::meOutputMvDataSurface;
166     curbe.m_data.DW33._16xOr32xMeMvInputDataSurfIndex = BindingTableOffset::meInputMvDataSurface;
167     curbe.m_data.DW34._4xMeOutputDistSurfIndex        = BindingTableOffset::meDistortionSurface;
168     curbe.m_data.DW35._4xMeOutputBrcDistSurfIndex     = BindingTableOffset::meBrcDistortion;
169     curbe.m_data.DW36.VMEFwdInterPredictionSurfIndex  = BindingTableOffset::meCurrForFwdRef;
170     curbe.m_data.DW37.VMEBwdInterPredictionSurfIndex  = BindingTableOffset::meCurrForBwdRef;
171     //curbe.m_data.DW38.VDEncStreamInSurfIndex          = BindingTableOffset::meVdencStreamInOutputBuffer;
172 
173     CODECHAL_ENCODE_CHK_STATUS_RETURN(kernelState->m_dshRegion.AddData(&curbe.m_data, kernelState->dwCurbeOffset, Curbe::m_curbeSize));
174 
175     return MOS_STATUS_SUCCESS;
176 }
177 
SendSurfaces(PMOS_COMMAND_BUFFER cmd,MHW_KERNEL_STATE * kernelState)178 MOS_STATUS CodechalKernelHmeG9::SendSurfaces(PMOS_COMMAND_BUFFER cmd, MHW_KERNEL_STATE *kernelState)
179 {
180     if (!(m_4xMeInUse || m_16xMeInUse || m_32xMeInUse))
181     {
182         return MOS_STATUS_INVALID_PARAMETER;
183     }
184 
185     if (m_surfaceParam.vdencStreamInEnabled)
186     {
187         CODECHAL_ENCODE_CHK_NULL_RETURN(m_surfaceParam.meVdencStreamInBuffer);
188     }
189     else
190     {
191         CODECHAL_ENCODE_CHK_NULL_RETURN(m_surfaceParam.meBrcDistortionBuffer);
192     }
193 
194     PMOS_SURFACE currScaledSurface;
195     uint32_t     refScaledBottomFieldOffset = 0;
196     bool         currFieldPicture = CodecHal_PictureIsField(*(m_surfaceParam.currOriginalPic)) ? true : false;
197     bool         currBottomField = CodecHal_PictureIsBottomField(*(m_surfaceParam.currOriginalPic)) ? true : false;
198     uint8_t      currVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
199 
200     CODECHAL_SURFACE_CODEC_PARAMS surfaceParams;
201     MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
202 
203     surfaceParams.bIs2DSurface = true;
204     surfaceParams.bMediaBlockRW = true;
205     surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
206     surfaceParams.dwBindingTableOffset = BindingTableOffset::meOutputMvDataSurface;
207     surfaceParams.bIsWritable = true;
208     surfaceParams.bRenderTarget = true;
209 
210     if (m_32xMeInUse)
211     {
212         currScaledSurface = m_encoder->m_trackedBuf->Get32xDsSurface(CODEC_CURR_TRACKED_BUFFER);
213         surfaceParams.psSurface = GetSurface(SurfaceId::me32xMvDataBuffer);
214         surfaceParams.dwOffset = m_32xMeMvBottomFieldOffset;
215     }
216     else if (m_16xMeInUse)
217     {
218         currScaledSurface = m_encoder->m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER);
219         surfaceParams.psSurface = GetSurface(SurfaceId::me16xMvDataBuffer);
220         surfaceParams.dwOffset = m_16xMeMvBottomFieldOffset;
221     }
222     else
223     {
224         currScaledSurface = m_encoder->m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER);
225         surfaceParams.psSurface = GetSurface(SurfaceId::me4xMvDataBuffer);
226         surfaceParams.dwOffset = m_4xMeMvBottomFieldOffset;
227     }
228 
229     // Force the values
230     CODECHAL_ENCODE_CHK_NULL_RETURN(surfaceParams.psSurface);
231     surfaceParams.psSurface->dwWidth = MOS_ALIGN_CEIL(m_surfaceParam.downScaledWidthInMb * 32, 64);
232     surfaceParams.psSurface->dwHeight = m_surfaceParam.downScaledHeightInMb * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER;
233     surfaceParams.psSurface->dwPitch = surfaceParams.psSurface->dwWidth;
234 
235     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
236         m_hwInterface,
237         cmd,
238         &surfaceParams,
239         kernelState));
240 
241     if (m_16xMeInUse && Is32xMeEnabled())
242     {
243         // Pass 32x MV to 16x ME operation
244         MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
245         surfaceParams.bIs2DSurface = true;
246         surfaceParams.bMediaBlockRW = true;
247         surfaceParams.psSurface = GetSurface(SurfaceId::me32xMvDataBuffer);
248         surfaceParams.dwOffset = currBottomField ? m_32xMeMvBottomFieldOffset : 0;
249         surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
250         surfaceParams.dwBindingTableOffset = BindingTableOffset::meInputMvDataSurface;
251         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
252             m_hwInterface,
253             cmd,
254             &surfaceParams,
255             kernelState));
256     }
257     else if (Is16xMeEnabled() && !m_32xMeInUse)
258     {
259         // Pass 16x MV to 4x ME operation
260         MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
261         surfaceParams.bIs2DSurface = true;
262         surfaceParams.bMediaBlockRW = true;
263         surfaceParams.psSurface = GetSurface(SurfaceId::me16xMvDataBuffer);
264         surfaceParams.dwOffset = currBottomField ? m_16xMeMvBottomFieldOffset : 0;
265         surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
266         surfaceParams.dwBindingTableOffset = BindingTableOffset::meInputMvDataSurface;
267         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
268             m_hwInterface,
269             cmd,
270             &surfaceParams,
271             kernelState));
272     }
273 
274     // Insert Distortion buffers only for 4xMe case
275     if (m_4xMeInUse)
276     {
277         if (!m_surfaceParam.vdencStreamInEnabled)
278         {
279             MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
280             surfaceParams.bIs2DSurface = true;
281             surfaceParams.bMediaBlockRW = true;
282             surfaceParams.psSurface = m_surfaceParam.meBrcDistortionBuffer;
283             surfaceParams.dwOffset = m_surfaceParam.meBrcDistortionBottomFieldOffset;
284             surfaceParams.dwBindingTableOffset = BindingTableOffset::meBrcDistortion;
285             surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value;
286             surfaceParams.bIsWritable = true;
287             surfaceParams.bRenderTarget = true;
288             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
289                 m_hwInterface,
290                 cmd,
291                 &surfaceParams,
292                 kernelState));
293         }
294 
295         if (m_4xMeDistortionBufferSupported)
296         {
297             MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
298             surfaceParams.bIs2DSurface = true;
299             surfaceParams.bMediaBlockRW = true;
300             surfaceParams.psSurface = GetSurface(SurfaceId::me4xDistortionBuffer);
301             CODECHAL_ENCODE_CHK_NULL_RETURN(surfaceParams.psSurface);
302             surfaceParams.psSurface->dwHeight = m_surfaceParam.downScaledHeightInMb * 4 * 10;
303             surfaceParams.dwOffset = m_meDistortionBottomFieldOffset;
304             surfaceParams.dwBindingTableOffset = BindingTableOffset::meDistortionSurface;
305             surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
306             surfaceParams.bIsWritable = true;
307             surfaceParams.bRenderTarget = true;
308             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
309                 m_hwInterface,
310                 cmd,
311                 &surfaceParams,
312                 kernelState));
313         }
314     }
315 
316     // Setup references 1...n
317     // LIST 0 references
318     CODEC_PICTURE refPic;
319     // Reference height and width information should be taken from the current scaled surface rather
320     // than from the reference scaled surface in the case of PAFF.
321     MOS_SURFACE refScaledSurface = *currScaledSurface;
322 
323     uint8_t fwdRefBTOffset[8];
324     fwdRefBTOffset[0] = BindingTableOffset::meFwdRefIdx0;
325     fwdRefBTOffset[1] = BindingTableOffset::meFwdRefIdx1;
326     fwdRefBTOffset[2] = BindingTableOffset::meFwdRefIdx2;
327     fwdRefBTOffset[3] = BindingTableOffset::meFwdRefIdx3;
328     fwdRefBTOffset[4] = BindingTableOffset::meFwdRefIdx4;
329     fwdRefBTOffset[5] = BindingTableOffset::meFwdRefIdx5;
330     fwdRefBTOffset[6] = BindingTableOffset::meFwdRefIdx6;
331     fwdRefBTOffset[7] = BindingTableOffset::meFwdRefIdx7;
332 
333     for (uint8_t refIdx = 0; refIdx <= m_surfaceParam.numRefIdxL0ActiveMinus1; refIdx++)
334     {
335         refPic = m_surfaceParam.refL0List[refIdx];
336 
337         if (!CodecHal_PictureIsInvalid(refPic) && m_surfaceParam.picIdx[refPic.FrameIdx].bValid)
338         {
339             if (refIdx == 0)
340             {
341                 // Current Picture Y - VME
342                 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
343                 surfaceParams.bUseAdvState = true;
344                 surfaceParams.psSurface = currScaledSurface;
345                 surfaceParams.dwOffset = currBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
346                 surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
347                 surfaceParams.dwBindingTableOffset = BindingTableOffset::meCurrForFwdRef;
348                 surfaceParams.ucVDirection = currVDirection;
349                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
350                     m_hwInterface,
351                     cmd,
352                     &surfaceParams,
353                     kernelState));
354             }
355 
356             bool    refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
357             uint8_t refPicIdx = m_surfaceParam.picIdx[refPic.FrameIdx].ucPicIdx;
358             uint8_t scaledIdx = m_surfaceParam.refList[refPicIdx]->ucScalingIdx;
359             if (m_32xMeInUse)
360             {
361                 MOS_SURFACE* p32xSurface = m_encoder->m_trackedBuf->Get32xDsSurface(scaledIdx);
362                 if (p32xSurface != nullptr)
363                 {
364                     refScaledSurface.OsResource = p32xSurface->OsResource;
365                 }
366                 else
367                 {
368                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
369                 }
370                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
371             }
372             else if (m_16xMeInUse)
373             {
374                 MOS_SURFACE* p16xSurface = m_encoder->m_trackedBuf->Get16xDsSurface(scaledIdx);
375                 if (p16xSurface != nullptr)
376                 {
377                     refScaledSurface.OsResource = p16xSurface->OsResource;
378                 }
379                 else
380                 {
381                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
382                 }
383                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
384             }
385             else
386             {
387                 MOS_SURFACE* p4xSurface = m_encoder->m_trackedBuf->Get4xDsSurface(scaledIdx);
388                 if (p4xSurface != nullptr)
389                 {
390                     refScaledSurface.OsResource = p4xSurface->OsResource;
391                 }
392                 else
393                 {
394                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
395                 }
396                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
397             }
398 
399             // L0 Reference Picture Y - VME
400             MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
401             surfaceParams.bUseAdvState = true;
402             surfaceParams.psSurface = &refScaledSurface;
403             surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0;
404             surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
405             surfaceParams.dwBindingTableOffset = fwdRefBTOffset[refIdx];
406             surfaceParams.ucVDirection = !currFieldPicture ? CODECHAL_VDIRECTION_FRAME :
407                 ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
408             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
409                 m_hwInterface,
410                 cmd,
411                 &surfaceParams,
412                 kernelState));
413         }
414     }
415 
416     // Setup references 1...n
417     // LIST 1 references
418     uint8_t bwdRefBTOffset[2];
419     bwdRefBTOffset[0] = BindingTableOffset::meBwdRefIdx0;
420     bwdRefBTOffset[1] = BindingTableOffset::meBwdRefIdx1;
421 
422     for (uint8_t refIdx = 0; refIdx <= m_surfaceParam.numRefIdxL1ActiveMinus1; refIdx++)
423     {
424         refPic = m_surfaceParam.refL1List[refIdx];
425 
426         if (!CodecHal_PictureIsInvalid(refPic) && m_surfaceParam.picIdx[refPic.FrameIdx].bValid)
427         {
428             if (refIdx == 0)
429             {
430                 // Current Picture Y - VME
431                 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
432                 surfaceParams.bUseAdvState = true;
433                 surfaceParams.psSurface = currScaledSurface;
434                 surfaceParams.dwOffset = currBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
435                 surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
436                 surfaceParams.dwBindingTableOffset = BindingTableOffset::meCurrForBwdRef;
437                 surfaceParams.ucVDirection = currVDirection;
438                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
439                     m_hwInterface,
440                     cmd,
441                     &surfaceParams,
442                     kernelState));
443             }
444 
445             bool    refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false;
446             uint8_t refPicIdx = m_surfaceParam.picIdx[refPic.FrameIdx].ucPicIdx;
447             uint8_t scaledIdx = m_surfaceParam.refList[refPicIdx]->ucScalingIdx;
448             if (m_32xMeInUse)
449             {
450                 MOS_SURFACE* p32xSurface = m_encoder->m_trackedBuf->Get32xDsSurface(scaledIdx);
451                 if (p32xSurface != nullptr)
452                 {
453                     refScaledSurface.OsResource = p32xSurface->OsResource;
454                 }
455                 else
456                 {
457                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
458                 }
459                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
460             }
461             else if (m_16xMeInUse)
462             {
463                 MOS_SURFACE* p16xSurface = m_encoder->m_trackedBuf->Get16xDsSurface(scaledIdx);
464                 if (p16xSurface != nullptr)
465                 {
466                     refScaledSurface.OsResource = p16xSurface->OsResource;
467                 }
468                 else
469                 {
470                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
471                 }
472                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
473             }
474             else
475             {
476                 MOS_SURFACE* p4xSurface = m_encoder->m_trackedBuf->Get4xDsSurface(scaledIdx);
477                 if (p4xSurface != nullptr)
478                 {
479                     refScaledSurface.OsResource = p4xSurface->OsResource;
480                 }
481                 else
482                 {
483                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
484                 }
485                 refScaledBottomFieldOffset = refBottomField ? m_surfaceParam.downScaledBottomFieldOffset : 0;
486             }
487             // L1 Reference Picture Y - VME
488             MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
489             surfaceParams.bUseAdvState = true;
490             surfaceParams.psSurface = &refScaledSurface;
491             surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0;
492             surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
493             surfaceParams.dwBindingTableOffset = bwdRefBTOffset[refIdx];
494             surfaceParams.ucVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
495             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
496                 m_hwInterface,
497                 cmd,
498                 &surfaceParams,
499                 kernelState));
500         }
501     }
502 
503     if (GetMediaStateType() == CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN)
504     {
505         MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
506         surfaceParams.dwSize                = m_surfaceParam.vdencStreamInSurfaceSize;
507         surfaceParams.bIs2DSurface          = false;
508         surfaceParams.presBuffer            = m_surfaceParam.meVdencStreamInBuffer;
509         surfaceParams.dwBindingTableOffset  = BindingTableOffset::meVdencStreamInOutputBuffer;
510         surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value;
511         surfaceParams.bIsWritable           = true;
512         surfaceParams.bRenderTarget         = true;
513         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
514             m_hwInterface,
515             cmd,
516             &surfaceParams,
517             kernelState));
518     }
519     return MOS_STATUS_SUCCESS;
520 }
521 
GetActiveKernelState()522 MHW_KERNEL_STATE *CodechalKernelHmeG9::GetActiveKernelState()
523 {
524     EncOperation operation;
525 
526     uint32_t kernelOffset = 0;
527     uint32_t kernelIndex;
528 
529     if (m_pictureCodingType == P_TYPE)
530     {
531         kernelIndex  = KernelIndex::hmeP;
532         operation    = ENC_ME;
533         kernelOffset = 0;
534     }
535     else
536     {
537         kernelIndex  = KernelIndex::hmeB;
538         operation    = ENC_ME;
539         kernelOffset = 1;
540     }
541     if (m_vdencEnabled && m_4xMeInUse)
542     {
543         kernelIndex  = KernelIndex::hmeVDEncStreamIn;
544         operation    = VDENC_ME;
545         kernelOffset = 0;
546     }
547 
548     auto it = m_kernelStatePool.find(kernelIndex);
549     if (it != m_kernelStatePool.end())
550     {
551         return it->second;
552     }
553     MHW_KERNEL_STATE *kernelState = nullptr;
554     CreateKernelState(&kernelState, kernelIndex, operation, kernelOffset);
555 
556     return kernelState;
557 }
558 
GetMediaStateType()559 CODECHAL_MEDIA_STATE_TYPE CodechalKernelHmeG9::GetMediaStateType()
560 {
561     CODECHAL_MEDIA_STATE_TYPE mediaStateType;
562     mediaStateType = m_32xMeInUse ? CODECHAL_MEDIA_STATE_32X_ME : m_16xMeInUse ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME;
563     if (m_surfaceParam.vdencStreamInEnabled && m_4xMeInUse)
564     {
565         mediaStateType = CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN;
566     }
567 
568     return mediaStateType;
569 }
570