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