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