xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/hw/mhw_sfc_impl.h (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2022, 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     mhw_sfc_impl.h
24 //! \brief    MHW SFC interface common base
25 //! \details
26 //!
27 
28 #ifndef __MHW_SFC_IMPL_H__
29 #define __MHW_SFC_IMPL_H__
30 
31 #include "mhw_sfc_itf.h"
32 #include "mhw_impl.h"
33 
34 namespace mhw
35 {
36 namespace sfc
37 {
38 template <typename cmd_t>
39 class Impl : public Itf, public mhw::Impl
40 {
41     _SFC_CMD_DEF(_MHW_CMD_ALL_DEF_FOR_IMPL);
42 
43 public:
Impl(PMOS_INTERFACE osItf)44     Impl(PMOS_INTERFACE osItf) : mhw::Impl(osItf)
45     {
46         MHW_FUNCTION_ENTER;
47 
48         MOS_ZeroMemory(&m_outputSurfCtrl, sizeof(m_outputSurfCtrl));
49         MOS_ZeroMemory(&m_avsLineBufferCtrl, sizeof(m_avsLineBufferCtrl));
50         MOS_ZeroMemory(&m_iefLineBufferCtrl, sizeof(m_iefLineBufferCtrl));
51         MOS_ZeroMemory(&m_sfdLineBufferCtrl, sizeof(m_sfdLineBufferCtrl));
52 
53         m_scalingMode = MHW_SCALING_AVS;
54 
55         if (osItf == nullptr)
56         {
57             MHW_ASSERTMESSAGE("Invalid input pointers provided");
58             return;
59         }
60         if (!osItf->bUsesGfxAddress && !osItf->bUsesPatchList)
61         {
62             MHW_ASSERTMESSAGE("No valid addressing mode indicated");
63             return;
64         }
65 
66         m_sfcScalabilitySupported = false;
67         m_sfcScalabilityEnabled   = false;
68         m_indexofSfc              = 0;
69         m_numofSfc                = 1;
70 
71         // Get Memory control object directly from MOS.
72         // If any override is needed, something like pfnOverrideMemoryObjectCtrl() / pfnComposeSurfaceCacheabilityControl()
73         // will need to be implemented.
74         m_outputSurfCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
75             MOS_HW_RESOURCE_USAGE_VP_OUTPUT_PICTURE_FF,
76             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
77 
78         m_avsLineBufferCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
79             MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF,
80             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
81         m_iefLineBufferCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
82             MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF,
83             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
84 
85         m_sfdLineBufferCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
86             MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED,
87             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
88         m_avsLineTileBufferCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
89             MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED,
90             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
91         m_iefLineTileBufferCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
92             MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED,
93             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
94         m_sfdLineTileBufferCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
95             MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED,
96             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
97         m_histogramBufferCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
98             MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED,
99             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
100         m_sfcIndirectBufferCtrl.Value = osItf->pfnCachePolicyGetMemoryObject(
101             MOS_CODEC_RESOURCE_USAGE_SURFACE_UNCACHED,
102             osItf->pfnGetGmmClientContext(osItf)).DwordValue;
103 
104         m_maxWidth  = MHW_SFC_MAX_WIDTH;
105         m_maxHeight = MHW_SFC_MAX_HEIGHT;
106     };
107 
MosGetHWTileType(MOS_TILE_TYPE tileType,MOS_TILE_MODE_GMM tileModeGMM,bool gmmTileEnabled)108     static __inline uint32_t MosGetHWTileType(MOS_TILE_TYPE tileType, MOS_TILE_MODE_GMM tileModeGMM, bool gmmTileEnabled)
109     {
110         uint32_t tileMode = 0;
111 
112         if (gmmTileEnabled)
113         {
114             return tileModeGMM;
115         }
116 
117         switch (tileType)
118         {
119         case MOS_TILE_LINEAR:
120             tileMode = 0;
121             break;
122         case MOS_TILE_YS:
123             tileMode = 1;
124             break;
125         case MOS_TILE_X:
126             tileMode = 2;
127             break;
128         default:
129             tileMode = 3;
130             break;
131         }
132         return tileMode;
133     }
134 
SetSfcAVSChromaTable(PSFC_AVS_CHROMA_FILTER_COEFF pUVCoeffTable,int32_t * piUVCoefsX,int32_t * piUVCoefsY)135     void SetSfcAVSChromaTable(
136         PSFC_AVS_CHROMA_FILTER_COEFF pUVCoeffTable,
137         int32_t                      *piUVCoefsX,
138         int32_t                      *piUVCoefsY)
139     {
140         int32_t i;
141 
142         MHW_CHK_NULL_NO_STATUS_RETURN(pUVCoeffTable);
143         MHW_CHK_NULL_NO_STATUS_RETURN(piUVCoefsX);
144         MHW_CHK_NULL_NO_STATUS_RETURN(piUVCoefsY);
145 
146         for (i = 0; i < NUM_HW_POLYPHASE_TABLES; i++, pUVCoeffTable++)
147         {
148             pUVCoeffTable->DW0.Table1XFilterCoefficient2 = *(piUVCoefsX++);
149             pUVCoeffTable->DW0.Table1XFilterCoefficient3 = *(piUVCoefsX++);
150             pUVCoeffTable->DW1.Table1XFilterCoefficient4 = *(piUVCoefsX++);
151             pUVCoeffTable->DW1.Table1XFilterCoefficient5 = *(piUVCoefsX++);
152 
153             pUVCoeffTable->DW0.Table1YFilterCoefficient2 = *(piUVCoefsY++);
154             pUVCoeffTable->DW0.Table1YFilterCoefficient3 = *(piUVCoefsY++);
155             pUVCoeffTable->DW1.Table1YFilterCoefficient4 = *(piUVCoefsY++);
156             pUVCoeffTable->DW1.Table1YFilterCoefficient5 = *(piUVCoefsY++);
157         }
158     }
159 
SetSfcAVSLumaTable(MOS_FORMAT SrcFormat,PSFC_AVS_LUMA_FILTER_COEFF pCoeffTable,int32_t * piYCoefsX,int32_t * piYCoefsY,bool bUse8x8Filter)160     void SetSfcAVSLumaTable(
161         MOS_FORMAT                      SrcFormat,
162         PSFC_AVS_LUMA_FILTER_COEFF      pCoeffTable,
163         int32_t * piYCoefsX,
164         int32_t * piYCoefsY,
165         bool                            bUse8x8Filter)
166     {
167         int32_t i;
168 
169         MHW_CHK_NULL_NO_STATUS_RETURN(pCoeffTable);
170         MHW_CHK_NULL_NO_STATUS_RETURN(piYCoefsX);
171         MHW_CHK_NULL_NO_STATUS_RETURN(piYCoefsY);
172 
173         for (i = 0; i < NUM_HW_POLYPHASE_TABLES; i++, pCoeffTable++)
174         {
175             // 4-tap filtering for G-channel, update only center 4 coeffs.
176             if (IS_RGB32_FORMAT(SrcFormat) && (!bUse8x8Filter))
177             {
178                 pCoeffTable->DW0.Table0XFilterCoefficient0 = 0;
179                 pCoeffTable->DW0.Table0XFilterCoefficient1 = 0;
180                 pCoeffTable->DW1.Table0XFilterCoefficient2 = *(piYCoefsX++);
181                 pCoeffTable->DW1.Table0XFilterCoefficient3 = *(piYCoefsX++);
182                 pCoeffTable->DW2.Table0XFilterCoefficient4 = *(piYCoefsX++);
183                 pCoeffTable->DW2.Table0XFilterCoefficient5 = *(piYCoefsX++);
184                 pCoeffTable->DW3.Table0XFilterCoefficient6 = 0;
185                 pCoeffTable->DW3.Table0XFilterCoefficient7 = 0;
186 
187                 pCoeffTable->DW0.Table0YFilterCoefficient0 = 0;
188                 pCoeffTable->DW0.Table0YFilterCoefficient1 = 0;
189                 pCoeffTable->DW1.Table0YFilterCoefficient2 = *(piYCoefsY++);
190                 pCoeffTable->DW1.Table0YFilterCoefficient3 = *(piYCoefsY++);
191                 pCoeffTable->DW2.Table0YFilterCoefficient4 = *(piYCoefsY++);
192                 pCoeffTable->DW2.Table0YFilterCoefficient5 = *(piYCoefsY++);
193                 pCoeffTable->DW3.Table0YFilterCoefficient6 = 0;
194                 pCoeffTable->DW3.Table0YFilterCoefficient7 = 0;
195             }
196             else
197             {
198                 pCoeffTable->DW0.Table0XFilterCoefficient0 = *(piYCoefsX++);
199                 pCoeffTable->DW0.Table0XFilterCoefficient1 = *(piYCoefsX++);
200                 pCoeffTable->DW1.Table0XFilterCoefficient2 = *(piYCoefsX++);
201                 pCoeffTable->DW1.Table0XFilterCoefficient3 = *(piYCoefsX++);
202                 pCoeffTable->DW2.Table0XFilterCoefficient4 = *(piYCoefsX++);
203                 pCoeffTable->DW2.Table0XFilterCoefficient5 = *(piYCoefsX++);
204                 pCoeffTable->DW3.Table0XFilterCoefficient6 = *(piYCoefsX++);
205                 pCoeffTable->DW3.Table0XFilterCoefficient7 = *(piYCoefsX++);
206 
207                 pCoeffTable->DW0.Table0YFilterCoefficient0 = *(piYCoefsY++);
208                 pCoeffTable->DW0.Table0YFilterCoefficient1 = *(piYCoefsY++);
209                 pCoeffTable->DW1.Table0YFilterCoefficient2 = *(piYCoefsY++);
210                 pCoeffTable->DW1.Table0YFilterCoefficient3 = *(piYCoefsY++);
211                 pCoeffTable->DW2.Table0YFilterCoefficient4 = *(piYCoefsY++);
212                 pCoeffTable->DW2.Table0YFilterCoefficient5 = *(piYCoefsY++);
213                 pCoeffTable->DW3.Table0YFilterCoefficient6 = *(piYCoefsY++);
214                 pCoeffTable->DW3.Table0YFilterCoefficient7 = *(piYCoefsY++);
215             }
216         }
217     }
218 
GetInputFrameWidthHeightAlignUnit(uint32_t & widthAlignUnit,uint32_t & heightAlignUnit,bool bVdbox,CODECHAL_STANDARD codecStandard,CodecDecodeJpegChromaType jpegChromaType)219     MOS_STATUS GetInputFrameWidthHeightAlignUnit(
220         uint32_t &widthAlignUnit,
221         uint32_t &heightAlignUnit,
222         bool bVdbox,
223         CODECHAL_STANDARD codecStandard,
224         CodecDecodeJpegChromaType jpegChromaType) override
225     {
226         if (bVdbox)
227         {
228             if (CODECHAL_JPEG == codecStandard && (jpegYUV400 == jpegChromaType ||
229                                                       jpegYUV444 == jpegChromaType || jpegYUV422H2Y == jpegChromaType) ||
230                 jpegBGR == jpegChromaType || jpegRGB == jpegChromaType)
231             {
232                 widthAlignUnit  = 8;
233                 heightAlignUnit = 8;
234                 return MOS_STATUS_SUCCESS;
235             }
236             else if (CODECHAL_HEVC == codecStandard || CODECHAL_VP9 == codecStandard)
237             {
238                 widthAlignUnit  = 8;
239                 heightAlignUnit = 8;
240                 return MOS_STATUS_SUCCESS;
241             }
242             else if (CODECHAL_AV1 == codecStandard)
243             {
244                 widthAlignUnit  = 1;
245                 heightAlignUnit = 1;
246                 return MOS_STATUS_SUCCESS;
247             }
248             else
249             {
250                 widthAlignUnit  = 16;
251                 heightAlignUnit = 16;
252                 return MOS_STATUS_SUCCESS;
253             }
254         }
255         else
256         {
257             widthAlignUnit  = m_veWidthAlignment;
258             heightAlignUnit = m_veHeightAlignment;
259             return MOS_STATUS_SUCCESS;
260         }
261     }
262 
SetSfcAVSScalingMode(MHW_SCALING_MODE ScalingMode)263     MOS_STATUS SetSfcAVSScalingMode(
264         MHW_SCALING_MODE ScalingMode) override
265     {
266         m_scalingMode = ScalingMode;
267         return MOS_STATUS_SUCCESS;
268     }
269 
GetInputMinWidthHeightInfo(uint32_t & width,uint32_t & height)270     MOS_STATUS GetInputMinWidthHeightInfo(uint32_t &width, uint32_t &height) override
271     {
272         width  = m_inputMinWidth;
273         height = m_inputMinHeight;
274         return MOS_STATUS_SUCCESS;
275     }
276 
GetOutputMinWidthHeightInfo(uint32_t & width,uint32_t & height)277     MOS_STATUS GetOutputMinWidthHeightInfo(uint32_t &width, uint32_t &height) override
278     {
279         width  = m_outputMinWidth;
280         height = m_outputMinHeight;
281         return MOS_STATUS_SUCCESS;
282     }
283 
GetMinWidthHeightInfo(uint32_t & width,uint32_t & height)284     MOS_STATUS GetMinWidthHeightInfo(uint32_t &width, uint32_t &height) override
285     {
286         width = m_minWidth;
287         height = m_minHeight;
288         return MOS_STATUS_SUCCESS;
289     }
290 
GetMaxWidthHeightInfo(uint32_t & width,uint32_t & height)291     MOS_STATUS GetMaxWidthHeightInfo(uint32_t &width, uint32_t &height) override
292     {
293         width  = m_maxWidth;
294         height = m_maxHeight;
295         return MOS_STATUS_SUCCESS;
296     }
297 
GetScalingRatioLimit(float & minScalingRatio,float & maxScalingRatio)298     MOS_STATUS GetScalingRatioLimit(float &minScalingRatio, float &maxScalingRatio) override
299     {
300         minScalingRatio = m_minScalingRatio;
301         maxScalingRatio = m_maxScalingRatio;
302         return MOS_STATUS_SUCCESS;
303     }
304 
SetSfcSamplerTable(SFC_AVS_LUMA_Coeff_Table_PAR * pLumaTable,SFC_AVS_CHROMA_Coeff_Table_PAR * pChromaTable,PMHW_AVS_PARAMS pAvsParams,MOS_FORMAT srcFormat,float fScaleX,float fScaleY,uint32_t dwChromaSiting,bool bUse8x8Filter,float fHPStrength,float fLanczosT)305     MOS_STATUS SetSfcSamplerTable(
306         SFC_AVS_LUMA_Coeff_Table_PAR   *pLumaTable,
307         SFC_AVS_CHROMA_Coeff_Table_PAR *pChromaTable,
308         PMHW_AVS_PARAMS           pAvsParams,
309         MOS_FORMAT                srcFormat,
310         float                     fScaleX,
311         float                     fScaleY,
312         uint32_t                  dwChromaSiting,
313         bool                      bUse8x8Filter,
314         float                     fHPStrength,
315         float                     fLanczosT) override
316     {
317         MHW_FUNCTION_ENTER;
318 
319         int32_t * piYCoefsX, *piYCoefsY;
320         int32_t * piUVCoefsX, *piUVCoefsY;
321         MHW_PLANE Plane;
322 
323         MHW_CHK_NULL_RETURN(pLumaTable);
324         MHW_CHK_NULL_RETURN(pChromaTable);
325         MHW_CHK_NULL_RETURN(pAvsParams);
326 
327         fHPStrength = 0.0F;
328         piYCoefsX   = pAvsParams->piYCoefsX;
329         piYCoefsY   = pAvsParams->piYCoefsY;
330         piUVCoefsX  = pAvsParams->piUVCoefsX;
331         piUVCoefsY  = pAvsParams->piUVCoefsY;
332 
333         // Skip calculation if no changes to AVS parameters
334         if (srcFormat == pAvsParams->Format &&
335             fScaleX == pAvsParams->fScaleX  &&
336             fScaleY == pAvsParams->fScaleY  &&
337             bUse8x8Filter == pAvsParams->bUse8x8Filter)
338         {
339             MHW_NORMALMESSAGE("Skip calculation since no changes to AVS parameters. srcFormat %d, fScaleX %f, fScaleY %f",
340                 srcFormat, fScaleX, fScaleY);
341 
342             SetSfcAVSLumaTable(
343                 srcFormat,
344                 pLumaTable->LumaTable,
345                 piYCoefsX,
346                 piYCoefsY,
347                 bUse8x8Filter);
348 
349             SetSfcAVSChromaTable(
350                 pChromaTable->ChromaTable,
351                 piUVCoefsX,
352                 piUVCoefsY);
353             return MOS_STATUS_SUCCESS;
354         }
355 
356         // AVS Coefficients don't change for Scaling Factors > 1.0x
357         // Hence recalculation is avoided
358         if (fScaleX > 1.0F && pAvsParams->fScaleX > 1.0F)
359         {
360             pAvsParams->fScaleX = fScaleX;
361         }
362 
363         // AVS Coefficients don't change for Scaling Factors > 1.0x
364         // Hence recalculation is avoided
365         if (fScaleY > 1.0F && pAvsParams->fScaleY > 1.0F)
366         {
367             pAvsParams->fScaleY = fScaleY;
368         }
369 
370         MHW_NORMALMESSAGE("srcFormat %d, pAvsParams->Format %d, fScaleX %f, fScaleY %f, pAvsParams->fScaleX %f, pAvsParams->fScaleY %f, pAvsParams->bUse8x8Filter %d, bUse8x8Filter %d, m_scalingMode %d, bForcePolyPhaseCoefs %d",
371             srcFormat, pAvsParams->Format, fScaleX, fScaleY, pAvsParams->fScaleX, pAvsParams->fScaleY, pAvsParams->bUse8x8Filter, bUse8x8Filter, m_scalingMode, (pAvsParams->bForcePolyPhaseCoefs ? 1 : 0));
372 
373         // Recalculate Horizontal scaling table
374         if (srcFormat != pAvsParams->Format || fScaleX != pAvsParams->fScaleX || pAvsParams->bUse8x8Filter != bUse8x8Filter)
375         {
376             MOS_ZeroMemory(
377                 piYCoefsX,
378                 8 * 32 * sizeof(int32_t));
379 
380             MOS_ZeroMemory(
381                 piUVCoefsX,
382                 4 * 32 * sizeof(int32_t));
383 
384             Plane = (IS_RGB32_FORMAT(srcFormat) && !bUse8x8Filter) ? MHW_U_PLANE : MHW_Y_PLANE;
385 
386             pAvsParams->fScaleX = fScaleX;
387 
388             if (m_scalingMode == MHW_SCALING_NEAREST)
389             {
390                 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
391                     piYCoefsX,
392                     Plane,
393                     true));
394                 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
395                     piUVCoefsX,
396                     MHW_U_PLANE,
397                     true));
398             }
399             else
400             {
401                 // For 1x scaling in horizontal direction and not force polyphase coefs, use special coefficients for filtering
402                 if ((fScaleX == 1.0F && !pAvsParams->bForcePolyPhaseCoefs))
403                 {
404                     MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
405                         piYCoefsX,
406                         Plane,
407                         true));
408 
409                     // The 8-tap adaptive is enabled for all channel if RGB format input, then UV/RB use the same coefficient as Y/G
410                     // So, coefficient for UV/RB channels caculation can be passed
411                     if ((!(IS_RGB32_FORMAT(srcFormat) && bUse8x8Filter)))
412                     {
413                         MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
414                             piUVCoefsX,
415                             MHW_U_PLANE,
416                             true));
417                     }
418                 }
419                 else
420                 {
421                     // Clamp the Scaling Factor if > 1.0x
422                     fScaleX = MOS_MIN(1.0F, fScaleX);
423 
424                     MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesY(
425                         piYCoefsX,
426                         fScaleX,
427                         Plane,
428                         srcFormat,
429                         fHPStrength,
430                         bUse8x8Filter,
431                         NUM_HW_POLYPHASE_TABLES,
432                         0));
433                 }
434 
435                 // The 8-tap adaptive is enabled for all channel if RGB format input, then UV/RB use the same coefficient as Y/G
436                 // So, coefficient for UV/RB channels caculation can be passed
437                 if (!(IS_RGB32_FORMAT(srcFormat) && bUse8x8Filter))
438                 {
439                     // If Chroma Siting info is present
440                     if (dwChromaSiting & MHW_CHROMA_SITING_HORZ_LEFT)
441                     {
442                         // No Chroma Siting
443                         MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesUV(
444                             piUVCoefsX,
445                             2.0F,
446                             fScaleX));
447                     }
448                     else
449                     {
450                         // Chroma siting offset will be add in the HW cmd
451                         MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesUV(
452                             piUVCoefsX,
453                             3.0F,
454                             fScaleX));
455                     }
456                 }
457             }
458         }
459 
460         // Recalculate Vertical scaling table
461         if (srcFormat != pAvsParams->Format || fScaleY != pAvsParams->fScaleY || pAvsParams->bUse8x8Filter != bUse8x8Filter)
462         {
463             MOS_ZeroMemory(piYCoefsY, 8 * 32 * sizeof(int32_t));
464             MOS_ZeroMemory(piUVCoefsY, 4 * 32 * sizeof(int32_t));
465 
466             Plane = (IS_RGB32_FORMAT(srcFormat) && !bUse8x8Filter) ? MHW_U_PLANE : MHW_Y_PLANE;
467 
468             pAvsParams->fScaleY = fScaleY;
469 
470             if (m_scalingMode == MHW_SCALING_NEAREST)
471             {
472                 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
473                     piYCoefsY,
474                     Plane,
475                     true));
476                 MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
477                     piUVCoefsY,
478                     MHW_U_PLANE,
479                     true));
480             }
481             else
482             {
483                 // For 1x scaling in vertical direction and not force polyphase coefs, use special coefficients for filtering
484                 if ((fScaleY == 1.0F && !pAvsParams->bForcePolyPhaseCoefs))
485                 {
486                     MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
487                         piYCoefsY,
488                         Plane,
489                         true));
490 
491                     // The 8-tap adaptive is enabled for all channel if RGB format input, then UV/RB use the same coefficient as Y/G
492                     // So, coefficient for UV/RB channels caculation can be passed
493                     if ((!(IS_RGB32_FORMAT(srcFormat) && bUse8x8Filter)))
494                     {
495                         MHW_CHK_STATUS_RETURN(Mhw_SetNearestModeTable(
496                             piUVCoefsY,
497                             MHW_U_PLANE,
498                             true));
499                     }
500                 }
501                 else
502                 {
503                     // Clamp the Scaling Factor if > 1.0x
504                     fScaleY = MOS_MIN(1.0F, fScaleY);
505 
506                     MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesY(
507                         piYCoefsY,
508                         fScaleY,
509                         Plane,
510                         srcFormat,
511                         fHPStrength,
512                         bUse8x8Filter,
513                         NUM_HW_POLYPHASE_TABLES,
514                         0));
515                 }
516 
517                 // The 8-tap adaptive is enabled for all channel if RGB format input, then UV/RB use the same coefficient as Y/G
518                 // So, coefficient for UV/RB channels caculation can be passed
519                 if (!(IS_RGB32_FORMAT(srcFormat) && bUse8x8Filter))
520                 {
521                     // If Chroma Siting info is present
522                     if (dwChromaSiting & MHW_CHROMA_SITING_VERT_TOP)
523                     {
524                         // No Chroma Siting
525                         MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesUV(
526                             piUVCoefsY,
527                             2.0F,
528                             fScaleY));
529                     }
530                     else
531                     {
532                         // Chroma siting offset will be add in the HW cmd
533                         MHW_CHK_STATUS_RETURN(Mhw_CalcPolyphaseTablesUV(
534                             piUVCoefsY,
535                             3.0F,
536                             fScaleY));
537                     }
538                 }
539             }
540         }
541 
542         // Save format used to calculate AVS parameters
543         pAvsParams->Format = srcFormat;
544         // Need to recaculate if use8x8Filter changed
545         pAvsParams->bUse8x8Filter = bUse8x8Filter;
546 
547         SetSfcAVSLumaTable(
548             srcFormat,
549             pLumaTable->LumaTable,
550             piYCoefsX,
551             piYCoefsY,
552             bUse8x8Filter);
553 
554         SetSfcAVSChromaTable(
555             pChromaTable->ChromaTable,
556             piUVCoefsX,
557             piUVCoefsY);
558 
559         return MOS_STATUS_SUCCESS;
560     }
561 
562     //!
563     //! \brief    Set which Sfc can be used by HW
564     //! \details  VPHAL set which Sfc can be use by HW
565     //! \param    [in] dwSfcIndex;
566     //!           set which Sfc can be used by HW
567     //! \param    [in] dwSfcCount;
568     //!           set Sfc Count
569     //! \return   MOS_STATUS
570     //!           MOS_STATUS_SUCCESS if success, else fail reason
SetSfcIndex(uint32_t dwSfcIndex,uint32_t dwSfcCount)571     MOS_STATUS SetSfcIndex(
572         uint32_t dwSfcIndex,
573         uint32_t dwSfcCount) override
574     {
575         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
576 
577         MHW_ASSERT(dwSfcIndex < dwSfcCount);
578 
579         m_indexofSfc            = dwSfcIndex;
580         m_numofSfc              = dwSfcCount;
581         m_sfcScalabilityEnabled = (dwSfcCount > 1) ? true : false;
582 
583         return eStatus;
584     }
585 
IsOutPutCenterEnable(bool inputEnable)586     void IsOutPutCenterEnable(bool inputEnable) override
587     {
588         m_outputCenteringEnable = inputEnable;
589     }
590 
_MHW_SETCMD_OVERRIDE_DECL(SFC_LOCK)591     _MHW_SETCMD_OVERRIDE_DECL(SFC_LOCK)
592     {
593         _MHW_SETCMD_CALLBASE(SFC_LOCK);
594 
595         cmd.DW1.VeSfcPipeSelect                    = (params.sfcPipeMode == SFC_PIPE_MODE::SFC_PIPE_MODE_VEBOX) ? 1 : 0;
596         cmd.DW1.PreScaledOutputSurfaceOutputEnable = params.bOutputToMemory ? 1 : 0;
597 
598         return MOS_STATUS_SUCCESS;
599     }
600 
_MHW_SETCMD_OVERRIDE_DECL(SFC_FRAME_START)601     _MHW_SETCMD_OVERRIDE_DECL(SFC_FRAME_START)
602     {
603         _MHW_SETCMD_CALLBASE(SFC_FRAME_START);
604 
605         return MOS_STATUS_SUCCESS;
606     }
607 
_MHW_SETCMD_OVERRIDE_DECL(SFC_IEF_STATE)608     _MHW_SETCMD_OVERRIDE_DECL(SFC_IEF_STATE)
609     {
610         _MHW_SETCMD_CALLBASE(SFC_IEF_STATE);
611 
612         // Init SFC_IEF_STATE_CMD
613         cmd.DW1.GainFactor            = 0;
614         cmd.DW1.R3XCoefficient        = 0;
615         cmd.DW1.R3CCoefficient        = 0;
616         cmd.DW2.GlobalNoiseEstimation = 0;
617         cmd.DW2.R5XCoefficient        = 0;
618         cmd.DW2.R5CxCoefficient       = 0;
619         cmd.DW2.R5CCoefficient        = 0;
620 
621         cmd.DW3.StdSinAlpha  = 101;
622         cmd.DW3.StdCosAlpha  = 79;
623         cmd.DW5.DiamondAlpha = 100;
624         cmd.DW7.InvMarginVyl = 3300;
625         cmd.DW8.InvMarginVyu = 1600;
626         cmd.DW10.S0L         = MOS_BITFIELD_VALUE((uint32_t)-5, 11);
627         cmd.DW10.YSlope2     = 31;
628         cmd.DW12.YSlope1     = 31;
629         cmd.DW14.S0U         = 256;
630         cmd.DW15.S1U         = 113;
631         cmd.DW15.S2U         = MOS_BITFIELD_VALUE((uint32_t)-179, 11);
632 
633         // Set IEF Params
634         if (params.bIEFEnable)
635         {
636             cmd.DW1.GainFactor          = params.dwGainFactor;
637             cmd.DW1.StrongEdgeThreshold = params.StrongEdgeThreshold;
638             cmd.DW1.R3XCoefficient      = params.dwR3xCoefficient;
639             cmd.DW1.R3CCoefficient      = params.dwR3cCoefficient;
640             cmd.DW2.StrongEdgeWeight    = params.StrongEdgeWeight;
641             cmd.DW2.RegularWeight       = params.RegularWeight;
642             cmd.DW2.R5XCoefficient      = params.dwR5xCoefficient;
643             cmd.DW2.R5CxCoefficient     = params.dwR5cxCoefficient;
644             cmd.DW2.R5CCoefficient      = params.dwR5cCoefficient;
645             cmd.DW4.VyStdEnable         = params.bVYSTDEnable;
646             cmd.DW5.SkinDetailFactor    = params.bSkinDetailFactor;
647         }
648 
649         // Set CSC Params
650         if (params.bCSCEnable)
651         {
652             MHW_CHK_NULL_RETURN(params.pfCscCoeff);
653             MHW_CHK_NULL_RETURN(params.pfCscInOffset);
654             MHW_CHK_NULL_RETURN(params.pfCscOutOffset);
655             cmd.DW16.TransformEnable = true;
656 
657             cmd.DW16.C0 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[0] * 1024.0F);  // S2.10
658             cmd.DW16.C1 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[1] * 1024.0F);  // S2.10
659             cmd.DW17.C2 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[2] * 1024.0F);  // S2.10
660 
661             cmd.DW17.C3 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[3] * 1024.0F);  // S2.10
662             cmd.DW18.C4 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[4] * 1024.0F);  // S2.10
663             cmd.DW18.C5 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[5] * 1024.0F);  // S2.10
664 
665             cmd.DW19.C6 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[6] * 1024.0F);  // S2.10
666             cmd.DW19.C7 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[7] * 1024.0F);  // S2.10
667             cmd.DW20.C8 = (uint32_t)MOS_F_ROUND(params.pfCscCoeff[8] * 1024.0F);  // S2.10
668 
669             cmd.DW21.OffsetIn1 = (uint32_t)MOS_F_ROUND(params.pfCscInOffset[0] * 4.0F);  // S8.2
670             cmd.DW22.OffsetIn2 = (uint32_t)MOS_F_ROUND(params.pfCscInOffset[1] * 4.0F);  // S8.2
671             cmd.DW23.OffsetIn3 = (uint32_t)MOS_F_ROUND(params.pfCscInOffset[2] * 4.0F);  // S8.2
672 
673             cmd.DW21.OffsetOut1 = (uint32_t)MOS_F_ROUND(params.pfCscOutOffset[0] * 4.0F);  // S8.2
674             cmd.DW22.OffsetOut2 = (uint32_t)MOS_F_ROUND(params.pfCscOutOffset[1] * 4.0F);  // S8.2
675             cmd.DW23.OffsetOut3 = (uint32_t)MOS_F_ROUND(params.pfCscOutOffset[2] * 4.0F);  // S8.2
676         }
677 
678         return MOS_STATUS_SUCCESS;
679     }
680 
_MHW_SETCMD_OVERRIDE_DECL(SFC_AVS_CHROMA_Coeff_Table)681     _MHW_SETCMD_OVERRIDE_DECL(SFC_AVS_CHROMA_Coeff_Table)
682     {
683         _MHW_SETCMD_CALLBASE(SFC_AVS_CHROMA_Coeff_Table);
684 
685         //PSFC_AVS_CHROMA_FILTER_COEFF pChromaCoeff;
686         //pChromaCoeff = params.ChromaTable;
687 
688         // Copy programmed State tables into the command
689         MHW_CHK_STATUS_RETURN(MOS_SecureMemcpy(
690             &(cmd.DW1),
691             sizeof(SFC_AVS_CHROMA_FILTER_COEFF) * 32,
692             params.ChromaTable,
693             sizeof(SFC_AVS_CHROMA_FILTER_COEFF) * 32));
694 
695         return MOS_STATUS_SUCCESS;
696     }
697 
_MHW_SETCMD_OVERRIDE_DECL(SFC_AVS_LUMA_Coeff_Table)698     _MHW_SETCMD_OVERRIDE_DECL(SFC_AVS_LUMA_Coeff_Table)
699     {
700         _MHW_SETCMD_CALLBASE(SFC_AVS_LUMA_Coeff_Table);
701 
702         //PSFC_AVS_LUMA_FILTER_COEFF pLumaCoeff;
703         //pLumaCoeff = params.LumaTable;
704 
705         // Copy programmed State tables into the command
706         MHW_CHK_STATUS_RETURN(MOS_SecureMemcpy(
707             &(cmd.DW1),
708             sizeof(SFC_AVS_LUMA_FILTER_COEFF) * 32,
709             params.LumaTable,
710             sizeof(SFC_AVS_LUMA_FILTER_COEFF) * 32));
711 
712         return MOS_STATUS_SUCCESS;
713     }
714 
_MHW_SETCMD_OVERRIDE_DECL(SFC_AVS_STATE)715     _MHW_SETCMD_OVERRIDE_DECL(SFC_AVS_STATE)
716     {
717         _MHW_SETCMD_CALLBASE(SFC_AVS_STATE);
718 
719        // Inilizatialied the SFC_AVS_STATE_CMD
720         cmd.DW1.TransitionAreaWith8Pixels = 5;
721         cmd.DW1.TransitionAreaWith4Pixels = 4;
722         if (params.dwAVSFilterMode == MEDIASTATE_SFC_AVS_FILTER_BILINEAR)
723         {
724             cmd.DW1.SharpnessLevel = 0;
725         }
726         else
727         {
728             cmd.DW1.SharpnessLevel = 255;
729         }
730 
731         cmd.DW2.MaxDerivativePoint8  = 20;
732         cmd.DW2.MaxDerivative4Pixels = 7;
733 
734         return MOS_STATUS_SUCCESS;
735     }
736 
737 protected:
738     using base_t = Itf;
739 
740     bool     m_outputCenteringEnable   = true;
741     bool     m_sfcScalabilitySupported = false;
742     bool     m_sfcScalabilityEnabled   = false;
743     uint32_t m_indexofSfc              = 0;
744     uint32_t m_numofSfc                = 0;
745 
746     uint16_t                           m_veWidthAlignment      = MHW_SFC_VE_WIDTH_ALIGN;
747     uint16_t                           m_veHeightAlignment     = MHW_SFC_VE_HEIGHT_ALIGN;
748     uint32_t                           m_maxWidth              = MHW_SFC_MAX_WIDTH;
749     uint32_t                           m_maxHeight             = MHW_SFC_MAX_HEIGHT;
750     uint32_t                           m_minWidth              = MHW_SFC_MIN_WIDTH;
751     uint32_t                           m_minHeight             = MHW_SFC_MIN_HEIGHT;
752     uint32_t                           m_inputMinWidth         = MHW_SFC_MIN_WIDTH;             // SFC input min width size for ve+sfc
753     uint32_t                           m_inputMinHeight        = MHW_SFC_MIN_HEIGHT;            // SFC input min height size for ve+sfc
754     uint32_t                           m_outputMinWidth        = MHW_SFC_OUTPUT_MIN_WIDTH;      // SFC output min width size for ve+sfc
755     uint32_t                           m_outputMinHeight       = MHW_SFC_OUTPUT_MIN_HEIGHT;     // SFC output min height size for ve+sfc
756 
757     float                              m_maxScalingRatio       = MHW_SFC_MAX_SCALINGFACTOR;
758     float                              m_minScalingRatio       = MHW_SFC_MIN_SCALINGFACTOR;
759 
760     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_outputSurfCtrl        = {};   // Output Frame caching control bits
761     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_avsLineBufferCtrl     = {};   // AVS Line Buffer caching control bits
762     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_iefLineBufferCtrl     = {};   // IEF Line Buffer caching control bits
763     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_sfdLineBufferCtrl     = {};   // SFD Line Buffer caching control bits
764     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_avsLineTileBufferCtrl = {};   // AVS Line Tile Buffer caching control bits
765     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_iefLineTileBufferCtrl = {};   // IEF Line Tile Buffer caching control bits
766     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_sfdLineTileBufferCtrl = {};   // SFD Line Tile Buffer caching control bits
767     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_histogramBufferCtrl   = {};   // Histogram Buffer caching control bits
768     MHW_MEMORY_OBJECT_CONTROL_PARAMS   m_sfcIndirectBufferCtrl = {};   // SfcIndirect Buffer caching control bits
769     MHW_SCALING_MODE                   m_scalingMode           = MHW_SCALING_NEAREST;
770 MEDIA_CLASS_DEFINE_END(mhw__sfc__Impl)
771 };
772 }  // namespace sfc
773 }  // namespace mhw
774 
775 #endif  // __MHW_SFC_IMPL_H__
776