1 /*
2 * Copyright (c) 2017-2020, 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_encode_csc_ds.cpp
24 //! \brief Defines base class for CSC and Downscaling
25 //!
26
27 #include "codechal_encoder_base.h"
28 #include "codechal_encode_csc_ds.h"
29 #include "hal_oca_interface.h"
30
AllocateSurfaceCsc()31 MOS_STATUS CodechalEncodeCscDs::AllocateSurfaceCsc()
32 {
33 CODECHAL_ENCODE_FUNCTION_ENTER;
34
35 if (!m_cscFlag)
36 {
37 return MOS_STATUS_SUCCESS;
38 }
39
40 return m_encoder->m_trackedBuf->AllocateSurfaceCsc();
41 }
42
CheckRawColorFormat(MOS_FORMAT format,MOS_TILE_TYPE tileType)43 MOS_STATUS CodechalEncodeCscDs::CheckRawColorFormat(MOS_FORMAT format, MOS_TILE_TYPE tileType)
44 {
45 CODECHAL_ENCODE_FUNCTION_ENTER;
46
47 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
48
49 // check input color format, and set target traverse thread space size
50 switch (format)
51 {
52 case Format_NV12:
53 m_colorRawSurface = cscColorNv12Linear;
54 m_cscRequireColor = 1;
55 m_threadTraverseSizeX = 5; // for NV12, thread space is 32x4
56 break;
57 case Format_YUY2:
58 case Format_YUYV:
59 m_colorRawSurface = cscColorYUY2;
60 m_cscRequireColor = (uint8_t)HCP_CHROMA_FORMAT_YUV420 == m_outputChromaFormat;
61 m_cscRequireConvTo8bPlanar = (uint8_t)HCP_CHROMA_FORMAT_YUV422 == m_outputChromaFormat;
62 m_threadTraverseSizeX = 4; // for YUY2, thread space is 16x4
63 break;
64 case Format_A8R8G8B8:
65 m_colorRawSurface = cscColorARGB;
66 m_cscRequireColor = 1;
67 m_cscUsingSfc = m_cscEnableSfc ? 1 : 0;
68 // Use EU for better performance in big resolution cases or TU1
69 if ((m_cscRawSurfWidth * m_cscRawSurfHeight > 1920 * 1088) || m_16xMeSupported)
70 {
71 m_cscUsingSfc = 0;
72 }
73 m_threadTraverseSizeX = 3; // for ARGB, thread space is 8x4
74 break;
75 case Format_A8B8G8R8:
76 m_colorRawSurface = cscColorABGR;
77 m_cscRequireColor = 1;
78 m_cscUsingSfc = m_cscEnableSfc ? 1 : 0;
79 // Use EU for better performance in big resolution cases or TU1
80 if ((m_cscRawSurfWidth * m_cscRawSurfHeight > 1920 * 1088) || m_16xMeSupported)
81 {
82 m_cscUsingSfc = 0;
83 }
84 m_threadTraverseSizeX = 3; // for ABGR, thread space is 8x4
85 break;
86 case Format_P010:
87 m_colorRawSurface = cscColorP010;
88 m_cscRequireConvTo8bPlanar = 1;
89 break;
90 default:
91 CODECHAL_ENCODE_ASSERTMESSAGE("Input color format = %d not supported!", format);
92 eStatus = MOS_STATUS_INVALID_PARAMETER;
93 break;
94 }
95
96 return eStatus;
97 }
98
InitSfcState()99 MOS_STATUS CodechalEncodeCscDs::InitSfcState()
100 {
101 CODECHAL_ENCODE_FUNCTION_ENTER;
102
103 if (!m_sfcState)
104 {
105 m_sfcState = (CodecHalEncodeSfc*)MOS_New(CodecHalEncodeSfc);
106 CODECHAL_ENCODE_CHK_NULL_RETURN(m_sfcState);
107
108 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_sfcState->Initialize(m_hwInterface, m_osInterface));
109
110 m_sfcState->SetInputColorSpace(MHW_CSpace_sRGB);
111 }
112
113 return MOS_STATUS_SUCCESS;
114 }
115
SetParamsSfc(CODECHAL_ENCODE_SFC_PARAMS * sfcParams)116 MOS_STATUS CodechalEncodeCscDs::SetParamsSfc(CODECHAL_ENCODE_SFC_PARAMS* sfcParams)
117 {
118 CODECHAL_ENCODE_FUNCTION_ENTER;
119
120 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
121
122 CODECHAL_ENCODE_CHK_NULL_RETURN(sfcParams);
123
124 // color space parameters have been set to pSfcState already, no need set here
125 sfcParams->pInputSurface = m_rawSurfaceToEnc;
126 sfcParams->pOutputSurface = m_encoder->m_trackedBuf->GetCscSurface(CODEC_CURR_TRACKED_BUFFER);
127 sfcParams->rcInputSurfaceRegion.X = 0;
128 sfcParams->rcInputSurfaceRegion.Y = 0;
129 sfcParams->rcInputSurfaceRegion.Width = m_cscRawSurfWidth;
130 sfcParams->rcInputSurfaceRegion.Height = m_cscRawSurfHeight;
131
132 sfcParams->rcOutputSurfaceRegion.X = 0;
133 sfcParams->rcOutputSurfaceRegion.Y = 0;
134 sfcParams->rcOutputSurfaceRegion.Width = m_cscRawSurfWidth;
135 sfcParams->rcOutputSurfaceRegion.Height = m_cscRawSurfHeight;
136
137 sfcParams->uiChromaSitingType = MHW_CHROMA_SITING_HORZ_CENTER | MHW_CHROMA_SITING_VERT_CENTER;
138
139 return eStatus;
140 }
141
InitKernelStateCsc()142 MOS_STATUS CodechalEncodeCscDs::InitKernelStateCsc()
143 {
144 CODECHAL_ENCODE_FUNCTION_ENTER;
145
146 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
147
148 auto kernelHeaderTable = (CscKernelHeader*)m_kernelBase;
149 auto currKrnHeader = kernelHeaderTable->header;
150
151 m_cscKernelState->KernelParams.iBTCount = cscNumSurfaces;
152 m_cscKernelState->KernelParams.iThreadCount = m_hwInterface->GetRenderInterface()->GetHwCaps()->dwMaxThreads;
153 m_cscKernelState->KernelParams.iCurbeLength = m_cscCurbeLength;
154 m_cscKernelState->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
155 m_cscKernelState->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
156 m_cscKernelState->KernelParams.iIdCount = 1;
157 m_cscKernelState->KernelParams.iInlineDataLength = 0;
158 m_cscKernelState->dwCurbeOffset = m_stateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
159 m_cscKernelState->KernelParams.pBinary =
160 m_kernelBase + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
161 m_cscKernelState->KernelParams.iSize = m_combinedKernelSize - (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
162
163 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->CalculateSshAndBtSizesRequested(
164 m_cscKernelState->KernelParams.iBTCount,
165 &m_cscKernelState->dwSshSize,
166 &m_cscKernelState->dwBindingTableSize));
167
168 CODECHAL_ENCODE_CHK_NULL_RETURN(m_renderInterface->m_stateHeapInterface);
169 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_renderInterface->m_stateHeapInterface, m_cscKernelState));
170
171 return eStatus;
172 }
173
SetKernelParamsCsc(KernelParams * params)174 MOS_STATUS CodechalEncodeCscDs::SetKernelParamsCsc(KernelParams* params)
175 {
176 CODECHAL_ENCODE_FUNCTION_ENTER;
177
178 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
179
180 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
181
182 /* calling mode for Ds+Copy kernel and/or 4x DS kernel
183 *
184 * For Progressive:
185 * ------------------------------------------------------------------------------------------------
186 * bScalingEnabled cscReqdForRawSurf bFirstField call Ds+Copy kernel? call 4x DS kernel?
187 * ------------------------------------------------------------------------------------------------
188 * 1 0 1 Yes
189 * 1 1 1 COPY_DS mode
190 * 0 0 1
191 * 0 1 1 COPY_ONLY mode
192 *
193 * For Interlaced:
194 * 1 0 1 Yes
195 * 1 1 1 COPY_ONLY mode Yes, see note 2
196 * 0 0 dont care
197 * 0 1 1 COPY_ONLY mode
198 * 0 1 0 do nothing for 2nd field
199 *
200 * Note 1: bFirstField must be == 1 when (1) bScalingEnabled == 1, or (2) Progressive content
201 * Note 2: so far Ds+Copy kernel does not support Interlaced, so we would have to do a COPY_ONLY, followed by 4x DS
202 * these 2 steps can combine into a single COPY_DS once Interlaced is supported
203 */
204
205 m_lastTaskInPhase = params->bLastTaskInPhaseCSC;
206 m_currRefList->b4xScalingUsed = m_scalingEnabled;
207
208 // setup Curbe
209 m_curbeParams.dwInputPictureWidth = m_cscRawSurfWidth;
210 m_curbeParams.dwInputPictureHeight = m_cscRawSurfHeight;
211 m_curbeParams.bFlatnessCheckEnabled = m_flatnessCheckEnabled;
212 m_curbeParams.bMBVarianceOutputEnabled = m_mbStatsEnabled;
213 m_curbeParams.bMBPixelAverageOutputEnabled = m_mbStatsEnabled;
214 m_curbeParams.bCscOrCopyOnly = !m_scalingEnabled || params->cscOrCopyOnly;
215 m_curbeParams.inputColorSpace = params->inputColorSpace;
216
217 // setup surface states
218 m_surfaceParamsCsc.psInputSurface = m_rawSurfaceToEnc;
219 m_surfaceParamsCsc.psOutputCopiedSurface = m_cscFlag ? m_encoder->m_trackedBuf->GetCscSurface(CODEC_CURR_TRACKED_BUFFER) : nullptr;
220 m_surfaceParamsCsc.psOutput4xDsSurface =
221 !m_curbeParams.bCscOrCopyOnly ? m_encoder->m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER) : nullptr;
222
223 if (m_mbStatsSupported)
224 {
225 m_surfaceParamsCsc.bMBVProcStatsEnabled = true;
226 m_surfaceParamsCsc.presMBVProcStatsBuffer = &m_resMbStatsBuffer;
227 }
228 else
229 {
230 m_surfaceParamsCsc.bFlatnessCheckEnabled = m_flatnessCheckEnabled;
231 m_surfaceParamsCsc.psFlatnessCheckSurface = &m_encoder->m_flatnessCheckSurface;
232 }
233
234 // setup walker param
235 m_walkerResolutionX = MOS_ROUNDUP_SHIFT(m_downscaledWidth4x, m_threadTraverseSizeX);
236 m_walkerResolutionY = MOS_ROUNDUP_SHIFT(m_downscaledHeight4x, m_threadTraverseSizeY);
237
238 return eStatus;
239 }
240
SetCurbeCsc()241 MOS_STATUS CodechalEncodeCscDs::SetCurbeCsc()
242 {
243 CODECHAL_ENCODE_FUNCTION_ENTER;
244
245 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
246
247 CscKernelCurbeData curbe;
248
249 curbe.DW0_InputPictureWidth = m_curbeParams.dwInputPictureWidth;
250 curbe.DW0_InputPictureHeight = m_curbeParams.dwInputPictureHeight;
251
252 curbe.DW1_SrcNV12SurfYIndex = cscSrcYPlane;
253 curbe.DW2_DstYSurfIndex = cscDstDsYPlane;
254 curbe.DW3_FlatDstSurfIndex = cscDstFlatOrMbStats;
255 curbe.DW4_CopyDstNV12SurfIndex = cscDstCopyYPlane;
256
257 if (m_curbeParams.bCscOrCopyOnly)
258 {
259 curbe.DW5_CscDsCopyOpCode = 0; // Copy only
260 }
261 else
262 {
263 // Enable DS kernel (0 disable, 1 enable)
264 curbe.DW5_CscDsCopyOpCode = 1; // 0x01 to 0x7F: DS + Copy
265 }
266
267 if (cscColorNv12TileY == m_colorRawSurface ||
268 cscColorNv12Linear == m_colorRawSurface)
269 {
270 curbe.DW5_InputColorFormat = 0;
271 }
272 else if (cscColorYUY2 == m_colorRawSurface)
273 {
274 curbe.DW5_InputColorFormat = 1;
275 }
276 else if (cscColorARGB == m_colorRawSurface)
277 {
278 curbe.DW5_InputColorFormat = 2;
279 }
280
281 if (m_curbeParams.bFlatnessCheckEnabled ||
282 m_curbeParams.bMBVarianceOutputEnabled ||
283 m_curbeParams.bMBPixelAverageOutputEnabled)
284 {
285 curbe.DW6_FlatnessThreshold = 128;
286 curbe.DW7_EnableMBFlatnessCheck = true;
287 }
288 else
289 {
290 curbe.DW7_EnableMBFlatnessCheck = false;
291 }
292
293 curbe.DW8_SrcNV12SurfUVIndex = cscSrcUVPlane;
294
295 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscKernelState->m_dshRegion.AddData(
296 &curbe,
297 m_cscKernelState->dwCurbeOffset,
298 sizeof(curbe)));
299
300 return eStatus;
301 }
302
SendSurfaceCsc(PMOS_COMMAND_BUFFER cmdBuffer)303 MOS_STATUS CodechalEncodeCscDs::SendSurfaceCsc(PMOS_COMMAND_BUFFER cmdBuffer)
304 {
305 CODECHAL_ENCODE_FUNCTION_ENTER;
306
307 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
308
309 // Source surface/s
310 CODECHAL_SURFACE_CODEC_PARAMS surfaceParams;
311 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
312 surfaceParams.bIs2DSurface = true; // linear surface is not 2D -> changed kernel
313 surfaceParams.bUseUVPlane = (cscColorNv12TileY == m_colorRawSurface ||
314 cscColorNv12Linear == m_colorRawSurface);
315 surfaceParams.bMediaBlockRW = true;
316 surfaceParams.psSurface = m_surfaceParamsCsc.psInputSurface;
317 surfaceParams.bUseARGB8Format = true;
318 surfaceParams.dwCacheabilityControl =
319 m_hwInterface->ComposeSurfaceCacheabilityControl(
320 MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE,
321 (codechalL3 | codechalLLC));
322
323 surfaceParams.dwVerticalLineStride = m_verticalLineStride;
324 surfaceParams.dwBindingTableOffset = cscSrcYPlane;
325 surfaceParams.dwUVBindingTableOffset = cscSrcUVPlane;
326 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
327 m_hwInterface,
328 cmdBuffer,
329 &surfaceParams,
330 m_cscKernelState));
331
332 // Destination surface/s - 4x downscaled surface
333 if (m_surfaceParamsCsc.psOutput4xDsSurface)
334 {
335 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
336 surfaceParams.bIs2DSurface =
337 surfaceParams.bIsWritable = true;
338 surfaceParams.psSurface = m_surfaceParamsCsc.psOutput4xDsSurface;
339 surfaceParams.dwCacheabilityControl = m_hwInterface->ComposeSurfaceCacheabilityControl(
340 MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE,
341 codechalLLC);
342 surfaceParams.dwVerticalLineStride = m_verticalLineStride;
343 surfaceParams.dwBindingTableOffset = cscDstDsYPlane;
344 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
345 m_hwInterface,
346 cmdBuffer,
347 &surfaceParams,
348 m_cscKernelState));
349 }
350
351 // FlatnessCheck or MbStats surface
352 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
353 if (m_surfaceParamsCsc.bMBVProcStatsEnabled)
354 {
355 surfaceParams.bRawSurface =
356 surfaceParams.bIsWritable = true;
357 surfaceParams.dwSize = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_surfaceParamsCsc.psInputSurface->dwWidth) *
358 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_surfaceParamsCsc.psInputSurface->dwHeight) * 16 * sizeof(uint32_t);
359 surfaceParams.presBuffer = m_surfaceParamsCsc.presMBVProcStatsBuffer;
360 surfaceParams.dwCacheabilityControl =
361 m_hwInterface->ComposeSurfaceCacheabilityControl(
362 MOS_CODEC_RESOURCE_USAGE_MB_STATS_ENCODE,
363 codechalLLC | codechalL3);
364 surfaceParams.dwBindingTableOffset = cscDstFlatOrMbStats;
365 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
366 m_hwInterface,
367 cmdBuffer,
368 &surfaceParams,
369 m_cscKernelState));
370 }
371 else if (m_surfaceParamsCsc.bFlatnessCheckEnabled)
372 {
373 surfaceParams.bIs2DSurface =
374 surfaceParams.bMediaBlockRW =
375 surfaceParams.bIsWritable = true;
376 surfaceParams.psSurface = m_surfaceParamsCsc.psFlatnessCheckSurface;
377 surfaceParams.dwCacheabilityControl =
378 m_hwInterface->ComposeSurfaceCacheabilityControl(
379 MOS_CODEC_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE,
380 codechalLLC | codechalL3);
381 surfaceParams.dwBindingTableOffset = cscDstFlatOrMbStats;
382 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
383 m_hwInterface,
384 cmdBuffer,
385 &surfaceParams,
386 m_cscKernelState));
387 }
388
389 // copy kernel output luma + chroma
390 if (m_surfaceParamsCsc.psOutputCopiedSurface)
391 {
392 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
393 surfaceParams.bIs2DSurface =
394 surfaceParams.bUseUVPlane =
395 surfaceParams.bMediaBlockRW =
396 surfaceParams.bIsWritable = true;
397 surfaceParams.psSurface = m_surfaceParamsCsc.psOutputCopiedSurface;
398 surfaceParams.dwCacheabilityControl = m_hwInterface->ComposeSurfaceCacheabilityControl(
399 MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE,
400 codechalLLC);
401 surfaceParams.dwBindingTableOffset = cscDstCopyYPlane;
402 surfaceParams.dwUVBindingTableOffset = cscDstCopyUVPlane;
403 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
404 m_hwInterface,
405 cmdBuffer,
406 &surfaceParams,
407 m_cscKernelState));
408 }
409
410 return eStatus;
411 }
412
SetSurfacesToEncPak()413 MOS_STATUS CodechalEncodeCscDs::SetSurfacesToEncPak()
414 {
415 CODECHAL_ENCODE_FUNCTION_ENTER;
416
417 auto cscSurface = m_encoder->m_trackedBuf->GetCscSurface(CODEC_CURR_TRACKED_BUFFER);
418
419 // assign CSC output surface according to different operation
420 if (RenderConsumesCscSurface())
421 {
422 m_rawSurfaceToEnc = cscSurface;
423
424 // update the RawBuffer and RefBuffer (if Raw is used as Ref)
425 m_currRefList->sRefRawBuffer = *cscSurface;
426 if (m_useRawForRef)
427 {
428 m_currRefList->sRefBuffer = *cscSurface;
429 }
430 CODECHAL_ENCODE_NORMALMESSAGE("Set m_rawSurfaceToEnc %d x %d",
431 m_rawSurfaceToEnc->dwWidth, m_rawSurfaceToEnc->dwHeight);
432 }
433
434 if (VdboxConsumesCscSurface())
435 {
436 m_rawSurfaceToPak = cscSurface;
437 CODECHAL_ENCODE_NORMALMESSAGE("Set m_rawSurfaceToPak %d x %d",
438 m_rawSurfaceToPak->dwWidth, m_rawSurfaceToPak->dwHeight);
439 }
440
441 // dump copied surface from Ds+Copy kernel
442 if (m_cscFlag)
443 {
444 CODECHAL_DEBUG_TOOL(
445 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
446 cscSurface,
447 CodechalDbgAttr::attrEncodeRawInputSurface,
448 "Copied_SrcSurf")) // needs to consider YUV420
449 )
450 }
451
452 return MOS_STATUS_SUCCESS;
453 }
454
InitKernelStateDS()455 MOS_STATUS CodechalEncodeCscDs::InitKernelStateDS()
456 {
457 CODECHAL_ENCODE_FUNCTION_ENTER;
458
459 uint32_t kernelSize, combinedKernelSize, numKernelsToLoad;
460
461 numKernelsToLoad = m_encoder->m_interlacedFieldDisabled ? 1 : CODEC_NUM_FIELDS_PER_FRAME;
462
463 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(
464 m_encoder->m_kernelBase,
465 m_encoder->m_kuid,
466 &m_dsKernelBase,
467 &combinedKernelSize));
468
469 CODECHAL_KERNEL_HEADER currKrnHeader;
470 for (uint32_t krnStateIdx = 0; krnStateIdx < numKernelsToLoad; krnStateIdx++)
471 {
472 kernelSize = combinedKernelSize;
473
474 m_dsKernelState = &m_encoder->m_scaling4xKernelStates[krnStateIdx];
475
476 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->pfnGetKernelHeaderAndSize(
477 m_dsKernelBase,
478 ENC_SCALING4X,
479 krnStateIdx,
480 &currKrnHeader,
481 &kernelSize))
482
483 m_dsKernelState->KernelParams.iBTCount = m_dsBTCount[0];
484 m_dsKernelState->KernelParams.iThreadCount = m_renderInterface->GetHwCaps()->dwMaxThreads;
485 m_dsKernelState->KernelParams.iCurbeLength = m_dsCurbeLength[0];
486 m_dsKernelState->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
487 m_dsKernelState->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
488 m_dsKernelState->KernelParams.iIdCount = 1;
489 m_dsKernelState->KernelParams.iInlineDataLength = m_dsInlineDataLength;
490
491 m_dsKernelState->dwCurbeOffset = m_stateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
492 m_dsKernelState->KernelParams.pBinary = m_dsKernelBase + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
493 m_dsKernelState->KernelParams.iSize = kernelSize;
494 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->CalculateSshAndBtSizesRequested(
495 m_dsKernelState->KernelParams.iBTCount,
496 &m_dsKernelState->dwSshSize,
497 &m_dsKernelState->dwBindingTableSize));
498
499 CODECHAL_ENCODE_CHK_NULL_RETURN(m_renderInterface->m_stateHeapInterface);
500 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_renderInterface->m_stateHeapInterface, m_dsKernelState));
501
502 if (m_32xMeSupported)
503 {
504 m_dsKernelState = &m_encoder->m_scaling2xKernelStates[krnStateIdx];
505
506 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->pfnGetKernelHeaderAndSize(
507 m_dsKernelBase,
508 ENC_SCALING2X,
509 krnStateIdx,
510 &currKrnHeader,
511 &kernelSize))
512
513 m_dsKernelState->KernelParams.iBTCount = m_dsBTCount[1];
514 m_dsKernelState->KernelParams.iThreadCount = m_renderInterface->GetHwCaps()->dwMaxThreads;
515 m_dsKernelState->KernelParams.iCurbeLength = m_dsCurbeLength[1];
516 m_dsKernelState->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
517 m_dsKernelState->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
518
519 m_dsKernelState->dwCurbeOffset = m_stateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
520 m_dsKernelState->KernelParams.pBinary = m_dsKernelBase + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
521 m_dsKernelState->KernelParams.iSize = kernelSize;
522 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->CalculateSshAndBtSizesRequested(
523 m_dsKernelState->KernelParams.iBTCount,
524 &m_dsKernelState->dwSshSize,
525 &m_dsKernelState->dwBindingTableSize));
526
527 CODECHAL_ENCODE_CHK_NULL_RETURN(m_renderInterface->m_stateHeapInterface);
528 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_renderInterface->m_stateHeapInterface, m_dsKernelState));
529 }
530
531 if (m_encoder->m_interlacedFieldDisabled)
532 {
533 m_encoder->m_scaling4xKernelStates[1] = m_encoder->m_scaling4xKernelStates[0];
534
535 if (m_32xMeSupported)
536 {
537 m_encoder->m_scaling2xKernelStates[1] = m_encoder->m_scaling2xKernelStates[0];
538 }
539 }
540 }
541
542 return MOS_STATUS_SUCCESS;
543 }
544
SetCurbeDS4x()545 MOS_STATUS CodechalEncodeCscDs::SetCurbeDS4x()
546 {
547 CODECHAL_ENCODE_FUNCTION_ENTER;
548
549 Ds4xKernelCurbeData curbe;
550
551 curbe.DW0_InputPictureWidth = m_curbeParams.dwInputPictureWidth;
552 curbe.DW0_InputPictureHeight = m_curbeParams.dwInputPictureHeight;
553
554 curbe.DW1_InputYBTIFrame = ds4xSrcYPlane;
555 curbe.DW2_OutputYBTIFrame = ds4xDstYPlane;
556
557 if (m_curbeParams.bFieldPicture)
558 {
559 curbe.DW3_InputYBTIBottomField = ds4xSrcYPlaneBtmField;
560 curbe.DW4_OutputYBTIBottomField = ds4xDstYPlaneBtmField;
561 }
562
563 if ((curbe.DW6_EnableMBFlatnessCheck = m_curbeParams.bFlatnessCheckEnabled))
564 {
565 curbe.DW5_FlatnessThreshold = 128;
566 curbe.DW8_FlatnessOutputBTIFrame = ds4xDstFlatness;
567
568 if (m_curbeParams.bFieldPicture)
569 {
570 curbe.DW9_FlatnessOutputBTIBottomField = ds4xDstFlatnessBtmField;
571 }
572 }
573
574 curbe.DW6_EnableMBVarianceOutput = m_curbeParams.bMBVarianceOutputEnabled;
575 curbe.DW6_EnableMBPixelAverageOutput = m_curbeParams.bMBPixelAverageOutputEnabled;
576 curbe.DW6_EnableBlock8x8StatisticsOutput = m_curbeParams.bBlock8x8StatisticsEnabled;
577
578 if (curbe.DW6_EnableMBVarianceOutput || curbe.DW6_EnableMBPixelAverageOutput)
579 {
580 curbe.DW10_MBVProcStatsBTIFrame = ds4xDstMbVProc;
581
582 if (m_curbeParams.bFieldPicture)
583 {
584 curbe.DW11_MBVProcStatsBTIBottomField = ds4xDstMbVProcBtmField;
585 }
586 }
587
588 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_dsKernelState->m_dshRegion.AddData(
589 &curbe,
590 m_dsKernelState->dwCurbeOffset,
591 sizeof(curbe)));
592
593 return MOS_STATUS_SUCCESS;
594 }
595
SetCurbeDS2x()596 MOS_STATUS CodechalEncodeCscDs::SetCurbeDS2x()
597 {
598 CODECHAL_ENCODE_FUNCTION_ENTER;
599
600 Ds2xKernelCurbeData curbe;
601
602 curbe.DW0_InputPictureWidth = m_curbeParams.dwInputPictureWidth;
603 curbe.DW0_InputPictureHeight = m_curbeParams.dwInputPictureHeight;
604
605 curbe.DW8_InputYBTIFrame = ds2xSrcYPlane;
606 curbe.DW9_OutputYBTIFrame = ds2xDstYPlane;
607
608 if (m_curbeParams.bFieldPicture)
609 {
610 curbe.DW10_InputYBTIBottomField = ds2xSrcYPlaneBtmField;
611 curbe.DW11_OutputYBTIBottomField = ds2xDstYPlaneBtmField;
612 }
613
614 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_dsKernelState->m_dshRegion.AddData(
615 &curbe,
616 m_dsKernelState->dwCurbeOffset,
617 sizeof(curbe)));
618
619 return MOS_STATUS_SUCCESS;
620 }
621
SetSurfaceParamsDS(KernelParams * params)622 MOS_STATUS CodechalEncodeCscDs::SetSurfaceParamsDS(KernelParams* params)
623 {
624 CODECHAL_ENCODE_FUNCTION_ENTER;
625
626 uint32_t scaleFactor, downscaledWidthInMb, downscaledHeightInMb;
627 uint32_t inputFrameWidth, inputFrameHeight, outputFrameWidth, outputFrameHeight;
628 uint32_t inputBottomFieldOffset, outputBottomFieldOffset;
629 PMOS_SURFACE inputSurface, outputSurface;
630 bool scaling4xInUse = !(params->b32xScalingInUse || params->b16xScalingInUse);
631 bool fieldPicture = CodecHal_PictureIsField(m_encoder->m_currOriginalPic);
632
633 if (params->b32xScalingInUse)
634 {
635 scaleFactor = SCALE_FACTOR_32x;
636 downscaledWidthInMb = m_downscaledWidth32x / CODECHAL_MACROBLOCK_WIDTH;
637 downscaledHeightInMb = m_downscaledHeight32x / CODECHAL_MACROBLOCK_HEIGHT;
638 if (fieldPicture)
639 {
640 downscaledHeightInMb = (downscaledHeightInMb + 1) >> 1 << 1;
641 }
642
643 inputSurface = m_encoder->m_trackedBuf->Get16xDsSurface(m_encoder->m_currRefList->ucScalingIdx);
644 inputFrameWidth = m_downscaledWidth16x;
645 inputFrameHeight = m_downscaledHeight16x;
646 inputBottomFieldOffset = m_scaled16xBottomFieldOffset;
647
648 outputSurface = m_encoder->m_trackedBuf->Get32xDsSurface(m_encoder->m_currRefList->ucScalingIdx);
649 outputFrameWidth = m_downscaledWidth32x;
650 outputFrameHeight = downscaledHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
651 outputBottomFieldOffset = m_scaled32xBottomFieldOffset;
652 m_lastTaskInPhase = params->bLastTaskInPhase32xDS;
653 m_currRefList->b32xScalingUsed = true;
654 }
655 else if (params->b16xScalingInUse)
656 {
657 scaleFactor = SCALE_FACTOR_16x;
658 downscaledWidthInMb = m_downscaledWidth16x / CODECHAL_MACROBLOCK_WIDTH;
659 downscaledHeightInMb = m_downscaledHeight16x / CODECHAL_MACROBLOCK_HEIGHT;
660 if (fieldPicture)
661 {
662 downscaledHeightInMb = (downscaledHeightInMb + 1) >> 1 << 1;
663 }
664
665 inputSurface = m_encoder->m_trackedBuf->Get4xDsSurface(m_encoder->m_currRefList->ucScalingIdx);
666 inputFrameWidth = m_downscaledWidth4x;
667 inputFrameHeight = m_downscaledHeight4x;
668 inputBottomFieldOffset = m_scaledBottomFieldOffset;
669
670 outputSurface = m_encoder->m_trackedBuf->Get16xDsSurface(m_encoder->m_currRefList->ucScalingIdx);
671 outputFrameWidth = m_downscaledWidth16x;
672 outputFrameHeight = downscaledHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
673 outputBottomFieldOffset = m_scaled16xBottomFieldOffset;
674 m_lastTaskInPhase = params->bLastTaskInPhase16xDS;
675 m_currRefList->b16xScalingUsed = true;
676 }
677 else
678 {
679 scaleFactor = SCALE_FACTOR_4x;
680 downscaledWidthInMb = m_downscaledWidth4x / CODECHAL_MACROBLOCK_WIDTH;
681 downscaledHeightInMb = m_downscaledHeight4x / CODECHAL_MACROBLOCK_HEIGHT;
682 if (fieldPicture)
683 {
684 downscaledHeightInMb = (downscaledHeightInMb + 1) >> 1 << 1;
685 }
686
687 inputSurface = (params->bRawInputProvided) ? ¶ms->sInputRawSurface : m_rawSurfaceToEnc;
688 inputFrameWidth = m_encoder->m_oriFrameWidth;
689 inputFrameHeight = m_encoder->m_oriFrameHeight;
690 inputBottomFieldOffset = 0;
691
692 outputSurface = m_encoder->m_trackedBuf->Get4xDsSurface(m_encoder->m_currRefList->ucScalingIdx);
693 outputFrameWidth = m_downscaledWidth4x;
694 outputFrameHeight = downscaledHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
695 outputBottomFieldOffset = m_scaledBottomFieldOffset;
696 m_lastTaskInPhase = params->bLastTaskInPhase4xDS;
697 m_currRefList->b4xScalingUsed = true;
698 }
699
700 CODEC_PICTURE originalPic = (params->bRawInputProvided) ? params->inputPicture : m_encoder->m_currOriginalPic;
701 FeiPreEncParams *preEncParams = nullptr;
702 if (m_encoder->m_codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC)
703 {
704 preEncParams = (FeiPreEncParams*)m_encoder->m_encodeParams.pPreEncParams;
705 CODECHAL_ENCODE_CHK_NULL_RETURN(preEncParams);
706 }
707
708 // setup surface states
709 m_surfaceParamsDS.bCurrPicIsFrame = !CodecHal_PictureIsField(originalPic);
710 m_surfaceParamsDS.psInputSurface = inputSurface;
711 m_surfaceParamsDS.dwInputFrameWidth = inputFrameWidth;
712 m_surfaceParamsDS.dwInputFrameHeight = inputFrameHeight;
713 m_surfaceParamsDS.psOutputSurface = outputSurface;
714 m_surfaceParamsDS.dwOutputFrameWidth = outputFrameWidth;
715 m_surfaceParamsDS.dwOutputFrameHeight = outputFrameHeight;
716 m_surfaceParamsDS.dwInputBottomFieldOffset = (uint32_t)inputBottomFieldOffset;
717 m_surfaceParamsDS.dwOutputBottomFieldOffset = (uint32_t)outputBottomFieldOffset;
718 m_surfaceParamsDS.bScalingOutUses16UnormSurfFmt = params->b32xScalingInUse;
719 m_surfaceParamsDS.bScalingOutUses32UnormSurfFmt = !params->b32xScalingInUse;
720
721 if (preEncParams)
722 {
723 m_surfaceParamsDS.bPreEncInUse = true;
724 m_surfaceParamsDS.bEnable8x8Statistics = preEncParams ? preEncParams->bEnable8x8Statistics : false;
725 if (params->bScalingforRef)
726 {
727 m_surfaceParamsDS.bMBVProcStatsEnabled = params->bStatsInputProvided;
728 m_surfaceParamsDS.presMBVProcStatsBuffer = (params->bStatsInputProvided) ? &(params->sInputStatsBuffer) : nullptr;
729 m_surfaceParamsDS.presMBVProcStatsBotFieldBuffer = (params->bStatsInputProvided) ? &(params->sInputStatsBotFieldBuffer) : nullptr;
730 }
731 else
732 {
733 m_surfaceParamsDS.bMBVProcStatsEnabled = !preEncParams->bDisableStatisticsOutput;
734 m_surfaceParamsDS.presMBVProcStatsBuffer = &(preEncParams->resStatsBuffer);
735 m_surfaceParamsDS.presMBVProcStatsBotFieldBuffer = &preEncParams->resStatsBotFieldBuffer;
736 }
737 m_surfaceParamsDS.dwMBVProcStatsBottomFieldOffset = m_mbVProcStatsBottomFieldOffset;
738 }
739 else if (m_mbStatsSupported)
740 {
741 //Currently Only Based on Flatness Check, later on Adaptive Transform Decision too
742 m_surfaceParamsDS.bMBVProcStatsEnabled = scaling4xInUse && (m_flatnessCheckEnabled || m_mbStatsEnabled);
743 m_surfaceParamsDS.presMBVProcStatsBuffer = &m_resMbStatsBuffer;
744 m_surfaceParamsDS.dwMBVProcStatsBottomFieldOffset = m_mbStatsBottomFieldOffset;
745
746 m_surfaceParamsDS.bFlatnessCheckEnabled = false; // Disabling flatness check as its encompassed in Mb stats
747 }
748 else
749 {
750 // Enable flatness check only for 4x scaling.
751 m_surfaceParamsDS.bFlatnessCheckEnabled = scaling4xInUse && m_flatnessCheckEnabled;
752 m_surfaceParamsDS.psFlatnessCheckSurface = &m_encoder->m_flatnessCheckSurface;
753 m_surfaceParamsDS.dwFlatnessCheckBottomFieldOffset = m_flatnessCheckBottomFieldOffset;
754 }
755
756 return MOS_STATUS_SUCCESS;
757 }
758
SendSurfaceDS(PMOS_COMMAND_BUFFER cmdBuffer)759 MOS_STATUS CodechalEncodeCscDs::SendSurfaceDS(PMOS_COMMAND_BUFFER cmdBuffer)
760 {
761 CODECHAL_ENCODE_FUNCTION_ENTER;
762
763 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
764
765 auto currPicIsFrame = m_surfaceParamsDS.bCurrPicIsFrame;
766
767 auto verticalLineStride = m_verticalLineStride;
768 auto verticalLineOffsetTop = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD;
769 auto verticalLineOffsetBottom = CODECHAL_VLINESTRIDEOFFSET_BOT_FIELD;
770
771 auto originalSurface = *m_surfaceParamsDS.psInputSurface;
772 originalSurface.dwWidth = m_surfaceParamsDS.dwInputFrameWidth;
773 originalSurface.dwHeight = m_surfaceParamsDS.dwInputFrameHeight;
774
775 // Use actual width and height for scaling source, not padded allocated dimensions
776 auto scaledSurface = m_surfaceParamsDS.psOutputSurface;
777 scaledSurface->dwWidth = m_surfaceParamsDS.dwOutputFrameWidth;
778 scaledSurface->dwHeight = m_surfaceParamsDS.dwOutputFrameHeight;
779
780 // Account for field case
781 if (!m_fieldScalingOutputInterleaved)
782 {
783 verticalLineStride = verticalLineOffsetTop = verticalLineOffsetBottom = 0;
784 originalSurface.dwHeight =
785 MOS_ALIGN_CEIL((currPicIsFrame) ? originalSurface.dwHeight : originalSurface.dwHeight / 2, 16);
786 scaledSurface->dwHeight =
787 MOS_ALIGN_CEIL((currPicIsFrame) ? scaledSurface->dwHeight : scaledSurface->dwHeight / 2, 16);
788 }
789 originalSurface.UPlaneOffset.iYOffset = originalSurface.dwHeight;
790
791 // Source surface/s
792 CODECHAL_SURFACE_CODEC_PARAMS surfaceParams;
793 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
794 surfaceParams.bIs2DSurface = true;
795 surfaceParams.bMediaBlockRW = true;
796 if (m_surfaceParamsDS.bScalingOutUses16UnormSurfFmt)
797 {
798 // 32x scaling requires R16_UNROM
799 surfaceParams.bUse16UnormSurfaceFormat = true;
800 }
801 else
802 {
803 surfaceParams.bUse32UnormSurfaceFormat = true;
804 }
805 surfaceParams.psSurface = &originalSurface;
806 surfaceParams.dwCacheabilityControl =
807 m_hwInterface->ComposeSurfaceCacheabilityControl(
808 MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE,
809 (codechalL3 | codechalLLC));
810 surfaceParams.dwVerticalLineStride = verticalLineStride;
811
812 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder->m_mmcState);
813 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_mmcState->SetSurfaceParams(&surfaceParams));
814
815 if (currPicIsFrame)
816 {
817 // Frame
818 surfaceParams.dwBindingTableOffset = m_dsBTISrcY;
819 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
820 m_hwInterface,
821 cmdBuffer,
822 &surfaceParams,
823 m_dsKernelState));
824 }
825 else
826 {
827 // Top field
828 surfaceParams.dwVerticalLineStrideOffset = verticalLineOffsetTop;
829 surfaceParams.dwBindingTableOffset = m_dsBTISrcYTopField;
830 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
831 m_hwInterface,
832 cmdBuffer,
833 &surfaceParams,
834 m_dsKernelState));
835
836 // Bot field
837 surfaceParams.dwOffset = m_surfaceParamsDS.dwInputBottomFieldOffset;
838 surfaceParams.dwVerticalLineStrideOffset = verticalLineOffsetBottom;
839 surfaceParams.dwBindingTableOffset = m_dsBTISrcYBtmField;
840 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
841 m_hwInterface,
842 cmdBuffer,
843 &surfaceParams,
844 m_dsKernelState));
845 }
846
847 // Destination surface/s
848 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
849 surfaceParams.bIs2DSurface = true;
850 surfaceParams.bIsWritable = true;
851 surfaceParams.bRenderTarget = true;
852 surfaceParams.psSurface = scaledSurface;
853 if (m_surfaceParamsDS.bScalingOutUses32UnormSurfFmt)
854 {
855 surfaceParams.bMediaBlockRW = true;
856 surfaceParams.bUse32UnormSurfaceFormat = true;
857 }
858 else if (m_surfaceParamsDS.bScalingOutUses16UnormSurfFmt)
859 {
860 surfaceParams.bMediaBlockRW = true;
861 surfaceParams.bUse16UnormSurfaceFormat = true;
862 }
863 surfaceParams.dwCacheabilityControl =
864 m_hwInterface->ComposeSurfaceCacheabilityControl(
865 MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_DST,
866 codechalLLC);
867
868 surfaceParams.dwVerticalLineStride = verticalLineStride;
869 surfaceParams.bRenderTarget = true;
870 surfaceParams.bIsWritable = true;
871
872 if (currPicIsFrame)
873 {
874 // Frame
875 surfaceParams.dwBindingTableOffset = m_dsBTIDstY;
876 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
877 m_hwInterface,
878 cmdBuffer,
879 &surfaceParams,
880 m_dsKernelState));
881 }
882 else
883 {
884 // Top field
885 surfaceParams.dwVerticalLineStrideOffset = verticalLineOffsetTop;
886 surfaceParams.dwBindingTableOffset = m_dsBTIDstYTopField;
887 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
888 m_hwInterface,
889 cmdBuffer,
890 &surfaceParams,
891 m_dsKernelState));
892
893 // Bot field
894 surfaceParams.dwOffset = m_surfaceParamsDS.dwOutputBottomFieldOffset;
895 surfaceParams.dwVerticalLineStrideOffset = verticalLineOffsetBottom;
896 surfaceParams.dwBindingTableOffset = m_dsBTIDstYBtmField;
897 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
898 m_hwInterface,
899 cmdBuffer,
900 &surfaceParams,
901 m_dsKernelState));
902 }
903
904 if (m_surfaceParamsDS.bFlatnessCheckEnabled)
905 {
906 // flatness check surface
907 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
908 surfaceParams.bIs2DSurface = true;
909 surfaceParams.psSurface = m_surfaceParamsDS.psFlatnessCheckSurface;
910 surfaceParams.dwCacheabilityControl =
911 m_hwInterface->ComposeSurfaceCacheabilityControl(
912 MOS_CODEC_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE,
913 codechalL3 | codechalLLC);
914 surfaceParams.bMediaBlockRW = true;
915 surfaceParams.dwVerticalLineStride = 0;
916 surfaceParams.bRenderTarget = true;
917 surfaceParams.bIsWritable = true;
918
919 if (currPicIsFrame)
920 {
921 // Frame
922 surfaceParams.dwBindingTableOffset = m_dsBTIDstFlatness;
923 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
924 m_hwInterface,
925 cmdBuffer,
926 &surfaceParams,
927 m_dsKernelState));
928 }
929 else
930 {
931 // Top field
932 surfaceParams.bUseHalfHeight = true;
933 surfaceParams.dwVerticalLineStrideOffset = 0;
934 surfaceParams.dwBindingTableOffset = m_dsBTIDstFlatnessTopField;
935 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
936 m_hwInterface,
937 cmdBuffer,
938 &surfaceParams,
939 m_dsKernelState));
940
941 // Bot field
942 surfaceParams.dwOffset = m_surfaceParamsDS.dwFlatnessCheckBottomFieldOffset;
943 surfaceParams.dwVerticalLineStrideOffset = 0;
944 surfaceParams.dwBindingTableOffset = m_dsBTIDstFlatnessBtmField;
945 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
946 m_hwInterface,
947 cmdBuffer,
948 &surfaceParams,
949 m_dsKernelState));
950 }
951 }
952
953 if (m_surfaceParamsDS.bMBVProcStatsEnabled)
954 {
955 uint32_t size;
956 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
957 surfaceParams.presBuffer = m_surfaceParamsDS.presMBVProcStatsBuffer;
958 surfaceParams.dwCacheabilityControl =
959 m_hwInterface->ComposeSurfaceCacheabilityControl(
960 MOS_CODEC_RESOURCE_USAGE_MB_STATS_ENCODE,
961 codechalL3 | codechalLLC);
962 surfaceParams.bRenderTarget = true;
963 surfaceParams.bIsWritable = true;
964 surfaceParams.bRawSurface = true;
965
966 if (currPicIsFrame)
967 {
968 if (m_surfaceParamsDS.bPreEncInUse)
969 {
970 size = ((originalSurface.dwWidth + 15) / 16) * ((originalSurface.dwHeight + 15) / 16) * 16 * sizeof(uint32_t);
971 }
972 else
973 {
974 size = ((originalSurface.dwWidth + 15) / 16) * 16 * sizeof(uint32_t) * ((originalSurface.dwHeight + 15) / 16);
975 }
976 surfaceParams.dwSize = size;
977 surfaceParams.dwBindingTableOffset = m_dsBTIDstMbVProc;
978 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
979 m_hwInterface,
980 cmdBuffer,
981 &surfaceParams,
982 m_dsKernelState));
983 }
984 else
985 {
986 if (m_surfaceParamsDS.bPreEncInUse)
987 {
988 size = ((originalSurface.dwWidth + 15) / 16) * ((originalSurface.dwHeight / 2 + 15) / 16) * 16 * sizeof(uint32_t);
989 }
990 else
991 {
992 size = ((originalSurface.dwWidth + 15) / 16) * 16 * sizeof(uint32_t) * ((originalSurface.dwHeight / 2 + 15) / 16);
993 }
994 surfaceParams.dwSize = size;
995
996 // Top field
997 surfaceParams.dwBindingTableOffset = m_dsBTIDstMbVProcTopField;
998 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
999 m_hwInterface,
1000 cmdBuffer,
1001 &surfaceParams,
1002 m_dsKernelState));
1003
1004 // Bot field
1005 if (m_surfaceParamsDS.bPreEncInUse)
1006 {
1007 surfaceParams.presBuffer = m_surfaceParamsDS.presMBVProcStatsBotFieldBuffer;
1008 }
1009 surfaceParams.dwOffset = m_surfaceParamsDS.dwMBVProcStatsBottomFieldOffset;
1010 surfaceParams.dwBindingTableOffset = m_dsBTIDstMbVProcBtmField;
1011 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
1012 m_hwInterface,
1013 cmdBuffer,
1014 &surfaceParams,
1015 m_dsKernelState));
1016 }
1017 }
1018
1019 return eStatus;
1020 }
1021
GetBTCount() const1022 uint8_t CodechalEncodeCscDs::GetBTCount() const
1023 {
1024 return (uint8_t)cscNumSurfaces;
1025 }
1026
GetCscAllocation(uint32_t & width,uint32_t & height,MOS_FORMAT & format)1027 void CodechalEncodeCscDs::GetCscAllocation(uint32_t &width, uint32_t &height, MOS_FORMAT &format)
1028 {
1029 uint32_t surfaceWidth, surfaceHeight;
1030 if (m_mode == CODECHAL_ENCODE_MODE_HEVC)
1031 {
1032 // The raw input surface to HEVC Enc should be 32 aligned because of VME hardware restriction as mentioned in DDI.
1033 surfaceWidth = MOS_ALIGN_CEIL(m_encoder->m_oriFrameWidth, 32);
1034 surfaceHeight = MOS_ALIGN_CEIL(m_encoder->m_oriFrameHeight, 32);
1035 }
1036 else
1037 {
1038 surfaceWidth = MOS_ALIGN_CEIL(m_encoder->m_frameWidth, m_rawSurfAlignment);
1039 surfaceHeight = MOS_ALIGN_CEIL(m_encoder->m_frameHeight, m_rawSurfAlignment);
1040 }
1041
1042 if ( (uint8_t)HCP_CHROMA_FORMAT_YUV422 == m_outputChromaFormat)
1043 {
1044 //P208 is 422 8 bit planar with UV interleaved. It has the same memory layout as YUY2V
1045 format = Format_P208;
1046 width = surfaceWidth;
1047 height = surfaceHeight;
1048 }
1049 else
1050 {
1051 format = Format_NV12;
1052 width = surfaceWidth;
1053 height = surfaceHeight;
1054 }
1055 }
1056
Initialize()1057 MOS_STATUS CodechalEncodeCscDs::Initialize()
1058 {
1059 CODECHAL_ENCODE_FUNCTION_ENTER;
1060
1061 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1062
1063 if (m_cscKernelUID)
1064 {
1065 uint8_t* binary;
1066 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(
1067 m_kernelBase,
1068 m_cscKernelUID,
1069 &binary,
1070 &m_combinedKernelSize));
1071
1072 CODECHAL_ENCODE_CHK_NULL_RETURN(m_kernelBase = binary);
1073
1074 m_hwInterface->GetStateHeapSettings()->dwIshSize +=
1075 MOS_ALIGN_CEIL(m_combinedKernelSize, (1 << MHW_KERNEL_OFFSET_SHIFT));
1076 }
1077
1078 return eStatus;
1079 }
1080
CheckCondition()1081 MOS_STATUS CodechalEncodeCscDs::CheckCondition()
1082 {
1083 CODECHAL_ENCODE_FUNCTION_ENTER;
1084
1085 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1086
1087 MOS_SURFACE details;
1088 MOS_ZeroMemory(&details, sizeof(details));
1089 details.Format = Format_Invalid;
1090 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(m_osInterface, &m_rawSurfaceToEnc->OsResource, &details));
1091
1092 auto cscFlagPrev = m_cscFlag;
1093 m_cscFlag = 0;
1094 m_cscRawSurfWidth = details.dwWidth;
1095 m_cscRawSurfHeight = details.dwHeight;
1096 m_colorRawSurface = cscColorNv12TileY; // by default assume NV12 Tile-Y format
1097 m_threadTraverseSizeX = 5;
1098 m_threadTraverseSizeY = 2; // for NV12, thread space is 32x4
1099
1100 // check raw surface's alignment
1101 if (m_cscEnableCopy && (details.dwWidth % m_rawSurfAlignment || details.dwHeight % m_rawSurfAlignment))
1102 {
1103 m_cscRequireCopy = 1;
1104 }
1105
1106 // check raw surface's color/tile format
1107 if (m_cscEnableColor && !m_encoder->CheckSupportedFormat(&details))
1108 {
1109 CODECHAL_ENCODE_CHK_STATUS_RETURN(CheckRawColorFormat(details.Format, details.TileType));
1110 }
1111
1112 // check raw surface's MMC state
1113 if (m_cscEnableMmc)
1114 {
1115 MOS_MEMCOMP_STATE mmcState;
1116
1117 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetMemoryCompressionMode(
1118 m_osInterface, &m_rawSurfaceToEnc->OsResource, &mmcState));
1119
1120 // Gen9 HEVC only: HCP on SKL does not support MMC surface, invoke Ds+Copy kernel to decompress MMC surface
1121 m_cscRequireMmc = (MOS_MEMCOMP_DISABLED != mmcState);
1122 }
1123
1124 // CSC no longer required, free existing CSC surface
1125 if (cscFlagPrev && !m_cscFlag)
1126 {
1127 m_encoder->m_trackedBuf->ResizeCsc();
1128 }
1129 CODECHAL_ENCODE_NORMALMESSAGE("raw surf = %d x %d, tile = %d, color = %d, cscFlag = %d",
1130 details.dwWidth, details.dwHeight, details.TileType, m_colorRawSurface, m_cscFlag);
1131
1132 return eStatus;
1133 }
1134
CheckReconSurfaceAlignment(PMOS_SURFACE surface)1135 MOS_STATUS CodechalEncodeCscDs::CheckReconSurfaceAlignment(PMOS_SURFACE surface)
1136 {
1137 CODECHAL_ENCODE_FUNCTION_ENTER;
1138
1139 uint8_t alignment;
1140 if (m_standard == CODECHAL_HEVC ||
1141 m_standard == CODECHAL_VP9)
1142 {
1143 alignment = m_hcpReconSurfAlignment;
1144 }
1145 else
1146 {
1147 alignment = m_mfxReconSurfAlignment;
1148 }
1149
1150 MOS_SURFACE resDetails;
1151 MOS_ZeroMemory(&resDetails, sizeof(resDetails));
1152 resDetails.Format = Format_Invalid;
1153 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(m_osInterface, &surface->OsResource, &resDetails));
1154
1155 if (resDetails.dwHeight % alignment)
1156 {
1157 CODECHAL_ENCODE_ASSERTMESSAGE("Recon surface alignment does not meet HW requirement!");
1158 return MOS_STATUS_INVALID_PARAMETER;
1159 }
1160
1161 return MOS_STATUS_SUCCESS;
1162 }
1163
CheckRawSurfaceAlignment(PMOS_SURFACE surface)1164 MOS_STATUS CodechalEncodeCscDs::CheckRawSurfaceAlignment(PMOS_SURFACE surface)
1165 {
1166 CODECHAL_ENCODE_FUNCTION_ENTER;
1167
1168 MOS_SURFACE resDetails;
1169 MOS_ZeroMemory(&resDetails, sizeof(resDetails));
1170 resDetails.Format = Format_Invalid;
1171 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(m_osInterface, &surface->OsResource, &resDetails));
1172
1173 if (resDetails.dwHeight % m_rawSurfAlignment)
1174 {
1175 CODECHAL_ENCODE_ASSERTMESSAGE("Raw surface alignment does not meet HW requirement!");
1176 return MOS_STATUS_INVALID_PARAMETER;
1177 }
1178
1179 return MOS_STATUS_SUCCESS;
1180 }
1181
SetHcpReconAlignment(uint8_t alignment)1182 void CodechalEncodeCscDs::SetHcpReconAlignment(uint8_t alignment)
1183 {
1184 m_hcpReconSurfAlignment = alignment;
1185 }
1186
WaitCscSurface(MOS_GPU_CONTEXT gpuContext,bool readOnly)1187 MOS_STATUS CodechalEncodeCscDs::WaitCscSurface(MOS_GPU_CONTEXT gpuContext, bool readOnly)
1188 {
1189 CODECHAL_ENCODE_FUNCTION_ENTER;
1190
1191 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1192
1193 auto syncParams = g_cInitSyncParams;
1194 syncParams.GpuContext = gpuContext;
1195 syncParams.bReadOnly = readOnly;
1196 syncParams.presSyncResource = &m_encoder->m_trackedBuf->GetCscSurface(CODEC_CURR_TRACKED_BUFFER)->OsResource;
1197
1198 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1199 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1200
1201 return eStatus;
1202 }
1203
KernelFunctions(KernelParams * params)1204 MOS_STATUS CodechalEncodeCscDs::KernelFunctions(
1205 KernelParams* params)
1206 {
1207 CODECHAL_ENCODE_FUNCTION_ENTER;
1208
1209 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1210
1211 bool useDsConvInCombinedKernel = m_useCommonKernel
1212 && !(CODECHAL_AVC == m_standard || CODECHAL_MPEG2 == m_standard || CODECHAL_VP8 == m_standard);
1213
1214 // call Ds+Copy
1215 if (m_cscFlag || useDsConvInCombinedKernel)
1216 {
1217 CODECHAL_ENCODE_CHK_STATUS_RETURN(CscKernel(params));
1218 }
1219
1220 // call 4x DS
1221 if (m_scalingEnabled && !m_currRefList->b4xScalingUsed)
1222 {
1223 params->b32xScalingInUse = false;
1224 params->b16xScalingInUse = false;
1225 CODECHAL_ENCODE_CHK_STATUS_RETURN(DsKernel(params));
1226 }
1227
1228 // call 16x/32x DS
1229 if (m_scalingEnabled && m_16xMeSupported)
1230 {
1231 //disable csc and reset colorFormat in 16x/32x stage since their inputs are 4x/16x DS results (only Y component)
1232 if(m_cscFlag && m_encoder->m_vdencEnabled && CODECHAL_HEVC == m_standard)
1233 {
1234 m_colorRawSurface = cscColorNv12TileY;
1235 m_cscFlag = false;
1236 }
1237
1238 // 4x downscaled images used as the input for 16x downscaling
1239 if (useDsConvInCombinedKernel)
1240 {
1241 params->stageDsConversion = dsStage16x;
1242 CODECHAL_ENCODE_CHK_STATUS_RETURN(CscKernel(params));
1243 }
1244 else
1245 {
1246 params->b16xScalingInUse = true;
1247 CODECHAL_ENCODE_CHK_STATUS_RETURN(DsKernel(params));
1248 }
1249
1250 if (m_32xMeSupported)
1251 {
1252 // 16x downscaled images used as the input for 32x downscaling
1253 if (useDsConvInCombinedKernel)
1254 {
1255 params->stageDsConversion = dsStage32x;
1256 CODECHAL_ENCODE_CHK_STATUS_RETURN(CscKernel(params));
1257 }
1258 else
1259 {
1260 params->b32xScalingInUse = true;
1261 params->b16xScalingInUse = false;
1262 CODECHAL_ENCODE_CHK_STATUS_RETURN(DsKernel(params));
1263 }
1264 }
1265 }
1266
1267 return MOS_STATUS_SUCCESS;
1268 }
1269
CscUsingSfc(ENCODE_INPUT_COLORSPACE colorSpace)1270 MOS_STATUS CodechalEncodeCscDs::CscUsingSfc(ENCODE_INPUT_COLORSPACE colorSpace)
1271 {
1272 CODECHAL_ENCODE_FUNCTION_ENTER;
1273
1274 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1275
1276 // init SFC state
1277 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitSfcState());
1278
1279 // wait for raw surface on VEBox context
1280 auto syncParams = g_cInitSyncParams;
1281 syncParams.GpuContext = MOS_GPU_CONTEXT_VEBOX;
1282 syncParams.presSyncResource = &m_rawSurfaceToEnc->OsResource;
1283 syncParams.bReadOnly = true;
1284 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1285 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1286
1287 // allocate CSC surface (existing surfaces will be re-used when associated frame goes out of RefList)
1288 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurfaceCsc());
1289
1290 if (m_encoder->m_trackedBuf->GetWaitCsc())
1291 {
1292 // on-demand sync for CSC surface re-use
1293 CODECHAL_ENCODE_CHK_STATUS_RETURN(WaitCscSurface(MOS_GPU_CONTEXT_VEBOX, false));
1294 }
1295
1296 CODECHAL_ENCODE_SFC_PARAMS sfcParams;
1297 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetParamsSfc(&sfcParams));
1298
1299 // set-up color space
1300 switch (colorSpace)
1301 {
1302 case ECOLORSPACE_P601:
1303 m_sfcState->SetOutputColorSpace(MHW_CSpace_BT601);
1304 break;
1305 case ECOLORSPACE_P709:
1306 m_sfcState->SetOutputColorSpace(MHW_CSpace_BT709);
1307 break;
1308 case ECOLORSPACE_P2020:
1309 m_sfcState->SetOutputColorSpace(MHW_CSpace_BT2020);
1310 break;
1311 default:
1312 CODECHAL_ENCODE_ASSERTMESSAGE("Unknow input color space = %d!", colorSpace);
1313 eStatus = MOS_STATUS_INVALID_PARAMETER;
1314 }
1315
1316 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_sfcState->SetParams(
1317 &sfcParams));
1318
1319 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_sfcState->RenderStart(
1320 m_encoder));
1321
1322 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSurfacesToEncPak());
1323
1324 return eStatus;
1325 }
1326
CscKernel(KernelParams * params)1327 MOS_STATUS CodechalEncodeCscDs::CscKernel(
1328 KernelParams* params)
1329 {
1330 CODECHAL_ENCODE_FUNCTION_ENTER;
1331
1332 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1333
1334 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1335
1336 if (!m_cscKernelState)
1337 {
1338 CODECHAL_ENCODE_CHK_NULL_RETURN(m_cscKernelState = MOS_New(MHW_KERNEL_STATE));
1339
1340 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateCsc());
1341 }
1342
1343 // allocate CSC surface (existing surfaces will be re-used when associated frame retires from RefList)
1344 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateSurfaceCsc());
1345
1346 if (m_scalingEnabled)
1347 {
1348 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_trackedBuf->AllocateSurfaceDS());
1349 if (m_standard == CODECHAL_VP9)
1350 {
1351 auto seqParams = (PCODEC_VP9_ENCODE_SEQUENCE_PARAMS)(m_encoder->m_encodeParams.pSeqParams);
1352 CODECHAL_ENCODE_CHK_NULL_RETURN(seqParams);
1353 if (seqParams->SeqFlags.fields.EnableDynamicScaling) {
1354 m_encoder->m_trackedBuf->ResizeSurfaceDS();
1355 }
1356 }
1357 }
1358
1359 if (m_2xScalingEnabled)
1360 {
1361 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_trackedBuf->AllocateSurface2xDS());
1362 }
1363
1364 if (m_encoder->m_trackedBuf->GetWaitCsc())
1365 {
1366 // on-demand sync for CSC surface re-use
1367 CODECHAL_ENCODE_CHK_STATUS_RETURN(WaitCscSurface(m_renderContext, false));
1368 }
1369
1370 // setup kernel params
1371 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetKernelParamsCsc(params));
1372
1373 if(m_encoder->m_vdencEnabled && CODECHAL_HEVC == m_standard)
1374 {
1375 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1376 m_surfaceParamsCsc.psInputSurface,
1377 CodechalDbgAttr::attrEncodeRawInputSurface,
1378 m_curbeParams.downscaleStage == dsStage4x ? "4xDS_Input" : (m_curbeParams.downscaleStage == dsStage16x ? "16xDS_Input" : "32xDS_Input"))));
1379 }
1380
1381 PerfTagSetting perfTag;
1382 perfTag.Value = 0;
1383 perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
1384 perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_DS_CONVERSION_KERNEL;
1385 perfTag.PictureCodingType = m_encoder->m_pictureCodingType;
1386 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
1387 // Each scaling kernel buffer counts as a separate perf task
1388 m_osInterface->pfnResetPerfBufferID(m_osInterface);
1389
1390 // if Single Task Phase is not enabled, use BT count for the kernel state.
1391 if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
1392 {
1393 auto maxBtCount = m_singleTaskPhaseSupported ?
1394 m_maxBtCount : m_cscKernelState->KernelParams.iBTCount;
1395 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->RequestSshSpaceForCmdBuf(maxBtCount));
1396 m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
1397 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->VerifySpaceAvailable());
1398 }
1399
1400 // setup CscDsCopy DSH and Interface Descriptor
1401 auto stateHeapInterface = m_renderInterface->m_stateHeapInterface;
1402 CODECHAL_ENCODE_CHK_NULL_RETURN(stateHeapInterface);
1403 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
1404 stateHeapInterface,
1405 m_cscKernelState,
1406 false,
1407 0,
1408 false,
1409 m_storeData));
1410
1411 MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
1412 MOS_ZeroMemory(&idParams, sizeof(idParams));
1413 idParams.pKernelState = m_cscKernelState;
1414 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SetInterfaceDescriptor(1, &idParams));
1415
1416 // send CURBE
1417 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeCsc());
1418
1419 if(m_encoder->m_vdencEnabled && CODECHAL_HEVC == m_standard)
1420 {
1421 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
1422 m_curbeParams.downscaleStage == dsStage4x ? CODECHAL_MEDIA_STATE_4X_SCALING :
1423 (m_curbeParams.downscaleStage == dsStage16x ? CODECHAL_MEDIA_STATE_16X_SCALING : CODECHAL_MEDIA_STATE_32X_SCALING),
1424 m_cscKernelState)));
1425 }
1426
1427 CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_CSC_DS_COPY;
1428 CODECHAL_DEBUG_TOOL(
1429 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
1430 encFunctionType,
1431 m_cscKernelState));
1432
1433 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1434 encFunctionType,
1435 MHW_DSH_TYPE,
1436 m_cscKernelState));
1437 )
1438
1439 MOS_COMMAND_BUFFER cmdBuffer;
1440 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1441
1442 SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
1443 sendKernelCmdsParams.EncFunctionType = encFunctionType;
1444 sendKernelCmdsParams.pKernelState = m_cscKernelState;
1445 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
1446
1447 // add binding table
1448 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SetBindingTable(m_cscKernelState));
1449
1450 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSurfaceCsc(&cmdBuffer));
1451
1452 CODECHAL_DEBUG_TOOL(
1453 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1454 encFunctionType,
1455 MHW_SSH_TYPE,
1456 m_cscKernelState));
1457 )
1458
1459 // If m_pollingSyncEnabled is set, insert HW semaphore to wait for external
1460 // raw surface processing to complete, before start CSC. Once the marker in
1461 // raw surface is overwritten by external operation, HW semaphore will be
1462 // signalled and CSC will start. This is to reduce SW latency between
1463 // external raw surface processing and CSC, in usages like remote gaming.
1464 if (m_pollingSyncEnabled)
1465 {
1466 MHW_MI_SEMAPHORE_WAIT_PARAMS miSemaphoreWaitParams;
1467 MOS_ZeroMemory((&miSemaphoreWaitParams), sizeof(miSemaphoreWaitParams));
1468 miSemaphoreWaitParams.presSemaphoreMem = &m_surfaceParamsCsc.psInputSurface->OsResource;
1469 miSemaphoreWaitParams.dwResourceOffset = m_syncMarkerOffset;
1470 miSemaphoreWaitParams.bPollingWaitMode = true;
1471 miSemaphoreWaitParams.dwSemaphoreData = m_syncMarkerValue;
1472 miSemaphoreWaitParams.CompareOperation = MHW_MI_SAD_NOT_EQUAL_SDD;
1473 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiSemaphoreWaitCmd(&cmdBuffer, &miSemaphoreWaitParams));
1474 }
1475
1476 if (!m_encoder->m_computeContextEnabled)
1477 {
1478 MHW_WALKER_PARAMS walkerParams;
1479 MOS_ZeroMemory(&walkerParams, sizeof(walkerParams));
1480 walkerParams.WalkerMode = m_walkerMode;
1481 walkerParams.UseScoreboard = m_useHwScoreboard;
1482 walkerParams.BlockResolution.x =
1483 walkerParams.GlobalResolution.x =
1484 walkerParams.GlobalOutlerLoopStride.x = m_walkerResolutionX;
1485 walkerParams.BlockResolution.y =
1486 walkerParams.GlobalResolution.y =
1487 walkerParams.GlobalInnerLoopUnit.y = m_walkerResolutionY;
1488
1489 //MAX VALUE
1490 walkerParams.dwLocalLoopExecCount = 0xFFFF;
1491 walkerParams.dwGlobalLoopExecCount = 0xFFFF;
1492
1493 // Raster scan walking pattern
1494 walkerParams.LocalOutLoopStride.y = 1;
1495 walkerParams.LocalInnerLoopUnit.x = 1;
1496 walkerParams.LocalEnd.x = m_walkerResolutionX - 1;
1497
1498 if (m_groupIdSelectSupported)
1499 {
1500 walkerParams.GroupIdLoopSelect = m_groupId;
1501 }
1502
1503 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderInterface->AddMediaObjectWalkerCmd(&cmdBuffer, &walkerParams));
1504 }
1505 else
1506 {
1507 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetWalkerCmd(&cmdBuffer, m_cscKernelState));
1508 }
1509
1510 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->EndStatusReport(&cmdBuffer, encFunctionType));
1511
1512 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SubmitBlocks(m_cscKernelState));
1513
1514 // If m_pollingSyncEnabled is set, write the marker to source surface for next MI_SEMAPHORE_WAIT to check.
1515 if (m_pollingSyncEnabled)
1516 {
1517 MHW_MI_STORE_DATA_PARAMS storeDataParams;
1518 storeDataParams.pOsResource = &m_surfaceParamsCsc.psInputSurface->OsResource;
1519 storeDataParams.dwResourceOffset = m_syncMarkerOffset;
1520 storeDataParams.dwValue = m_syncMarkerValue;
1521 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams));
1522 }
1523
1524 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
1525 {
1526 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->UpdateGlobalCmdBufId());
1527 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1528 }
1529
1530 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1531 &cmdBuffer,
1532 encFunctionType,
1533 nullptr)));
1534
1535 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(
1536 &cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));
1537
1538 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1539
1540 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
1541 {
1542 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface->pOsContext);
1543 m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
1544 m_lastTaskInPhase = false;
1545 }
1546
1547 if (dsDisabled == params->stageDsConversion && !(m_encoder->m_vdencEnabled && CODECHAL_HEVC == m_standard))
1548 {
1549 // send appropriate surface to Enc/Pak depending on different CSC operation type
1550 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSurfacesToEncPak());
1551 }
1552
1553 return eStatus;
1554 }
1555
DsKernel(KernelParams * params)1556 MOS_STATUS CodechalEncodeCscDs::DsKernel(
1557 KernelParams* params)
1558 {
1559 CODECHAL_ENCODE_FUNCTION_ENTER;
1560
1561 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1562
1563 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1564
1565 if (!m_firstField)
1566 {
1567 // Both fields are scaled when the first field comes in, no need to scale again
1568 return eStatus;
1569 }
1570
1571 if (!m_dsKernelState)
1572 {
1573 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateDS());
1574 }
1575
1576 if (m_scalingEnabled)
1577 {
1578 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_trackedBuf->AllocateSurfaceDS());
1579 if (m_standard == CODECHAL_VP9)
1580 {
1581 auto seqParams = (PCODEC_VP9_ENCODE_SEQUENCE_PARAMS)(m_encoder->m_encodeParams.pSeqParams);
1582 CODECHAL_ENCODE_CHK_NULL_RETURN(seqParams);
1583 if (seqParams->SeqFlags.fields.EnableDynamicScaling) {
1584 m_encoder->m_trackedBuf->ResizeSurfaceDS();
1585 }
1586 }
1587 }
1588
1589 if (m_2xScalingEnabled)
1590 {
1591 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_trackedBuf->AllocateSurface2xDS());
1592 }
1593
1594 PerfTagSetting perfTag;
1595 perfTag.Value = 0;
1596 perfTag.Mode = m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
1597 perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL;
1598 perfTag.PictureCodingType = m_encoder->m_pictureCodingType;
1599 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
1600 m_osInterface->pfnIncPerfBufferID(m_osInterface);
1601 // Each scaling kernel buffer counts as a separate perf task
1602 m_osInterface->pfnResetPerfBufferID(m_osInterface);
1603
1604 bool fieldPicture = CodecHal_PictureIsField(m_encoder->m_currOriginalPic);
1605 m_dsKernelState = params->b32xScalingInUse ?
1606 &m_encoder->m_scaling2xKernelStates[fieldPicture] :
1607 &m_encoder->m_scaling4xKernelStates[fieldPicture];
1608
1609 // If Single Task Phase is not enabled, use BT count for the kernel state.
1610 if (m_firstTaskInPhase || !m_singleTaskPhaseSupported)
1611 {
1612 auto maxBtCount = m_singleTaskPhaseSupported ?
1613 m_maxBtCount : m_dsKernelState->KernelParams.iBTCount;
1614 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->RequestSshSpaceForCmdBuf(maxBtCount));
1615 m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
1616 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->VerifySpaceAvailable());
1617 }
1618
1619 //Setup Scaling DSH
1620 auto stateHeapInterface = m_renderInterface->m_stateHeapInterface;
1621 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
1622 stateHeapInterface,
1623 m_dsKernelState,
1624 false,
1625 0,
1626 false,
1627 m_storeData));
1628
1629 MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
1630 MOS_ZeroMemory(&idParams, sizeof(idParams));
1631 idParams.pKernelState = m_dsKernelState;
1632 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SetInterfaceDescriptor(1, &idParams));
1633
1634 uint32_t downscaledWidthInMb, downscaledHeightInMb;
1635 uint32_t inputFrameWidth, inputFrameHeight;
1636
1637 if (params->b32xScalingInUse)
1638 {
1639 downscaledWidthInMb = m_downscaledWidth32x / CODECHAL_MACROBLOCK_WIDTH;
1640 downscaledHeightInMb = m_downscaledHeight32x / CODECHAL_MACROBLOCK_HEIGHT;
1641 if (fieldPicture)
1642 {
1643 downscaledHeightInMb = (downscaledHeightInMb + 1) >> 1 << 1;
1644 }
1645
1646 inputFrameWidth = m_downscaledWidth16x;
1647 inputFrameHeight = m_downscaledHeight16x;
1648
1649 m_lastTaskInPhase = params->bLastTaskInPhase32xDS;
1650 m_currRefList->b32xScalingUsed = true;
1651 }
1652 else if (params->b16xScalingInUse)
1653 {
1654 downscaledWidthInMb = m_downscaledWidth16x / CODECHAL_MACROBLOCK_WIDTH;
1655 downscaledHeightInMb = m_downscaledHeight16x / CODECHAL_MACROBLOCK_HEIGHT;
1656 if (fieldPicture)
1657 {
1658 downscaledHeightInMb = (downscaledHeightInMb + 1) >> 1 << 1;
1659 }
1660
1661 inputFrameWidth = m_downscaledWidth4x;
1662 inputFrameHeight = m_downscaledHeight4x;
1663
1664 m_lastTaskInPhase = params->bLastTaskInPhase16xDS;
1665 m_currRefList->b16xScalingUsed = true;
1666 }
1667 else
1668 {
1669 downscaledWidthInMb = m_downscaledWidth4x / CODECHAL_MACROBLOCK_WIDTH;
1670 downscaledHeightInMb = m_downscaledHeight4x / CODECHAL_MACROBLOCK_HEIGHT;
1671 if (fieldPicture)
1672 {
1673 downscaledHeightInMb = (downscaledHeightInMb + 1) >> 1 << 1;
1674 }
1675
1676 inputFrameWidth = m_encoder->m_oriFrameWidth;
1677 inputFrameHeight = m_encoder->m_oriFrameHeight;
1678
1679 m_lastTaskInPhase = params->bLastTaskInPhase4xDS;
1680 m_currRefList->b4xScalingUsed = true;
1681 }
1682
1683 CODEC_PICTURE originalPic = (params->bRawInputProvided) ? params->inputPicture : m_encoder->m_currOriginalPic;
1684 FeiPreEncParams *preEncParams = nullptr;
1685 if (m_encoder->m_codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC)
1686 {
1687 preEncParams = (FeiPreEncParams*)m_encoder->m_encodeParams.pPreEncParams;
1688 CODECHAL_ENCODE_CHK_NULL_RETURN(preEncParams);
1689 }
1690
1691 bool scaling4xInUse = !(params->b32xScalingInUse || params->b16xScalingInUse);
1692 m_curbeParams.pKernelState = m_dsKernelState;
1693 m_curbeParams.dwInputPictureWidth = inputFrameWidth;
1694 m_curbeParams.dwInputPictureHeight = inputFrameHeight;
1695 m_curbeParams.b16xScalingInUse = params->b16xScalingInUse;
1696 m_curbeParams.b32xScalingInUse = params->b32xScalingInUse;
1697 m_curbeParams.bFieldPicture = fieldPicture;
1698 // Enable flatness check only for 4x scaling.
1699 m_curbeParams.bFlatnessCheckEnabled = scaling4xInUse && m_flatnessCheckEnabled;
1700 m_curbeParams.bMBVarianceOutputEnabled = m_curbeParams.bMBPixelAverageOutputEnabled =
1701 preEncParams ? !preEncParams->bDisableStatisticsOutput : scaling4xInUse && m_mbStatsEnabled;
1702 m_curbeParams.bBlock8x8StatisticsEnabled = preEncParams ? preEncParams->bEnable8x8Statistics : false;
1703
1704 if (params->b32xScalingInUse)
1705 {
1706 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeDS2x());
1707 }
1708 else
1709 {
1710 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeDS4x());
1711 }
1712
1713 auto encFunctionType = params->b32xScalingInUse ? CODECHAL_MEDIA_STATE_32X_SCALING :
1714 (params->b16xScalingInUse ? CODECHAL_MEDIA_STATE_16X_SCALING : CODECHAL_MEDIA_STATE_4X_SCALING);
1715 CODECHAL_DEBUG_TOOL(
1716 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1717 encFunctionType,
1718 MHW_DSH_TYPE,
1719 m_dsKernelState));
1720 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
1721 encFunctionType,
1722 m_dsKernelState));
1723 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1724 encFunctionType,
1725 MHW_ISH_TYPE,
1726 m_dsKernelState));
1727 )
1728
1729 MOS_COMMAND_BUFFER cmdBuffer;
1730 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1731
1732 SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
1733 sendKernelCmdsParams.EncFunctionType = encFunctionType;
1734 sendKernelCmdsParams.pKernelState = m_dsKernelState;
1735 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
1736
1737 // Add binding table
1738 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SetBindingTable(m_dsKernelState));
1739 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSurfaceParamsDS(params));
1740 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSurfaceDS(&cmdBuffer));
1741
1742 // Add dump for scaling surface state heap here
1743 CODECHAL_DEBUG_TOOL(
1744 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1745 encFunctionType,
1746 MHW_SSH_TYPE,
1747 m_dsKernelState));
1748 )
1749
1750 uint32_t resolutionX, resolutionY;
1751 if (params->b32xScalingInUse)
1752 {
1753 resolutionX = downscaledWidthInMb;
1754 resolutionY = downscaledHeightInMb;
1755 }
1756 else
1757 {
1758 resolutionX = downscaledWidthInMb * 2; /* looping for Walker is needed at 8x8 block level */
1759 resolutionY = downscaledHeightInMb * 2;
1760 if (fieldPicture && (m_encoder->m_codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC))
1761 {
1762 resolutionY = MOS_ALIGN_CEIL(downscaledHeightInMb, 2) * 2;
1763 }
1764 }
1765
1766 MHW_WALKER_PARAMS walkerParams;
1767 MOS_ZeroMemory(&walkerParams, sizeof(MHW_WALKER_PARAMS));
1768 walkerParams.WalkerMode = m_walkerMode;
1769 walkerParams.BlockResolution.x =
1770 walkerParams.GlobalResolution.x =
1771 walkerParams.GlobalOutlerLoopStride.x = resolutionX;
1772 walkerParams.BlockResolution.y =
1773 walkerParams.GlobalResolution.y =
1774 walkerParams.GlobalInnerLoopUnit.y = resolutionY;
1775 walkerParams.dwLocalLoopExecCount = 0xFFFF; //MAX VALUE
1776 walkerParams.dwGlobalLoopExecCount = 0xFFFF; //MAX VALUE
1777
1778 // Raster scan walking pattern
1779 walkerParams.LocalOutLoopStride.y = 1;
1780 walkerParams.LocalInnerLoopUnit.x = 1;
1781 walkerParams.LocalEnd.x = resolutionX - 1;
1782
1783 if (m_groupIdSelectSupported)
1784 {
1785 walkerParams.GroupIdLoopSelect = m_groupId;
1786 }
1787
1788 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderInterface->AddMediaObjectWalkerCmd(&cmdBuffer, &walkerParams));
1789
1790 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->EndStatusReport(&cmdBuffer, encFunctionType));
1791
1792 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SubmitBlocks(m_dsKernelState));
1793
1794 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
1795 {
1796 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->UpdateGlobalCmdBufId());
1797 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1798 }
1799
1800 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1801 &cmdBuffer,
1802 encFunctionType,
1803 nullptr)));
1804
1805 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(
1806 &cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));
1807
1808 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1809
1810 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
1811 {
1812 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface->pOsContext);
1813 m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
1814 m_lastTaskInPhase = false;
1815 }
1816
1817 return eStatus;
1818 }
1819
SetHevcCscFlagAndRawColor()1820 MOS_STATUS CodechalEncodeCscDs::SetHevcCscFlagAndRawColor()
1821 {
1822 CODECHAL_ENCODE_FUNCTION_ENTER;
1823
1824 if(m_rawSurfaceToEnc->Format != Format_NV12 && CheckRawColorFormat(m_rawSurfaceToEnc->Format, m_rawSurfaceToEnc->TileType) == MOS_STATUS_SUCCESS)
1825 {
1826 m_cscFlag = true;
1827 }
1828
1829 return MOS_STATUS_SUCCESS;
1830 }
1831
CodechalEncodeCscDs(CodechalEncoderState * encoder)1832 CodechalEncodeCscDs::CodechalEncodeCscDs(CodechalEncoderState *encoder)
1833 : m_useRawForRef(encoder->m_useRawForRef),
1834 m_useCommonKernel(encoder->m_useCommonKernel),
1835 m_useHwScoreboard(encoder->m_useHwScoreboard),
1836 m_renderContextUsesNullHw(encoder->m_renderContextUsesNullHw),
1837 m_groupIdSelectSupported(encoder->m_groupIdSelectSupported),
1838 m_16xMeSupported(encoder->m_16xMeSupported),
1839 m_32xMeSupported(encoder->m_32xMeSupported),
1840 m_scalingEnabled(encoder->m_scalingEnabled),
1841 m_2xScalingEnabled(encoder->m_2xScalingEnabled),
1842 m_firstField(encoder->m_firstField),
1843 m_fieldScalingOutputInterleaved(encoder->m_fieldScalingOutputInterleaved),
1844 m_flatnessCheckEnabled(encoder->m_flatnessCheckEnabled),
1845 m_mbStatsEnabled(encoder->m_mbStatsEnabled),
1846 m_mbStatsSupported(encoder->m_mbStatsSupported),
1847 m_singleTaskPhaseSupported(encoder->m_singleTaskPhaseSupported),
1848 m_firstTaskInPhase(encoder->m_firstTaskInPhase),
1849 m_lastTaskInPhase(encoder->m_lastTaskInPhase),
1850 m_pollingSyncEnabled(encoder->m_pollingSyncEnabled),
1851 m_groupId(encoder->m_groupId),
1852 m_outputChromaFormat(encoder->m_outputChromaFormat),
1853 m_standard(encoder->m_standard),
1854 m_mode(encoder->m_mode),
1855 m_downscaledWidth4x(encoder->m_downscaledWidth4x),
1856 m_downscaledHeight4x(encoder->m_downscaledHeight4x),
1857 m_downscaledWidth16x(encoder->m_downscaledWidth16x),
1858 m_downscaledHeight16x(encoder->m_downscaledHeight16x),
1859 m_downscaledWidth32x(encoder->m_downscaledWidth32x),
1860 m_downscaledHeight32x(encoder->m_downscaledHeight32x),
1861 m_scaledBottomFieldOffset(encoder->m_scaledBottomFieldOffset),
1862 m_scaled16xBottomFieldOffset(encoder->m_scaled16xBottomFieldOffset),
1863 m_scaled32xBottomFieldOffset(encoder->m_scaled32xBottomFieldOffset),
1864 m_mbVProcStatsBottomFieldOffset(encoder->m_mbvProcStatsBottomFieldOffset),
1865 m_mbStatsBottomFieldOffset(encoder->m_mbStatsBottomFieldOffset),
1866 m_flatnessCheckBottomFieldOffset(encoder->m_flatnessCheckBottomFieldOffset),
1867 m_verticalLineStride(encoder->m_verticalLineStride),
1868 m_maxBtCount(encoder->m_maxBtCount),
1869 m_vmeStatesSize(encoder->m_vmeStatesSize),
1870 m_storeData(encoder->m_storeData),
1871 m_syncMarkerOffset(encoder->m_syncMarkerOffset),
1872 m_syncMarkerValue(encoder->m_syncMarkerValue),
1873 m_renderContext(encoder->m_renderContext),
1874 m_walkerMode(encoder->m_walkerMode),
1875 m_currRefList(encoder->m_currRefList),
1876 m_resMbStatsBuffer(encoder->m_resMbStatsBuffer),
1877 m_rawSurfaceToEnc(encoder->m_rawSurfaceToEnc),
1878 m_rawSurfaceToPak(encoder->m_rawSurfaceToPak)
1879 {
1880 // Initilize interface pointers
1881 m_encoder = encoder;
1882 m_osInterface = encoder->GetOsInterface();
1883 m_hwInterface = encoder->GetHwInterface();
1884 m_debugInterface = encoder->GetDebugInterface();
1885 m_miInterface = m_hwInterface->GetMiInterface();
1886 m_renderInterface = m_hwInterface->GetRenderInterface();
1887 m_stateHeapInterface = m_renderInterface->m_stateHeapInterface->pStateHeapInterface;
1888
1889 m_cscFlag = m_cscDsConvEnable = 0;
1890
1891 m_dsBTCount[0] = ds4xNumSurfaces;
1892 m_dsBTCount[1] = ds2xNumSurfaces;
1893 m_dsCurbeLength[0] = sizeof(Ds4xKernelCurbeData);
1894 m_dsCurbeLength[1] = sizeof(Ds2xKernelCurbeData);
1895 m_dsInlineDataLength = sizeof(DsKernelInlineData);
1896 }
1897
~CodechalEncodeCscDs()1898 CodechalEncodeCscDs::~CodechalEncodeCscDs()
1899 {
1900 MOS_Delete(m_cscKernelState);
1901 m_cscKernelState = nullptr;
1902
1903 if (m_sfcState)
1904 {
1905 MOS_Delete(m_sfcState);
1906 m_sfcState = nullptr;
1907 }
1908 }
1909