1 /*
2 * Copyright (c) 2012-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     vphal_render_sfc_g12_base.cpp
24 //! \brief    VPHAL SFC Gen12 rendering component
25 //! \details  The SFC renderer supports Scaling, IEF, CSC/ColorFill and Rotation.
26 //!           It's responsible for setting up HW states and generating the SFC
27 //!           commands.
28 //!
29 #include "mhw_sfc_g12_X.h"
30 #include "vphal_render_vebox_base.h"
31 #include "vphal_render_sfc_g12_base.h"
32 #include "vp_hal_ddi_utils.h"
33 
34 #if __VPHAL_SFC_SUPPORTED
35 
VphalSfcStateG12(PMOS_INTERFACE osInterface,PRENDERHAL_INTERFACE renderHal,PMHW_SFC_INTERFACE sfcInterface)36 VphalSfcStateG12::VphalSfcStateG12(
37     PMOS_INTERFACE       osInterface,
38     PRENDERHAL_INTERFACE renderHal,
39     PMHW_SFC_INTERFACE   sfcInterface)
40     : VphalSfcState(osInterface, renderHal, sfcInterface)
41 {
42     // Setup disable render flag controlled by a user feature key for validation purpose
43     // Enable output centering by default on Gen12+
44     ReadUserSetting(
45         m_userSettingPtr,
46         m_disableOutputCentering,
47         __MEDIA_USER_FEATURE_VALUE_SFC_OUTPUT_CENTERING_DISABLE,
48         MediaUserSetting::Group::Sequence);
49 }
50 
IsFormatSupported(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutSurface,PVPHAL_ALPHA_PARAMS pAlphaParams)51 bool VphalSfcStateG12::IsFormatSupported(
52     PVPHAL_SURFACE      pSrcSurface,
53     PVPHAL_SURFACE      pOutSurface,
54     PVPHAL_ALPHA_PARAMS pAlphaParams)
55 {
56     // Init to false for in case the input parameters are nullptr
57     bool ret = false;
58 
59     VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrcSurface);
60     VPHAL_RENDER_CHK_NULL_NO_STATUS(pOutSurface);
61 
62     // Default to true
63     ret = true;
64 
65     // Check if Input Format is supported
66     if (!IsInputFormatSupported(pSrcSurface))
67     {
68         VPHAL_RENDER_NORMALMESSAGE("Unsupported Source Format '0x%08x' for SFC.", pSrcSurface->Format);
69         ret = false;
70         return ret;
71     }
72 
73     // SFC can not support fp16 output. HDR path is the only way to handle any fp16 output.
74     // Before entering into HDR path, it is possible that we need to use SFC to do P010->ARGB10.
75     // As for SFC is needed or not, we use bHDRSfc to decide.
76     if (pOutSurface->Format == Format_A16R16G16B16F ||
77         pOutSurface->Format == Format_A16B16G16R16F)
78     {
79         ret = false;
80         return ret;
81     }
82 
83     // Check if Output Format is supported
84     if (!IsOutputFormatSupported(pOutSurface))
85     {
86         ret = false;
87         return ret;
88     }
89 
90     // Check if the input/output combination is supported, given certain alpha fill mode.
91     // So far SFC only supports filling constant alpha.
92     if (pAlphaParams &&
93         pAlphaParams->AlphaMode == VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM)
94     {
95         //No Alpha DDI for LIBVA, Always allow SFC to do detail feature on GEN12+ on linux
96         //No matter what the current alpha mode is.
97         if (pSrcSurface->bIEF == true)
98         {
99             pAlphaParams->AlphaMode = VPHAL_ALPHA_FILL_MODE_NONE;
100             pAlphaParams->fAlpha    = 1.0;
101             return true;
102         }
103         else if ((pOutSurface->Format == Format_A8R8G8B8 ||
104                 pOutSurface->Format == Format_A8B8G8R8 ||
105                 pOutSurface->Format == Format_R10G10B10A2 ||
106                 pOutSurface->Format == Format_B10G10R10A2 ||
107                 pOutSurface->Format == Format_Y410 ||
108                 pOutSurface->Format == Format_Y416 ||
109                 pOutSurface->Format == Format_AYUV) &&
110             (pSrcSurface->Format == Format_A8B8G8R8 ||
111                 pSrcSurface->Format == Format_A8R8G8B8 ||
112                 pSrcSurface->Format == Format_Y410 ||
113                 pSrcSurface->Format == Format_Y416 ||
114                 pSrcSurface->Format == Format_AYUV))
115         {
116             return false;
117         }
118     }
119 
120 finish:
121     return ret;
122 }
123 
IsInputFormatSupported(PVPHAL_SURFACE srcSurface)124 bool VphalSfcStateG12::IsInputFormatSupported(
125     PVPHAL_SURFACE              srcSurface)
126 {
127     bool ret = true;
128     // Check if Input Format is supported
129     if ((srcSurface->Format != Format_NV12)     &&
130         (srcSurface->Format != Format_AYUV)     &&
131         (srcSurface->Format != Format_P010)     &&
132         (srcSurface->Format != Format_P016)     &&
133         (srcSurface->Format != Format_Y410)     &&
134         (srcSurface->Format != Format_Y210)     &&
135         (srcSurface->Format != Format_Y416)     &&
136         (srcSurface->Format != Format_Y216)     &&
137         (srcSurface->Format != Format_A8B8G8R8) &&
138         (srcSurface->Format != Format_X8B8G8R8) &&
139         (srcSurface->Format != Format_A8R8G8B8) &&
140         (srcSurface->Format != Format_X8R8G8B8) &&
141         !IS_PA_FORMAT(srcSurface->Format))
142     {
143         VPHAL_RENDER_NORMALMESSAGE("Unsupported Source Format '0x%08x' for SFC.", srcSurface->Format);
144         ret = false;
145     }
146 
147     return ret;
148 }
149 
IsOutputFormatSupported(PVPHAL_SURFACE outSurface)150 bool VphalSfcStateG12::IsOutputFormatSupported(
151     PVPHAL_SURFACE              outSurface)
152 {
153     bool ret = true;
154 
155     if (!IS_RGB32_FORMAT(outSurface->Format)   &&
156         // Remove RGB565 support due to quality issue, may reopen this after root cause in the future.
157         //!IS_RGB16_FORMAT(outSurface->Format)   &&
158         outSurface->Format != Format_YUY2      &&
159         outSurface->Format != Format_UYVY      &&
160         outSurface->Format != Format_AYUV      &&
161         outSurface->Format != Format_Y210      &&
162         outSurface->Format != Format_Y410      &&
163         outSurface->Format != Format_Y216      &&
164         outSurface->Format != Format_Y416)
165     {
166         if (outSurface->TileType == MOS_TILE_Y &&
167              (outSurface->Format == Format_P010 ||
168               outSurface->Format == Format_P016 ||
169               outSurface->Format == Format_NV12))
170         {
171             ret = true;
172         }
173         else
174         {
175             VPHAL_RENDER_NORMALMESSAGE("Unsupported Render Target Format '0x%08x' for SFC Pipe.", outSurface->Format);
176             ret = false;
177         }
178     }
179 
180     return ret;
181 }
182 
GetInputWidthHeightAlignUnit(MOS_FORMAT inputFormat,MOS_FORMAT outputFormat,uint16_t & widthAlignUnit,uint16_t & heightAlignUnit,bool isInterlacedScaling)183 void VphalSfcStateG12::GetInputWidthHeightAlignUnit(
184     MOS_FORMAT              inputFormat,
185     MOS_FORMAT              outputFormat,
186     uint16_t                &widthAlignUnit,
187     uint16_t                &heightAlignUnit,
188     bool                    isInterlacedScaling)
189 {
190     MOS_UNUSED(outputFormat);
191     widthAlignUnit  = 1;
192     heightAlignUnit = 1;
193 
194     // Apply alignment restriction to Region of the input frame.
195     switch (VpHalDDIUtils::GetSurfaceColorPack(inputFormat))
196     {
197         case VPHAL_COLORPACK_420:
198             widthAlignUnit  = 2;
199             heightAlignUnit = 2;
200             break;
201         case VPHAL_COLORPACK_422:
202             widthAlignUnit  = 2;
203             break;
204         default:
205             break;
206     }
207 }
208 
IsOutputCapable(bool isColorFill,PVPHAL_SURFACE src,PVPHAL_SURFACE renderTarget)209 bool VphalSfcStateG12::IsOutputCapable(
210     bool            isColorFill,
211     PVPHAL_SURFACE  src,
212     PVPHAL_SURFACE  renderTarget)
213 {
214     bool isOutputCapable = false;
215     // Only Gen12 later H/W support ColorFill, the (OffsetX, OffsetY)
216     // of scaled region not being (0, 0) or the tile type not being
217     // Tile_Y on NV12/P010/P016 output surface. Disable SFC even if other
218     // features are supported before Gen12.
219     if ((isColorFill         ||
220         src->rcDst.top  != 0 ||
221         src->rcDst.left != 0 ||
222         renderTarget->TileType != MOS_TILE_Y) &&
223         (renderTarget->Format == Format_NV12 ||
224          renderTarget->Format == Format_P010 ||
225          renderTarget->Format == Format_P016))
226     {
227         if ((renderTarget->TileType == MOS_TILE_Y))
228         {
229             isOutputCapable = true;
230         }
231         else
232         {
233             isOutputCapable = false;
234         }
235     }
236     else
237     {
238         isOutputCapable = true;
239     }
240 
241     return isOutputCapable;
242 }
243 
DetermineCscParams(PVPHAL_SURFACE src,PVPHAL_SURFACE renderTarget)244 void VphalSfcStateG12::DetermineCscParams(
245     PVPHAL_SURFACE                  src,
246     PVPHAL_SURFACE                  renderTarget)
247 {
248     // Determine if CSC is required in SFC pipe
249     m_renderData.SfcInputCspace = src->ColorSpace;
250 
251     if (m_renderData.SfcInputCspace != renderTarget->ColorSpace)
252     {
253         m_renderData.bCSC = true;
254     }
255 }
256 
DetermineInputFormat(PVPHAL_SURFACE src,PVPHAL_VEBOX_RENDER_DATA veboxRenderData)257 void VphalSfcStateG12::DetermineInputFormat(
258     PVPHAL_SURFACE                  src,
259     PVPHAL_VEBOX_RENDER_DATA        veboxRenderData)
260 {
261     // Determine SFC input surface format
262     if (IS_RGB_FORMAT(src->Format))
263     {
264         m_renderData.SfcInputFormat = src->Format;
265     }
266     else if (veboxRenderData->bDeinterlace || veboxRenderData->bQueryVariance)
267     {
268         m_renderData.SfcInputFormat = Format_YUY2;
269     }
270     else
271     {
272         m_renderData.SfcInputFormat = src->Format;
273     }
274 }
275 
SetSfcStateParams(PVPHAL_VEBOX_RENDER_DATA pRenderData,PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutSurface)276 MOS_STATUS VphalSfcStateG12::SetSfcStateParams(
277     PVPHAL_VEBOX_RENDER_DATA    pRenderData,
278     PVPHAL_SURFACE              pSrcSurface,
279     PVPHAL_SURFACE              pOutSurface)
280 {
281     MOS_STATUS                  eStatus;
282     PMHW_SFC_STATE_PARAMS_G12   sfcStateParams;
283 
284     eStatus                = MOS_STATUS_UNKNOWN;
285     sfcStateParams         = static_cast<PMHW_SFC_STATE_PARAMS_G12>(m_renderData.SfcStateParams);
286     VPHAL_RENDER_CHK_NULL_RETURN(sfcStateParams);
287 
288     eStatus = VphalSfcState::SetSfcStateParams(pRenderData, pSrcSurface, pOutSurface);
289 
290     //set SFD linear surface
291     sfcStateParams->resSfdLineBuffer = Mos_ResourceIsNull(&m_SFDLineBufferSurface.OsResource) ? nullptr : &m_SFDLineBufferSurface.OsResource;
292 
293     VPHAL_RENDER_CHK_NULL_RETURN(m_sfcInterface);
294     MhwSfcInterfaceG12 *sfcInterface = dynamic_cast<MhwSfcInterfaceG12 *>(m_sfcInterface);
295     VPHAL_RENDER_CHK_NULL_RETURN(sfcInterface);
296     // Output centering
297     if (!m_disableOutputCentering)
298     {
299         sfcInterface->IsOutPutCenterEnable(true);
300     }
301     else
302     {
303         sfcInterface->IsOutPutCenterEnable(false);
304     }
305 
306     // ARGB8,ABGR10,A16B16G16R16,VYUY and YVYU output format need to enable swap
307     if (pOutSurface->Format == Format_X8R8G8B8     ||
308         pOutSurface->Format == Format_A8R8G8B8     ||
309         pOutSurface->Format == Format_R10G10B10A2  ||
310         pOutSurface->Format == Format_A16B16G16R16 ||
311         pOutSurface->Format == Format_VYUY         ||
312         pOutSurface->Format == Format_YVYU)
313     {
314         sfcStateParams->bRGBASwapEnable = true;
315     }
316     else
317     {
318         sfcStateParams->bRGBASwapEnable = false;
319     }
320 
321     // Enable Adaptive Filtering for YUV input only on Gen12LP, if it is being upscaled
322     // in either direction. We must check for this before clamping the SF.
323     if ((IS_YUV_FORMAT(m_renderData.SfcInputFormat) || (m_renderData.SfcInputFormat == Format_AYUV)) &&  // YUV format
324         (m_renderData.fScaleX > 1.0F || m_renderData.fScaleY > 1.0F) && // scaling ratio > 1
325         (sfcStateParams->dwAVSFilterMode != MEDIASTATE_SFC_AVS_FILTER_BILINEAR)) // AVS 8x8(VE+SFC) or 5X5 (VD+SFC)
326     {
327         sfcStateParams->bBypassXAdaptiveFilter = false;
328         sfcStateParams->bBypassYAdaptiveFilter = false;
329     }
330     else
331     {
332         sfcStateParams->bBypassXAdaptiveFilter = true;
333         sfcStateParams->bBypassYAdaptiveFilter = true;
334     }
335 
336     return eStatus;
337 }
338 
IsOutputPipeSfcFeasible(PCVPHAL_RENDER_PARAMS pcRenderParams,PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pRenderTarget)339 bool VphalSfcStateG12::IsOutputPipeSfcFeasible(
340     PCVPHAL_RENDER_PARAMS       pcRenderParams,
341     PVPHAL_SURFACE              pSrcSurface,
342     PVPHAL_SURFACE              pRenderTarget)
343 {
344     //!
345     //! \brief SFC can be the output pipe when the following conditions are all met
346     //!        1.  User feature keys value "SFC Disable" is false
347     //!        2.  Single render target only
348     //!        3.  Rotation disabled or ONLY Rotation enabled when the SFC output is Y-tile
349     //!        4.  For TGL, SFC support Mirror+Rotation when SFC output is Y-tile
350     //!        5.  i/o format is supported by SFC, taking into account the alpha fill info
351     //!        6. Comp DI(ARGB/ABGR) is disabled
352     //!        7. Variance Query is disabled
353     //!
354     if (IsDisabled()                            == false                                        &&
355         pcRenderParams->uDstCount               == 1                                            &&
356         (pSrcSurface->Rotation                  == VPHAL_ROTATION_IDENTITY                      ||
357          (pSrcSurface->Rotation                 <= VPHAL_ROTATION_270                           &&
358           pcRenderParams->pTarget[0]->TileType  == MOS_TILE_Y)                                  ||
359          (pSrcSurface->Rotation                 <= VPHAL_ROTATE_90_MIRROR_HORIZONTAL            &&
360           pcRenderParams->pTarget[0]->TileType  == MOS_TILE_Y                                   &&
361           GFX_IS_GEN_12_OR_LATER(m_renderHal->Platform)))                                       &&
362         IsFormatSupported(pSrcSurface, pcRenderParams->pTarget[0], pcRenderParams->pCompAlpha)  &&
363         (pSrcSurface->pDeinterlaceParams        == nullptr                                      ||
364          (pSrcSurface->Format != Format_A8R8G8B8 && pSrcSurface->Format != Format_A8B8G8R8))    &&
365         pSrcSurface->bQueryVariance             == false)
366     {
367         return true;
368     }
369 
370     return false;
371 }
372 
SetRenderingFlags(PVPHAL_COLORFILL_PARAMS pColorFillParams,PVPHAL_ALPHA_PARAMS pAlphaParams,PVPHAL_SURFACE pSrc,PVPHAL_SURFACE pRenderTarget,PVPHAL_VEBOX_RENDER_DATA pRenderData)373 void VphalSfcStateG12::SetRenderingFlags(
374     PVPHAL_COLORFILL_PARAMS  pColorFillParams,
375     PVPHAL_ALPHA_PARAMS      pAlphaParams,
376     PVPHAL_SURFACE           pSrc,
377     PVPHAL_SURFACE           pRenderTarget,
378     PVPHAL_VEBOX_RENDER_DATA pRenderData)
379 {
380     PRENDERHAL_INTERFACE    pRenderHal;
381     float                   fScaleX;
382     float                   fScaleY;
383     uint32_t                dwSurfaceWidth;
384     uint32_t                dwSurfaceHeight;
385     uint16_t                wWidthAlignUnit;
386     uint16_t                wHeightAlignUnit;
387     uint32_t                dwSourceRegionWidth;
388     uint32_t                dwSourceRegionHeight;
389     uint32_t                dwOutputRegionWidth;
390     uint32_t                dwOutputRegionHeight;
391     uint32_t                dwVeboxBottom;
392     uint32_t                dwVeboxRight;
393     VPHAL_COLORPACK         srcColorPack;
394     VPHAL_COLORPACK         dstColorPack;
395 
396     VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrc);
397     VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderTarget);
398 
399     pRenderHal       = m_renderHal;
400     wWidthAlignUnit  = 1;
401     wHeightAlignUnit = 1;
402     dwVeboxBottom    = (uint32_t)pSrc->rcSrc.bottom;
403     dwVeboxRight     = (uint32_t)pSrc->rcSrc.right;
404     srcColorPack     = VpHalDDIUtils::GetSurfaceColorPack(pSrc->Format);
405     dstColorPack     = VpHalDDIUtils::GetSurfaceColorPack(pRenderTarget->Format);
406 
407     // Get the SFC input surface size from Vebox
408     AdjustBoundary(
409         pSrc,
410         &dwSurfaceWidth,
411         &dwSurfaceHeight);
412 
413     // Apply alignment restriction to the source regions.
414     switch (srcColorPack)
415     {
416         case VPHAL_COLORPACK_420:
417             wWidthAlignUnit     = 2;
418             wHeightAlignUnit    = 2;
419             break;
420         case VPHAL_COLORPACK_422:
421             wWidthAlignUnit     = 2;
422             wHeightAlignUnit    = 1;
423             break;
424         default:
425             wWidthAlignUnit     = 1;
426             wHeightAlignUnit    = 1;
427             break;
428     }
429 
430     if(pSrc->bDirectionalScalar)
431     {
432         dwVeboxBottom *= 2;
433         dwVeboxRight  *= 2;
434     }
435 
436     // Region of the input frame which needs to be processed by SFC
437     dwSourceRegionHeight = MOS_ALIGN_FLOOR(
438                             MOS_MIN((uint32_t)(dwVeboxBottom - pSrc->rcSrc.top), dwSurfaceHeight),
439                             wHeightAlignUnit);
440     dwSourceRegionWidth  = MOS_ALIGN_FLOOR(
441                             MOS_MIN((uint32_t)(dwVeboxRight  - pSrc->rcSrc.left), dwSurfaceWidth),
442                             wWidthAlignUnit);
443 
444     // Apply alignment restriction to the scaled regions.
445     switch (dstColorPack)
446     {
447         case VPHAL_COLORPACK_420:
448             wWidthAlignUnit     = 2;
449             wHeightAlignUnit    = 2;
450             break;
451         case VPHAL_COLORPACK_422:
452             wWidthAlignUnit     = 2;
453             wHeightAlignUnit    = 1;
454             break;
455         default:
456             wWidthAlignUnit     = 1;
457             wHeightAlignUnit    = 1;
458             break;
459     }
460     // Size of the Output Region over the Render Target
461     dwOutputRegionHeight = MOS_ALIGN_CEIL(
462                             MOS_MIN((uint32_t)(pSrc->rcDst.bottom - pSrc->rcDst.top), pRenderTarget->dwHeight),
463                             wHeightAlignUnit);
464     dwOutputRegionWidth  = MOS_ALIGN_CEIL(
465                             MOS_MIN((uint32_t)(pSrc->rcDst.right - pSrc->rcDst.left), pRenderTarget->dwWidth),
466                             wWidthAlignUnit);
467 
468     // Calculate the scaling ratio
469     // Both source region and scaled region are pre-rotated
470     if (pSrc->Rotation == VPHAL_ROTATION_IDENTITY ||
471         pSrc->Rotation == VPHAL_ROTATION_180      ||
472         pSrc->Rotation == VPHAL_MIRROR_HORIZONTAL ||
473         pSrc->Rotation == VPHAL_MIRROR_VERTICAL)
474     {
475         fScaleX      = (float)dwOutputRegionWidth  / (float)dwSourceRegionWidth;
476         fScaleY      = (float)dwOutputRegionHeight / (float)dwSourceRegionHeight;
477     }
478     else
479     {
480         // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 || VPHAL_ROTATE_90_MIRROR_VERTICAL || VPHAL_ROTATE_90_MIRROR_HORIZONTAL
481         fScaleX      = (float)dwOutputRegionHeight / (float)dwSourceRegionWidth;
482         fScaleY      = (float)dwOutputRegionWidth  / (float)dwSourceRegionHeight;
483     }
484 
485     // Set RenderData flags
486     m_renderData.bScaling   = ((fScaleX == 1.0F) && (fScaleY == 1.0F)) ?
487                                  false : true;
488 
489     m_renderData.bColorFill = (pColorFillParams &&
490                                (!pColorFillParams->bDisableColorfillinSFC)   &&
491                                 pSrc->InterlacedScalingType == ISCALING_NONE &&
492                                 (pColorFillParams->bOnePixelBiasinSFC ?
493                                (!RECT1_CONTAINS_RECT2_ONEPIXELBIAS(pSrc->rcDst, pRenderTarget->rcDst)) :
494                                (!RECT1_CONTAINS_RECT2(pSrc->rcDst, pRenderTarget->rcDst)))) ?
495                                  true : false;
496 
497     m_renderData.bIEF       = (pSrc->pIEFParams              &&
498                                   pSrc->pIEFParams->bEnabled    &&
499                                   (pSrc->pIEFParams->fIEFFactor > 0.0f)) ?
500                                  true : false;
501 
502     // Determine if CSC is required in SFC pipe
503     DetermineCscParams(
504         pSrc,
505         pRenderTarget);
506 
507     // Determine SFC input surface format
508     DetermineInputFormat(
509         pSrc,
510         pRenderData);
511 
512     m_renderData.fScaleX            = fScaleX;
513     m_renderData.fScaleY            = fScaleY;
514     m_renderData.pColorFillParams   = m_renderData.bColorFill ? pColorFillParams : nullptr;
515     m_renderData.pAvsParams         = &m_AvsParameters;
516     m_renderData.pAlphaParams       = pAlphaParams;
517     m_renderData.pSfcPipeOutSurface = pRenderTarget;
518     m_renderData.SfcRotation        = pSrc->Rotation;
519     m_renderData.SfcScalingMode     = pSrc->ScalingMode;
520 
521     // In SFC, we have a lot of HW restrictions on Chroma Sitting Programming.
522     // So prevent any invalid input for SFC to avoid HW problems.
523     // Prevent invalid input for input surface and format.
524     m_renderData.SfcSrcChromaSiting = pSrc->ChromaSiting;
525     if (m_renderData.SfcSrcChromaSiting == MHW_CHROMA_SITING_NONE)
526     {
527         m_renderData.SfcSrcChromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
528     }
529     switch (VpHalDDIUtils::GetSurfaceColorPack(m_renderData.SfcInputFormat))
530     {
531         case VPHAL_COLORPACK_422:
532             m_renderData.SfcSrcChromaSiting = (m_renderData.SfcSrcChromaSiting & 0x7) | CHROMA_SITING_VERT_TOP;
533             break;
534         case VPHAL_COLORPACK_444:
535             m_renderData.SfcSrcChromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP;
536             break;
537         default:
538             break;
539     }
540     // Prevent invalid input for output surface and format
541     if (pRenderTarget->ChromaSiting == MHW_CHROMA_SITING_NONE)
542     {
543         pRenderTarget->ChromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
544     }
545     switch (dstColorPack)
546     {
547         case VPHAL_COLORPACK_422:
548             pRenderTarget->ChromaSiting = (pRenderTarget->ChromaSiting & 0x7) | CHROMA_SITING_VERT_TOP;
549             break;
550         case VPHAL_COLORPACK_444:
551             pRenderTarget->ChromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP;
552             break;
553         default:
554             break;
555     }
556 
557     m_renderData.bForcePolyPhaseCoefs = VpHal_IsChromaUpSamplingNeeded(pSrc, pRenderTarget);
558 
559     // Cache Render Target pointer
560     pRenderData->pRenderTarget = pRenderTarget;
561 
562 finish:
563     return;
564 }
565 
SetSfcMmcStatus(PVPHAL_VEBOX_RENDER_DATA renderData,PVPHAL_SURFACE outSurface,PMHW_SFC_STATE_PARAMS sfcStateParams)566 MOS_STATUS VphalSfcStateG12::SetSfcMmcStatus(
567     PVPHAL_VEBOX_RENDER_DATA renderData,
568     PVPHAL_SURFACE           outSurface,
569     PMHW_SFC_STATE_PARAMS    sfcStateParams)
570 {
571     MOS_STATUS       eStatus = MOS_STATUS_SUCCESS;
572 
573     VPHAL_RENDER_CHK_NULL_RETURN(outSurface);
574     VPHAL_RENDER_CHK_NULL_RETURN(sfcStateParams);
575 
576     if (outSurface->CompressionMode               &&
577         IsFormatMMCSupported(outSurface->Format)  &&
578         outSurface->TileType == MOS_TILE_Y        &&
579         IsSfcMmcEnabled())
580     {
581         sfcStateParams->bMMCEnable = true;
582         sfcStateParams->MMCMode    = outSurface->CompressionMode;
583 
584         if (outSurface->OsResource.bUncompressedWriteNeeded)
585         {
586             sfcStateParams->MMCMode = MOS_MMC_RC;
587         }
588     }
589     else
590     {
591         sfcStateParams->bMMCEnable = false;
592     }
593 
594     return eStatus;
595 }
596 
IsFormatMMCSupported(MOS_FORMAT Format)597 bool VphalSfcStateG12::IsFormatMMCSupported(MOS_FORMAT Format)
598 {
599     // Check if Sample Format is supported
600     if ((Format != Format_YUY2) &&
601         (Format != Format_Y210) &&
602         (Format != Format_Y410) &&
603         (Format != Format_Y216) &&
604         (Format != Format_Y416) &&
605         (Format != Format_P010) &&
606         (Format != Format_P016) &&
607         (Format != Format_AYUV) &&
608         (Format != Format_NV21) &&
609         (Format != Format_NV12) &&
610         (Format != Format_UYVY) &&
611         (Format != Format_YUYV) &&
612         (Format != Format_R10G10B10A2)   &&
613         (Format != Format_B10G10R10A2)   &&
614         (Format != Format_A8B8G8R8)      &&
615         (Format != Format_X8B8G8R8)      &&
616         (Format != Format_A8R8G8B8)      &&
617         (Format != Format_X8R8G8B8)      &&
618         (Format != Format_A16B16G16R16F) &&
619         (Format != Format_A16R16G16B16F))
620     {
621         VPHAL_RENDER_NORMALMESSAGE("Unsupported Format '0x%08x' for SFC MMC.", Format);
622         return false;
623     }
624 
625     return true;
626 }
627 
628 #endif // __VPHAL_SFC_SUPPORTED
629