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