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