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) ? &params->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