1 /*
2 * Copyright (c) 2012-2021, 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_base.cpp
24 //! \brief VPHAL SFC 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 "vphal_render_vebox_base.h"
30 #include "vphal_render_ief.h"
31 #include "vphal_render_sfc_base.h"
32
33 #if __VPHAL_SFC_SUPPORTED
34
35 //!
36 //! \brief Constants used to derive Line Buffer sizes
37 //!
38 #define SFC_CACHELINE_SIZE_IN_BYTES (512 / 8)
39 #define SFC_AVS_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL (5 * SFC_CACHELINE_SIZE_IN_BYTES / 8)
40 #define SFC_IEF_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL (1 * SFC_CACHELINE_SIZE_IN_BYTES / 4)
41
42 //!
43 //! \brief Initialize SFC Output Surface Command parameters
44 //! \details Initialize MHW SFC Output Surface Command parameters from SFC Pipe output Surface
45 //! \param [in] pSfcPipeOutSurface
46 //! pointer to SFC Pipe output Surface
47 //! \param [out] pMhwOutSurfParams
48 //! pointer to SFC Output Surface Command parameters
49 //! \return MOS_STATUS
50 //!
VpHal_InitMhwOutSurfParams(PVPHAL_SURFACE pSfcPipeOutSurface,PMHW_SFC_OUT_SURFACE_PARAMS pMhwOutSurfParams)51 MOS_STATUS VpHal_InitMhwOutSurfParams(
52 PVPHAL_SURFACE pSfcPipeOutSurface,
53 PMHW_SFC_OUT_SURFACE_PARAMS pMhwOutSurfParams)
54 {
55 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
56
57 VPHAL_RENDER_CHK_NULL(pSfcPipeOutSurface);
58 VPHAL_RENDER_CHK_NULL(pMhwOutSurfParams);
59
60 MOS_ZeroMemory(pMhwOutSurfParams, sizeof(*pMhwOutSurfParams));
61
62 pMhwOutSurfParams->ChromaSiting = pSfcPipeOutSurface->ChromaSiting;
63 pMhwOutSurfParams->dwWidth = pSfcPipeOutSurface->dwWidth;
64 pMhwOutSurfParams->dwHeight = pSfcPipeOutSurface->dwHeight;
65 pMhwOutSurfParams->dwPitch = pSfcPipeOutSurface->dwPitch;
66 pMhwOutSurfParams->TileType = pSfcPipeOutSurface->TileType;
67 pMhwOutSurfParams->TileModeGMM = pSfcPipeOutSurface->TileModeGMM;
68 pMhwOutSurfParams->bGMMTileEnabled = pSfcPipeOutSurface->bGMMTileEnabled;
69 pMhwOutSurfParams->pOsResource = &(pSfcPipeOutSurface->OsResource);
70 pMhwOutSurfParams->Format = pSfcPipeOutSurface->Format;
71 pMhwOutSurfParams->bCompressible = pSfcPipeOutSurface->bCompressible;
72 pMhwOutSurfParams->dwCompressionFormat = pSfcPipeOutSurface->CompressionFormat;
73 pMhwOutSurfParams->dwSurfaceXOffset = pSfcPipeOutSurface->YPlaneOffset.iXOffset;
74 pMhwOutSurfParams->dwSurfaceYOffset = pSfcPipeOutSurface->YPlaneOffset.iYOffset;
75
76 if (pSfcPipeOutSurface->dwPitch > 0)
77 {
78 pMhwOutSurfParams->dwUYoffset = ((pSfcPipeOutSurface->UPlaneOffset.iSurfaceOffset - pSfcPipeOutSurface->YPlaneOffset.iSurfaceOffset) / pSfcPipeOutSurface->dwPitch) + pSfcPipeOutSurface->UPlaneOffset.iYOffset;
79 }
80
81 finish:
82 return eStatus;
83 }
84
85 //!
86 //! \brief Get SFC Rotation mode parameter
87 //! \details Get MHW SFC Rotation mode parameter
88 //! \param [in] Rotation
89 //! VPHAL roration mode parameter
90 //! \return MHW_ROTATION
91 //!
VpHal_GetMhwRotationParam(VPHAL_ROTATION Rotation)92 MHW_ROTATION VpHal_GetMhwRotationParam(VPHAL_ROTATION Rotation)
93 {
94 switch (Rotation)
95 {
96 case VPHAL_ROTATION_90:
97 return MHW_ROTATION_90; // 90 Degree Rotation
98
99 case VPHAL_ROTATION_180:
100 return MHW_ROTATION_180; // 180 Degree Rotation
101
102 case VPHAL_ROTATION_270:
103 return MHW_ROTATION_270; // 270 Degree Rotation
104
105 case VPHAL_MIRROR_HORIZONTAL:
106 return MHW_MIRROR_HORIZONTAL; // Horizontal Mirror
107
108 case VPHAL_MIRROR_VERTICAL:
109 return MHW_MIRROR_VERTICAL; // Vertical Mirror
110
111 case VPHAL_ROTATE_90_MIRROR_VERTICAL:
112 return MHW_ROTATION_270; // 270 Degree rotation and Horizontal Mirror
113
114 case VPHAL_ROTATE_90_MIRROR_HORIZONTAL:
115 return MHW_ROTATION_90; // 90 Degree rotation and Horizontal Mirror
116
117 default:
118 case VPHAL_ROTATION_IDENTITY:
119 return MHW_ROTATION_IDENTITY;
120 }
121 }
122
123 //!
124 //! \brief Get SFC Scaling mode parameter
125 //! \details Get MHW SFC Scaling mode parameter
126 //! \param [in] Scaling mode
127 //! VPHAL Scaling mode parameter
128 //! \return MHW_SCALING_MODE
129 //!
VpHal_GetMhwScalingModeParam(VPHAL_SCALING_MODE ScalingMode)130 MHW_SCALING_MODE VpHal_GetMhwScalingModeParam(VPHAL_SCALING_MODE ScalingMode)
131 {
132 switch (ScalingMode)
133 {
134 case VPHAL_SCALING_NEAREST:
135 return MHW_SCALING_NEAREST; // Nearest interpolation
136
137 case VPHAL_SCALING_BILINEAR:
138 return MHW_SCALING_BILINEAR; // Bilinear interpolation
139
140 case VPHAL_SCALING_AVS:
141 case VPHAL_SCALING_ADV_QUALITY:
142 default:
143 return MHW_SCALING_AVS;
144 }
145 }
146
IsFormatMMCSupported(MOS_FORMAT Format)147 bool VphalSfcState::IsFormatMMCSupported(
148 MOS_FORMAT Format)
149 {
150 // Check if Sample Format is supported
151 if ((Format != Format_NV12) &&
152 (Format != Format_UYVY) &&
153 (Format != Format_YUYV))
154 {
155 VPHAL_RENDER_NORMALMESSAGE("Unsupported Format '0x%08x' for SFC MMC.", Format);
156 return false;
157 }
158
159 return true;
160 }
161
VphalSfcState(PMOS_INTERFACE osInterface,PRENDERHAL_INTERFACE renderHal,PMHW_SFC_INTERFACE sfcInterface)162 VphalSfcState::VphalSfcState(
163 PMOS_INTERFACE osInterface,
164 PRENDERHAL_INTERFACE renderHal,
165 PMHW_SFC_INTERFACE sfcInterface)
166 {
167 VPHAL_RENDER_ASSERT(osInterface);
168 VPHAL_RENDER_ASSERT(renderHal);
169 VPHAL_RENDER_ASSERT(sfcInterface);
170
171 m_renderHal = renderHal;
172 m_sfcInterface = sfcInterface;
173 m_osInterface = osInterface;
174
175 // Allocate AVS state
176 VpHal_RndrCommonInitAVSParams(
177 &m_AvsParameters,
178 POLYPHASE_Y_COEFFICIENT_TABLE_SIZE_G9,
179 POLYPHASE_UV_COEFFICIENT_TABLE_SIZE_G9);
180 }
181
~VphalSfcState()182 VphalSfcState::~VphalSfcState()
183 {
184 VpHal_RndrCommonDestroyAVSParams(&m_AvsParameters);
185 MOS_FreeMemAndSetNull(m_renderData.SfcStateParams);
186 }
187
IsOutputCapable(bool isColorFill,PVPHAL_SURFACE src,PVPHAL_SURFACE renderTarget)188 bool VphalSfcState::IsOutputCapable(
189 bool isColorFill,
190 PVPHAL_SURFACE src,
191 PVPHAL_SURFACE renderTarget)
192 {
193 bool isOutputCapable = false;
194
195 VPHAL_RENDER_NORMALMESSAGE(
196 "isColorFill %d, \
197 src->rcDst.top %d, \
198 src->rcDst.left %d, \
199 renderTarget->TileType %d, \
200 renderTarget->Format %d",
201 isColorFill,
202 src->rcDst.top,
203 src->rcDst.left,
204 renderTarget->TileType,
205 renderTarget->Format);
206
207 // H/W does not support ColorFill, the (OffsetX, OffsetY)
208 // of scaled region not being (0, 0) or the tile type not being
209 // Tile_Y on NV12/P010/P016 output surface. Disable SFC even if other
210 // features are supported.
211 if ((isColorFill ||
212 src->rcDst.top != 0 ||
213 src->rcDst.left != 0 ||
214 renderTarget->TileType != MOS_TILE_Y) &&
215 (renderTarget->Format == Format_NV12 ||
216 renderTarget->Format == Format_P010 ||
217 renderTarget->Format == Format_P016))
218 {
219 isOutputCapable = false;
220 }
221 else
222 {
223 isOutputCapable = true;
224 }
225
226 return isOutputCapable;
227 }
228
AdjustBoundary(PVPHAL_SURFACE pSurface,uint32_t * pdwSurfaceWidth,uint32_t * pdwSurfaceHeight)229 void VphalSfcState::AdjustBoundary(
230 PVPHAL_SURFACE pSurface,
231 uint32_t* pdwSurfaceWidth,
232 uint32_t* pdwSurfaceHeight)
233 {
234 uint32_t dwVeboxHeight;
235 uint32_t dwVeboxWidth;
236 uint32_t dwVeboxBottom;
237 uint32_t dwVeboxRight;
238 MEDIA_WA_TABLE *pWaTable = nullptr;
239
240 VPHAL_RENDER_CHK_NULL_NO_STATUS(m_sfcInterface);
241 VPHAL_RENDER_CHK_NULL_NO_STATUS(m_osInterface);
242 VPHAL_RENDER_CHK_NULL_NO_STATUS(pSurface);
243 VPHAL_RENDER_CHK_NULL_NO_STATUS(pdwSurfaceWidth);
244 VPHAL_RENDER_CHK_NULL_NO_STATUS(pdwSurfaceHeight);
245
246 pWaTable = m_osInterface->pfnGetWaTable(m_osInterface);
247 VPHAL_RENDER_CHK_NULL_NO_STATUS(pWaTable);
248
249 if (MEDIA_IS_WA(pWaTable, WaVeboxInputHeight16Aligned) &&
250 (pSurface->Format == Format_NV12 ||
251 pSurface->Format == Format_P010 ||
252 pSurface->Format == Format_P016))
253 {
254 m_sfcInterface->m_veHeightAlignment = 16;
255 }
256 else
257 {
258 m_sfcInterface->m_veHeightAlignment = MHW_SFC_VE_HEIGHT_ALIGN;
259 }
260
261 // For the VEBOX output to SFC, the width is multiple of 16 and height
262 // is multiple of 4
263 dwVeboxHeight = pSurface->dwHeight;
264 dwVeboxWidth = pSurface->dwWidth;
265 dwVeboxBottom = (uint32_t)pSurface->rcMaxSrc.bottom;
266 dwVeboxRight = (uint32_t)pSurface->rcMaxSrc.right;
267
268 if(pSurface->bDirectionalScalar)
269 {
270 dwVeboxHeight *= 2;
271 dwVeboxWidth *= 2;
272 dwVeboxBottom *= 2;
273 dwVeboxRight *= 2;
274 }
275
276 *pdwSurfaceHeight = MOS_ALIGN_CEIL(
277 MOS_MIN(dwVeboxHeight, MOS_MAX(dwVeboxBottom, MHW_VEBOX_MIN_HEIGHT)),
278 m_sfcInterface->m_veHeightAlignment);
279 *pdwSurfaceWidth = MOS_ALIGN_CEIL(
280 MOS_MIN(dwVeboxWidth, MOS_MAX(dwVeboxRight, MHW_VEBOX_MIN_WIDTH)),
281 m_sfcInterface->m_veWidthAlignment);
282
283 finish:
284 return;
285 }
286
IsOutputPipeSfcFeasible(PCVPHAL_RENDER_PARAMS pcRenderParams,PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pRenderTarget)287 bool VphalSfcState::IsOutputPipeSfcFeasible(
288 PCVPHAL_RENDER_PARAMS pcRenderParams,
289 PVPHAL_SURFACE pSrcSurface,
290 PVPHAL_SURFACE pRenderTarget)
291 {
292 VPHAL_RENDER_NORMALMESSAGE(
293 "IsDisabled %d, \
294 uDstCount %d, \
295 Rotation %d, \
296 pTarget[0]->TileType %d, \
297 IsFormatSupported %d, \
298 InputFormat %d, \
299 OutputFormat %d, \
300 pCompAlpha %p, \
301 pDeinterlaceParams %p, \
302 bQueryVariance %d",
303 IsDisabled(),
304 pcRenderParams->uDstCount,
305 pSrcSurface->Rotation,
306 pcRenderParams->pTarget[0]->TileType,
307 IsFormatSupported(pSrcSurface, pcRenderParams->pTarget[0], pcRenderParams->pCompAlpha),
308 pSrcSurface->Format,
309 pcRenderParams->pTarget[0]->Format,
310 pcRenderParams->pCompAlpha,
311 pSrcSurface->pDeinterlaceParams,
312 pSrcSurface->bQueryVariance);
313
314 //!
315 //! \brief SFC can be the output pipe when the following conditions are all met
316 //! 1. User feature keys value "SFC Disable" is false
317 //! 2. Single render target only
318 //! 3. Rotation disabled or ONLY Rotation enabled when the SFC output is Y-tile
319 //! 4. i/o format is supported by SFC, taking into account the alpha fill info
320 //! 5. Comp DI(ARGB/ABGR) is disabled
321 //! 6. Variance Query is disabled
322 //!
323 if (IsDisabled() == false &&
324 pcRenderParams->uDstCount == 1 &&
325 (pSrcSurface->Rotation == VPHAL_ROTATION_IDENTITY ||
326 (pSrcSurface->Rotation <= VPHAL_ROTATION_270 &&
327 pcRenderParams->pTarget[0]->TileType == MOS_TILE_Y)) &&
328 IsFormatSupported(pSrcSurface, pcRenderParams->pTarget[0], pcRenderParams->pCompAlpha) &&
329 (pSrcSurface->pDeinterlaceParams == nullptr ||
330 (pSrcSurface->Format != Format_A8R8G8B8 && pSrcSurface->Format != Format_A8B8G8R8)) &&
331 pSrcSurface->bQueryVariance == false)
332 {
333 // For platforms with VEBOX disabled but procamp enabled, go Render path
334 if (MEDIA_IS_SKU(m_renderHal->pSkuTable, FtrDisableVEBoxFeatures) && pSrcSurface->pProcampParams != nullptr)
335 {
336 return false;
337 }
338
339 return true;
340 }
341
342 return false;
343 }
344
GetOutputPipe(PVPHAL_SURFACE pSrc,PVPHAL_SURFACE pRenderTarget,PCVPHAL_RENDER_PARAMS pcRenderParams)345 VPHAL_OUTPUT_PIPE_MODE VphalSfcState::GetOutputPipe(
346 PVPHAL_SURFACE pSrc,
347 PVPHAL_SURFACE pRenderTarget,
348 PCVPHAL_RENDER_PARAMS pcRenderParams)
349 {
350 float fScaleX;
351 float fScaleY;
352 uint32_t dwSurfaceWidth;
353 uint32_t dwSurfaceHeight;
354 VPHAL_OUTPUT_PIPE_MODE OutputPipe;
355 bool bColorFill;
356 uint16_t wWidthAlignUnit;
357 uint16_t wHeightAlignUnit;
358 uint32_t dwSourceRegionWidth;
359 uint32_t dwSourceRegionHeight;
360 uint32_t dwOutputRegionWidth;
361 uint32_t dwOutputRegionHeight;
362 uint32_t dwSfcMaxWidth;
363 uint32_t dwSfcMaxHeight;
364 uint32_t dwSfcMinWidth;
365 uint32_t dwSfcMinHeight;
366
367 OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP;
368
369 VPHAL_RENDER_CHK_NULL_NO_STATUS(m_sfcInterface);
370 VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrc);
371 VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderTarget);
372 VPHAL_RENDER_CHK_NULL_NO_STATUS(pcRenderParams);
373
374 dwSfcMaxWidth = m_sfcInterface->m_maxWidth;
375 dwSfcMaxHeight = m_sfcInterface->m_maxHeight;
376 dwSfcMinWidth = m_sfcInterface->m_minWidth;
377 dwSfcMinHeight = m_sfcInterface->m_minHeight;
378 wWidthAlignUnit = 1;
379 wHeightAlignUnit = 1;
380
381 // Check if the feature can be supported by SFC output pipe
382 if (!IsOutputPipeSfcFeasible(pcRenderParams, pSrc, pRenderTarget))
383 {
384 VPHAL_RENDER_NORMALMESSAGE("Feature or surface format not supported by SFC Pipe.");
385 OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP;
386 return OutputPipe;
387 }
388
389 // Get the SFC input surface size from Vebox
390 AdjustBoundary(
391 pSrc,
392 &dwSurfaceWidth,
393 &dwSurfaceHeight);
394
395 // Apply alignment restriction to the source and scaled regions.
396 switch(pRenderTarget->Format)
397 {
398 case Format_NV12:
399 wWidthAlignUnit = 2;
400 wHeightAlignUnit = 2;
401 break;
402 case Format_YUY2:
403 case Format_UYVY:
404 wWidthAlignUnit = 2;
405 break;
406 default:
407 break;
408 }
409
410 // Region of the input frame which needs to be processed by SFC
411 dwSourceRegionHeight = MOS_ALIGN_FLOOR(
412 MOS_MIN((uint32_t)(pSrc->rcSrc.bottom - pSrc->rcSrc.top), dwSurfaceHeight),
413 wHeightAlignUnit);
414 dwSourceRegionWidth = MOS_ALIGN_FLOOR(
415 MOS_MIN((uint32_t)(pSrc->rcSrc.right - pSrc->rcSrc.left), dwSurfaceWidth),
416 wWidthAlignUnit);
417
418 // Size of the Output Region over the Render Target
419 dwOutputRegionHeight = MOS_ALIGN_CEIL(
420 (uint32_t)(pSrc->rcDst.bottom - pSrc->rcDst.top),
421 wHeightAlignUnit);
422 dwOutputRegionWidth = MOS_ALIGN_CEIL(
423 (uint32_t)(pSrc->rcDst.right - pSrc->rcDst.left),
424 wWidthAlignUnit);
425
426 // SFC i/o width and height should fall into the range of [128, 4K]
427 if (OUT_OF_BOUNDS(dwSurfaceWidth, dwSfcMinWidth, dwSfcMaxWidth) ||
428 OUT_OF_BOUNDS(dwSurfaceHeight, dwSfcMinHeight, dwSfcMaxHeight) ||
429 OUT_OF_BOUNDS(dwSourceRegionWidth, dwSfcMinWidth, dwSfcMaxWidth) ||
430 OUT_OF_BOUNDS(dwSourceRegionHeight, dwSfcMinHeight, dwSfcMaxHeight) ||
431 OUT_OF_BOUNDS(dwOutputRegionWidth, dwSfcMinWidth, dwSfcMaxWidth) ||
432 OUT_OF_BOUNDS(dwOutputRegionHeight, dwSfcMinHeight, dwSfcMaxHeight) ||
433 OUT_OF_BOUNDS(pRenderTarget->dwWidth, dwSfcMinWidth, dwSfcMaxWidth) ||
434 OUT_OF_BOUNDS(pRenderTarget->dwHeight, dwSfcMinHeight, dwSfcMaxHeight))
435 {
436 VPHAL_RENDER_NORMALMESSAGE("Surface dimensions not supported by SFC Pipe.");
437 OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP;
438 return OutputPipe;
439 }
440
441 // Size of the Output Region over the Render Target
442 dwOutputRegionHeight = MOS_MIN(dwOutputRegionHeight, pRenderTarget->dwHeight);
443 dwOutputRegionWidth = MOS_MIN(dwOutputRegionWidth, pRenderTarget->dwWidth);
444
445 // Calculate the scaling ratio
446 // Both source region and scaled region are pre-rotated
447 if (pSrc->Rotation == VPHAL_ROTATION_IDENTITY ||
448 pSrc->Rotation == VPHAL_ROTATION_180 ||
449 pSrc->Rotation == VPHAL_MIRROR_HORIZONTAL ||
450 pSrc->Rotation == VPHAL_MIRROR_VERTICAL)
451 {
452 fScaleX = (float)dwOutputRegionWidth / (float)dwSourceRegionWidth;
453 fScaleY = (float)dwOutputRegionHeight / (float)dwSourceRegionHeight;
454 }
455 else
456 {
457 // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 || VPHAL_ROTATE_90_MIRROR_VERTICAL || VPHAL_ROTATE_90_MIRROR_HORIZONTAL
458 fScaleX = (float)dwOutputRegionHeight / (float)dwSourceRegionWidth;
459 fScaleY = (float)dwOutputRegionWidth / (float)dwSourceRegionHeight;
460 }
461
462 // SFC scaling range is [0.125, 8] for both X and Y direction.
463 if ((fScaleX < 0.125F) || (fScaleX > 8.0F) ||
464 (fScaleY < 0.125F) || (fScaleY > 8.0F))
465 {
466 VPHAL_RENDER_NORMALMESSAGE("Scaling factor not supported by SFC Pipe.");
467 OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP;
468 return OutputPipe;
469 }
470
471 if (MEDIA_IS_WA(m_renderHal->pWaTable, WaDisableSFCSrcCrop) &&
472 dwSurfaceHeight > 1120 &&
473 (((pSrc->rcSrc.left > 0) || (dwSurfaceWidth - pSrc->rcSrc.right > 0)) ||
474 ((pSrc->rcSrc.bottom > 1120) && (pSrc->rcSrc.bottom < (int32_t)dwSurfaceHeight)) ||
475 ((pSrc->rcSrc.top > 1120) && (pSrc->rcSrc.top < (int32_t)dwSurfaceHeight)) ||
476 (pSrc->rcSrc.bottom < (int32_t)dwSurfaceHeight)))
477 {
478 VPHAL_RENDER_NORMALMESSAGE("Fallback to comp path as SW WA for SFC Cropping TDR.");
479 OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP;
480 return OutputPipe;
481 }
482
483 // if ScalingPreference == Composition, switch to use composition path
484 // This flag can be set by app.
485 if (pSrc->ScalingPreference == VPHAL_SCALING_PREFER_COMP)
486 {
487 VPHAL_RENDER_NORMALMESSAGE("DDI set ScalingPreference to Composition to use render for scaling.");
488 OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP;
489 return OutputPipe;
490 }
491
492 bColorFill = (pcRenderParams->pColorFillParams &&
493 (!pcRenderParams->pColorFillParams->bDisableColorfillinSFC) &&
494 (pcRenderParams->pColorFillParams->bOnePixelBiasinSFC ?
495 (!RECT1_CONTAINS_RECT2_ONEPIXELBIAS(pSrc->rcDst, pRenderTarget->rcDst)) :
496 (!RECT1_CONTAINS_RECT2(pSrc->rcDst, pRenderTarget->rcDst)))) ?
497 true : false;
498
499 if (IsOutputCapable(bColorFill, pSrc, pRenderTarget))
500 {
501 OutputPipe = VPHAL_OUTPUT_PIPE_MODE_SFC;
502 }
503 else
504 {
505 OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP;
506 }
507
508 finish:
509 return OutputPipe;
510 }
511
DetermineCscParams(PVPHAL_SURFACE src,PVPHAL_SURFACE renderTarget)512 void VphalSfcState::DetermineCscParams(
513 PVPHAL_SURFACE src,
514 PVPHAL_SURFACE renderTarget)
515 {
516 // Determine if CSC is required in SFC pipe
517 if (IS_RGB_CSPACE(src->ColorSpace))
518 {
519 if (IS_YUV_CSPACE(renderTarget->ColorSpace))
520 {
521 m_renderData.SfcInputCspace = renderTarget->ColorSpace;
522 }
523 else if (MEDIA_IS_HDCONTENT(src->dwWidth, src->dwHeight))
524 {
525 m_renderData.SfcInputCspace = CSpace_BT709;
526 }
527 else
528 {
529 m_renderData.SfcInputCspace = CSpace_BT601;
530 }
531 }
532 else
533 {
534 m_renderData.SfcInputCspace = src->ColorSpace;
535 }
536
537 if (m_renderData.SfcInputCspace != renderTarget->ColorSpace)
538 {
539 m_renderData.bCSC = true;
540 }
541 }
542
DetermineInputFormat(PVPHAL_SURFACE src,PVPHAL_VEBOX_RENDER_DATA veboxRenderData)543 void VphalSfcState::DetermineInputFormat(
544 PVPHAL_SURFACE src,
545 PVPHAL_VEBOX_RENDER_DATA veboxRenderData)
546 {
547 // Determine SFC input surface format
548 if (IS_RGB_FORMAT(src->Format))
549 {
550 m_renderData.SfcInputFormat = Format_AYUV;
551 }
552 else if (veboxRenderData->bDeinterlace)
553 {
554 m_renderData.SfcInputFormat = Format_YUY2;
555 }
556 else
557 {
558 m_renderData.SfcInputFormat = src->Format;
559 }
560 }
561
SetRenderingFlags(PVPHAL_COLORFILL_PARAMS pColorFillParams,PVPHAL_ALPHA_PARAMS pAlphaParams,PVPHAL_SURFACE pSrc,PVPHAL_SURFACE pRenderTarget,PVPHAL_VEBOX_RENDER_DATA pRenderData)562 void VphalSfcState::SetRenderingFlags(
563 PVPHAL_COLORFILL_PARAMS pColorFillParams,
564 PVPHAL_ALPHA_PARAMS pAlphaParams,
565 PVPHAL_SURFACE pSrc,
566 PVPHAL_SURFACE pRenderTarget,
567 PVPHAL_VEBOX_RENDER_DATA pRenderData)
568 {
569 PRENDERHAL_INTERFACE pRenderHal;
570 float fScaleX;
571 float fScaleY;
572 uint32_t dwSurfaceWidth;
573 uint32_t dwSurfaceHeight;
574 uint16_t wWidthAlignUnit;
575 uint16_t wHeightAlignUnit;
576 uint32_t dwSourceRegionWidth;
577 uint32_t dwSourceRegionHeight;
578 uint32_t dwOutputRegionWidth;
579 uint32_t dwOutputRegionHeight;
580 uint32_t dwVeboxBottom;
581 uint32_t dwVeboxRight;
582 VPHAL_COLORPACK dstColorPack;
583
584 VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrc);
585 VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderTarget);
586
587 pRenderHal = m_renderHal;
588 wWidthAlignUnit = 1;
589 wHeightAlignUnit = 1;
590 dwVeboxBottom = (uint32_t)pSrc->rcSrc.bottom;
591 dwVeboxRight = (uint32_t)pSrc->rcSrc.right;
592 dstColorPack = VpHal_GetSurfaceColorPack(pRenderTarget->Format);
593
594 // Get the SFC input surface size from Vebox
595 AdjustBoundary(
596 pSrc,
597 &dwSurfaceWidth,
598 &dwSurfaceHeight);
599
600 // Apply alignment restriction to the source and scaled regions.
601 switch (dstColorPack)
602 {
603 case VPHAL_COLORPACK_420:
604 wWidthAlignUnit = 2;
605 wHeightAlignUnit = 2;
606 break;
607 case VPHAL_COLORPACK_422:
608 wWidthAlignUnit = 2;
609 break;
610 default:
611 break;
612 }
613
614 if(pSrc->bDirectionalScalar)
615 {
616 dwVeboxBottom *= 2;
617 dwVeboxRight *= 2;
618 }
619
620 // Region of the input frame which needs to be processed by SFC
621 dwSourceRegionHeight = MOS_ALIGN_FLOOR(
622 MOS_MIN((uint32_t)(dwVeboxBottom - pSrc->rcSrc.top), dwSurfaceHeight),
623 wHeightAlignUnit);
624 dwSourceRegionWidth = MOS_ALIGN_FLOOR(
625 MOS_MIN((uint32_t)(dwVeboxRight - pSrc->rcSrc.left), dwSurfaceWidth),
626 wWidthAlignUnit);
627
628 // Size of the Output Region over the Render Target
629 dwOutputRegionHeight = MOS_ALIGN_CEIL(
630 MOS_MIN((uint32_t)(pSrc->rcDst.bottom - pSrc->rcDst.top), pRenderTarget->dwHeight),
631 wHeightAlignUnit);
632 dwOutputRegionWidth = MOS_ALIGN_CEIL(
633 MOS_MIN((uint32_t)(pSrc->rcDst.right - pSrc->rcDst.left), pRenderTarget->dwWidth),
634 wWidthAlignUnit);
635
636 // Calculate the scaling ratio
637 // Both source region and scaled region are pre-rotated
638 if (pSrc->Rotation == VPHAL_ROTATION_IDENTITY ||
639 pSrc->Rotation == VPHAL_ROTATION_180 ||
640 pSrc->Rotation == VPHAL_MIRROR_HORIZONTAL ||
641 pSrc->Rotation == VPHAL_MIRROR_VERTICAL)
642 {
643 fScaleX = (float)dwOutputRegionWidth / (float)dwSourceRegionWidth;
644 fScaleY = (float)dwOutputRegionHeight / (float)dwSourceRegionHeight;
645 }
646 else
647 {
648 // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 || VPHAL_ROTATE_90_MIRROR_VERTICAL || VPHAL_ROTATE_90_MIRROR_HORIZONTAL
649 fScaleX = (float)dwOutputRegionHeight / (float)dwSourceRegionWidth;
650 fScaleY = (float)dwOutputRegionWidth / (float)dwSourceRegionHeight;
651 }
652
653 // Set RenderData flags
654 m_renderData.bScaling = ((fScaleX == 1.0F) && (fScaleY == 1.0F)) ?
655 false : true;
656
657 m_renderData.bColorFill = (pColorFillParams &&
658 (!pColorFillParams->bDisableColorfillinSFC) &&
659 pSrc->InterlacedScalingType == ISCALING_NONE &&
660 (pColorFillParams->bOnePixelBiasinSFC ?
661 (!RECT1_CONTAINS_RECT2_ONEPIXELBIAS(pSrc->rcDst, pRenderTarget->rcDst)) :
662 (!RECT1_CONTAINS_RECT2(pSrc->rcDst, pRenderTarget->rcDst)))) ?
663 true : false;
664
665 m_renderData.bIEF = (pSrc->pIEFParams &&
666 pSrc->pIEFParams->bEnabled &&
667 (pSrc->pIEFParams->fIEFFactor > 0.0f)) ?
668 true : false;
669
670 // Determine if CSC is required in SFC pipe
671 DetermineCscParams(
672 pSrc,
673 pRenderTarget);
674
675 // Determine SFC input surface format
676 DetermineInputFormat(
677 pSrc,
678 pRenderData);
679
680 m_renderData.fScaleX = fScaleX;
681 m_renderData.fScaleY = fScaleY;
682 m_renderData.pColorFillParams = m_renderData.bColorFill ? pColorFillParams : nullptr;
683 m_renderData.pAvsParams = &m_AvsParameters;
684 m_renderData.pAlphaParams = pAlphaParams;
685 m_renderData.pSfcPipeOutSurface = pRenderTarget;
686 m_renderData.SfcRotation = pSrc->Rotation;
687 m_renderData.SfcScalingMode = pSrc->ScalingMode;
688
689 // In SFC, we have a lot of HW restrictions on Chroma Sitting Programming.
690 // So prevent any invalid input for SFC to avoid HW problems.
691 // Prevent invalid input for input surface and format.
692 m_renderData.SfcSrcChromaSiting = pSrc->ChromaSiting;
693 if (m_renderData.SfcSrcChromaSiting == MHW_CHROMA_SITING_NONE)
694 {
695 m_renderData.SfcSrcChromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
696 }
697 switch (VpHal_GetSurfaceColorPack(m_renderData.SfcInputFormat))
698 {
699 case VPHAL_COLORPACK_422:
700 m_renderData.SfcSrcChromaSiting = (m_renderData.SfcSrcChromaSiting & 0x7) | CHROMA_SITING_VERT_TOP;
701 break;
702 case VPHAL_COLORPACK_444:
703 m_renderData.SfcSrcChromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP;
704 break;
705 default:
706 break;
707 }
708 // Prevent invalid input for output surface and format
709 if (pRenderTarget->ChromaSiting == MHW_CHROMA_SITING_NONE)
710 {
711 pRenderTarget->ChromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
712 }
713 switch (dstColorPack)
714 {
715 case VPHAL_COLORPACK_422:
716 pRenderTarget->ChromaSiting = (pRenderTarget->ChromaSiting & 0x7) | CHROMA_SITING_VERT_TOP;
717 break;
718 case VPHAL_COLORPACK_444:
719 pRenderTarget->ChromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP;
720 break;
721 default:
722 break;
723 }
724
725 m_renderData.bForcePolyPhaseCoefs = VpHal_IsChromaUpSamplingNeeded(pSrc, pRenderTarget);
726
727 // Cache Render Target pointer
728 pRenderData->pRenderTarget = pRenderTarget;
729
730 VPHAL_RENDER_NORMALMESSAGE(
731 "RenderData: bScaling %d, bColorFill %d, bIEF %d, SfcInputFormat %d, SfcRotation %d, SfcScalingMode %d, SfcSrcChromaSiting %d",
732 m_renderData.bScaling,
733 m_renderData.bColorFill,
734 m_renderData.bIEF,
735 m_renderData.SfcInputFormat,
736 m_renderData.SfcRotation,
737 m_renderData.SfcScalingMode,
738 m_renderData.SfcSrcChromaSiting);
739
740 finish:
741 return;
742 }
743
IsFormatSupported(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutSurface,PVPHAL_ALPHA_PARAMS pAlphaParams)744 bool VphalSfcState::IsFormatSupported(
745 PVPHAL_SURFACE pSrcSurface,
746 PVPHAL_SURFACE pOutSurface,
747 PVPHAL_ALPHA_PARAMS pAlphaParams)
748 {
749 // Init to false for in case the input parameters are nullptr
750 bool ret = false;
751
752 VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrcSurface);
753 VPHAL_RENDER_CHK_NULL_NO_STATUS(pOutSurface);
754
755 // Default to true
756 ret = true;
757
758 // Check if Input Format is supported
759 if (!IsInputFormatSupported(pSrcSurface))
760 {
761 VPHAL_RENDER_NORMALMESSAGE("Unsupported Source Format '0x%08x' for SFC.", pSrcSurface->Format);
762 ret = false;
763 return ret;
764 }
765
766 // SFC can not support fp16 output. HDR path is the only way to handle any fp16 output.
767 // Before entering into HDR path, it is possible that we need to use SFC to do P010->ARGB10.
768 // As for SFC is needed or not, we use bHDRSfc to decide.
769 if (pOutSurface->Format == Format_A16R16G16B16F ||
770 pOutSurface->Format == Format_A16B16G16R16F)
771 {
772 ret = false;
773 return ret;
774 }
775
776 // Check if Output Format is supported
777 if (!IsOutputFormatSupported(pOutSurface))
778 {
779 ret = false;
780 return ret;
781 }
782
783 // Check if the input/output combination is supported, given certain alpha fill mode.
784 // So far SFC only supports filling constant alpha.
785 if (pAlphaParams &&
786 pAlphaParams->AlphaMode == VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM)
787 {
788 if ((pOutSurface->Format == Format_A8R8G8B8 ||
789 pOutSurface->Format == Format_A8B8G8R8 ||
790 pOutSurface->Format == Format_R10G10B10A2 ||
791 pOutSurface->Format == Format_B10G10R10A2 ||
792 pOutSurface->Format == Format_Y410 ||
793 pOutSurface->Format == Format_Y416 ||
794 pOutSurface->Format == Format_AYUV) &&
795 (pSrcSurface->Format == Format_A8B8G8R8 ||
796 pSrcSurface->Format == Format_A8R8G8B8 ||
797 pSrcSurface->Format == Format_Y410 ||
798 pSrcSurface->Format == Format_Y416 ||
799 pSrcSurface->Format == Format_AYUV))
800 {
801 ret = false;
802 }
803 }
804
805 finish:
806 return ret;
807 }
808
FreeResources()809 void VphalSfcState::FreeResources()
810 {
811 // Free AVS Line Buffer surface for SFC
812 m_osInterface->pfnFreeResource(
813 m_osInterface,
814 &m_AVSLineBufferSurface.OsResource);
815
816 // Free IEF Line Buffer surface for SFC
817 m_osInterface->pfnFreeResource(
818 m_osInterface,
819 &m_IEFLineBufferSurface.OsResource);
820
821 // Free SFD Line Buffer surface for SFC
822 m_osInterface->pfnFreeResource(
823 m_osInterface,
824 &m_SFDLineBufferSurface.OsResource);
825
826 return;
827 }
828
AllocateResources()829 MOS_STATUS VphalSfcState::AllocateResources()
830 {
831 MOS_STATUS eStatus;
832 uint32_t dwWidth;
833 uint32_t dwHeight;
834 uint32_t dwSize;
835 bool bAllocated;
836 PMHW_SFC_STATE_PARAMS pSfcStateParams;
837 Mos_MemPool memTypeSurfVideoMem = MOS_MEMPOOL_VIDEOMEMORY;
838
839 eStatus = MOS_STATUS_UNKNOWN;
840 bAllocated = false;
841 pSfcStateParams = m_renderData.SfcStateParams;
842
843 VPHAL_RENDER_CHK_NULL(pSfcStateParams);
844 VPHAL_RENDER_CHK_NULL(m_renderHal);
845 VPHAL_RENDER_CHK_NULL(m_renderHal->pSkuTable);
846
847 if (MEDIA_IS_SKU(m_renderHal->pSkuTable, FtrLimitedLMemBar))
848 {
849 memTypeSurfVideoMem = MOS_MEMPOOL_DEVICEMEMORY;
850 }
851
852 // Allocate AVS Line Buffer surface----------------------------------------------
853 dwWidth = 1;
854 dwHeight = pSfcStateParams->dwInputFrameHeight * SFC_AVS_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL;
855 dwSize = dwWidth * dwHeight;
856
857 VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface(
858 m_osInterface,
859 &m_AVSLineBufferSurface,
860 "SfcAVSLineBufferSurface",
861 Format_Buffer,
862 MOS_GFXRES_BUFFER,
863 MOS_TILE_LINEAR,
864 dwSize,
865 1,
866 false,
867 MOS_MMC_DISABLED,
868 &bAllocated,
869 MOS_HW_RESOURCE_DEF_MAX,
870 MOS_TILE_UNSET_GMM,
871 memTypeSurfVideoMem,
872 MOS_MEMPOOL_DEVICEMEMORY == memTypeSurfVideoMem));
873
874 // Allocate IEF Line Buffer surface----------------------------------------------
875 dwWidth = 1;
876 dwHeight = pSfcStateParams->dwScaledRegionHeight * SFC_IEF_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL;
877 dwSize = dwWidth * dwHeight;
878
879 VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface(
880 m_osInterface,
881 &m_IEFLineBufferSurface,
882 "SfcIEFLineBufferSurface",
883 Format_Buffer,
884 MOS_GFXRES_BUFFER,
885 MOS_TILE_LINEAR,
886 dwSize,
887 1,
888 false,
889 MOS_MMC_DISABLED,
890 &bAllocated,
891 MOS_HW_RESOURCE_DEF_MAX,
892 MOS_TILE_UNSET_GMM,
893 memTypeSurfVideoMem,
894 MOS_MEMPOOL_DEVICEMEMORY == memTypeSurfVideoMem));
895
896 // Allocate SFD Line Buffer surface----------------------------------------------
897 if (NEED_SFD_LINE_BUFFER(pSfcStateParams->dwScaledRegionHeight))
898 {
899 dwSize = SFD_LINE_BUFFER_SIZE(pSfcStateParams->dwScaledRegionHeight);
900
901 VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface(
902 m_osInterface,
903 &m_SFDLineBufferSurface,
904 "SfcSFDLineBufferSurface",
905 Format_Buffer,
906 MOS_GFXRES_BUFFER,
907 MOS_TILE_LINEAR,
908 dwSize,
909 1,
910 false,
911 MOS_MMC_DISABLED,
912 &bAllocated,
913 MOS_HW_RESOURCE_DEF_MAX,
914 MOS_TILE_UNSET_GMM,
915 memTypeSurfVideoMem,
916 MOS_MEMPOOL_DEVICEMEMORY == memTypeSurfVideoMem));
917 }
918
919 finish:
920 if (eStatus != MOS_STATUS_SUCCESS)
921 {
922 FreeResources();
923 }
924
925 return eStatus;
926 }
927
GetOutputWidthHeightAlignUnit(MOS_FORMAT outputFormat,uint16_t & widthAlignUnit,uint16_t & heightAlignUnit,bool isInterlacedScaling)928 void VphalSfcState::GetOutputWidthHeightAlignUnit(
929 MOS_FORMAT outputFormat,
930 uint16_t &widthAlignUnit,
931 uint16_t &heightAlignUnit,
932 bool isInterlacedScaling)
933 {
934 widthAlignUnit = 1;
935 heightAlignUnit = 1;
936
937 switch (VpHal_GetSurfaceColorPack(outputFormat))
938 {
939 case VPHAL_COLORPACK_420:
940 widthAlignUnit = 2;
941 heightAlignUnit = 2;
942 break;
943 case VPHAL_COLORPACK_422:
944 widthAlignUnit = 2;
945 break;
946 default:
947 break;
948 }
949 }
950
SetSfcStateInputOrderingMode(PVPHAL_VEBOX_RENDER_DATA veboxRenderData,PMHW_SFC_STATE_PARAMS sfcStateParams)951 void VphalSfcState::SetSfcStateInputOrderingMode(
952 PVPHAL_VEBOX_RENDER_DATA veboxRenderData,
953 PMHW_SFC_STATE_PARAMS sfcStateParams)
954 {
955 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VE_4x8;
956 }
957
SetSfcStateParams(PVPHAL_VEBOX_RENDER_DATA pRenderData,PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutSurface)958 MOS_STATUS VphalSfcState::SetSfcStateParams(
959 PVPHAL_VEBOX_RENDER_DATA pRenderData,
960 PVPHAL_SURFACE pSrcSurface,
961 PVPHAL_SURFACE pOutSurface)
962 {
963 MOS_STATUS eStatus;
964 PMOS_INTERFACE pOsInterface;
965 PMHW_SFC_STATE_PARAMS pSfcStateParams;
966 PVPHAL_ALPHA_PARAMS pAlphaParams;
967 VPHAL_COLOR_SAMPLE_8 Src;
968 VPHAL_CSPACE src_cspace, dst_cspace;
969 uint16_t wOutputWidthAlignUnit;
970 uint16_t wOutputHeightAlignUnit;
971 uint16_t wInputWidthAlignUnit;
972 uint16_t wInputHeightAlignUnit;
973 uint32_t dwSurfaceWidth;
974 uint32_t dwSurfaceHeight;
975 uint32_t dwVeboxBottom;
976 uint32_t dwVeboxRight;
977 VPHAL_GET_SURFACE_INFO Info;
978 VPHAL_COLORPACK dstColorPack;
979
980 VPHAL_RENDER_CHK_NULL(pSrcSurface);
981 VPHAL_RENDER_CHK_NULL(pOutSurface);
982
983 eStatus = MOS_STATUS_UNKNOWN;
984 pOsInterface = m_osInterface;
985 pSfcStateParams = m_renderData.SfcStateParams;
986 pAlphaParams = m_renderData.pAlphaParams;
987 wOutputWidthAlignUnit = 1;
988 wOutputHeightAlignUnit = 1;
989 wInputWidthAlignUnit = 1;
990 wInputHeightAlignUnit = 1;
991 dwVeboxBottom = (uint32_t)pSrcSurface->rcSrc.bottom;
992 dwVeboxRight = (uint32_t)pSrcSurface->rcSrc.right;
993 dstColorPack = VpHal_GetSurfaceColorPack(pOutSurface->Format);
994
995 VPHAL_RENDER_CHK_NULL(pSfcStateParams);
996 MOS_ZeroMemory(pSfcStateParams, sizeof(*pSfcStateParams));
997
998 pSfcStateParams->sfcPipeMode = MEDIASTATE_SFC_PIPE_VE_TO_SFC;
999
1000 // Setup General params
1001 // Set chroma subsampling type according to the Vebox output, but
1002 // when Vebox is bypassed, set it according to the source surface format.
1003 if (pRenderData->bIECP)
1004 {
1005 pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444;
1006 m_renderData.SfcSrcChromaSiting = MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_TOP;
1007 pSfcStateParams->b8tapChromafiltering = true;
1008 }
1009 else if (pRenderData->bDeinterlace)
1010 {
1011 pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
1012 pSfcStateParams->b8tapChromafiltering = false;
1013 }
1014 else
1015 {
1016 if (m_renderData.SfcInputFormat == Format_NV12 ||
1017 (m_renderData.SfcInputFormat == Format_P010) ||
1018 (m_renderData.SfcInputFormat == Format_P016))
1019 {
1020 pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_420;
1021 pSfcStateParams->b8tapChromafiltering = false;
1022 }
1023 else if (VpHal_GetSurfaceColorPack(m_renderData.SfcInputFormat) == VPHAL_COLORPACK_422)
1024 {
1025 pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
1026 pSfcStateParams->b8tapChromafiltering = false;
1027 }
1028 else if (VpHal_GetSurfaceColorPack(m_renderData.SfcInputFormat) == VPHAL_COLORPACK_444)
1029 {
1030 pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444;
1031 pSfcStateParams->b8tapChromafiltering = true;
1032 }
1033 else
1034 {
1035 pSfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_400;
1036 pSfcStateParams->b8tapChromafiltering = false;
1037 }
1038 }
1039
1040 // Default to Horizontal Left, Vertical Top
1041 pSfcStateParams->dwChromaDownSamplingVerticalCoef = (pOutSurface->ChromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ?
1042 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 :
1043 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8;
1044 pSfcStateParams->dwChromaDownSamplingHorizontalCoef = (pOutSurface->ChromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ?
1045 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 :
1046 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8;
1047
1048 // Set the Pre-AVS chroma downsampling param according to SFC i/o chroma subsampling type
1049 switch (pSfcStateParams->dwInputChromaSubSampling)
1050 {
1051 case MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444:
1052 if (dstColorPack == VPHAL_COLORPACK_420)
1053 {
1054 pSfcStateParams->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_444TO420;
1055 }
1056 else if (dstColorPack == VPHAL_COLORPACK_422)
1057 {
1058 pSfcStateParams->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_444TO422;
1059 }
1060 break;
1061
1062 case MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H:
1063 if (dstColorPack == VPHAL_COLORPACK_420)
1064 {
1065 pSfcStateParams->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_422TO420;
1066 }
1067 break;
1068
1069 default:
1070 pSfcStateParams->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_DISABLED;
1071 break;
1072 }
1073
1074 VPHAL_RENDER_NORMALMESSAGE("SfcStateParams: dwInputChromaSubSampling %d, b8tapChromafiltering %d, dwChromaDownSamplingMode %d.",
1075 pSfcStateParams->dwInputChromaSubSampling,
1076 pSfcStateParams->b8tapChromafiltering,
1077 pSfcStateParams->dwChromaDownSamplingMode);
1078
1079 SetSfcStateInputOrderingMode(pRenderData, pSfcStateParams);
1080
1081 pSfcStateParams->OutputFrameFormat = pOutSurface->Format;
1082
1083 pSfcStateParams->fChromaSubSamplingXSiteOffset = 0.0F;
1084 pSfcStateParams->fChromaSubSamplingYSiteOffset = 0.0F;
1085
1086 // Setup all parameters in SFC_STATE related to Scaling and AVS
1087 pSfcStateParams->dwAVSFilterMode = (m_renderData.SfcScalingMode == VPHAL_SCALING_BILINEAR) ?
1088 MEDIASTATE_SFC_AVS_FILTER_BILINEAR :
1089 MEDIASTATE_SFC_AVS_FILTER_8x8;
1090
1091 // Get the SFC input surface size from Vebox
1092 AdjustBoundary(
1093 pSrcSurface,
1094 &dwSurfaceWidth,
1095 &dwSurfaceHeight);
1096
1097 // This should be set to the height and width of the frame streaming from Vebox
1098 pSfcStateParams->dwInputFrameHeight = dwSurfaceHeight;
1099 pSfcStateParams->dwInputFrameWidth = dwSurfaceWidth;
1100
1101 // Apply alignment restriction to the Region of the output frame.
1102 GetOutputWidthHeightAlignUnit(
1103 pSfcStateParams->OutputFrameFormat,
1104 wOutputWidthAlignUnit,
1105 wOutputHeightAlignUnit,
1106 pSrcSurface->bInterlacedScaling);
1107
1108 // Apply alignment restriction to Region of the input frame.
1109 GetInputWidthHeightAlignUnit(
1110 m_renderData.SfcInputFormat,
1111 pSfcStateParams->OutputFrameFormat,
1112 wInputWidthAlignUnit,
1113 wInputHeightAlignUnit,
1114 pSrcSurface->bInterlacedScaling);
1115
1116 if(pSrcSurface->bDirectionalScalar)
1117 {
1118 dwVeboxBottom *= 2;
1119 dwVeboxRight *= 2;
1120 }
1121
1122 // This should be set to the height and width of the Render Target
1123 pSfcStateParams->dwOutputFrameHeight = MOS_ALIGN_CEIL(pOutSurface->dwHeight, wOutputHeightAlignUnit);
1124 pSfcStateParams->dwOutputFrameWidth = MOS_ALIGN_CEIL(pOutSurface->dwWidth, wOutputWidthAlignUnit);
1125
1126 // Region of the input frame which needs to be processed by SFC
1127 pSfcStateParams->dwSourceRegionVerticalOffset = MOS_ALIGN_CEIL((uint32_t)pSrcSurface->rcSrc.top, wInputHeightAlignUnit);
1128 pSfcStateParams->dwSourceRegionHorizontalOffset = MOS_ALIGN_CEIL((uint32_t)pSrcSurface->rcSrc.left, wInputWidthAlignUnit);
1129
1130
1131 if (pSrcSurface->bInterlacedScaling &&
1132 (pSrcSurface->rcSrc.bottom - pSrcSurface->rcSrc.top) == (pSrcSurface->rcDst.bottom - pSrcSurface->rcDst.top))
1133 {
1134 pSfcStateParams->dwSourceRegionHeight = MOS_ALIGN_CEIL(
1135 MOS_MIN((uint32_t)(dwVeboxBottom - pSrcSurface->rcSrc.top), pSfcStateParams->dwInputFrameHeight),
1136 wInputHeightAlignUnit);
1137
1138 if (pSfcStateParams->dwSourceRegionHeight > pSfcStateParams->dwInputFrameHeight)
1139 {
1140 pSfcStateParams->dwSourceRegionHeight -= wInputHeightAlignUnit;
1141 VPHAL_RENDER_ASSERTMESSAGE("Interlaced scaling case: surface height is %d, which is not 4 align. Use floor align.", pSfcStateParams->dwInputFrameHeight);
1142 }
1143 }
1144 else
1145 {
1146 pSfcStateParams->dwSourceRegionHeight = MOS_ALIGN_FLOOR(
1147 MOS_MIN((uint32_t)(dwVeboxBottom - pSrcSurface->rcSrc.top), pSfcStateParams->dwInputFrameHeight),
1148 wInputHeightAlignUnit);
1149 }
1150
1151 pSfcStateParams->dwSourceRegionWidth = MOS_ALIGN_FLOOR(
1152 MOS_MIN((uint32_t)(dwVeboxRight - pSrcSurface->rcSrc.left), pSfcStateParams->dwInputFrameWidth),
1153 wInputWidthAlignUnit);
1154
1155 // Size of the Scaled Region over the Render Target
1156 pSfcStateParams->dwScaledRegionHeight = MOS_ALIGN_CEIL(MOS_UF_ROUND(m_renderData.fScaleY * pSfcStateParams->dwSourceRegionHeight), wOutputHeightAlignUnit);
1157 pSfcStateParams->dwScaledRegionWidth = MOS_ALIGN_CEIL(MOS_UF_ROUND(m_renderData.fScaleX * pSfcStateParams->dwSourceRegionWidth), wOutputWidthAlignUnit);
1158
1159
1160
1161 // Scaled region is pre-rotated. Adjust its width and height with those of the output frame
1162 if (m_renderData.SfcRotation == VPHAL_ROTATION_IDENTITY ||
1163 m_renderData.SfcRotation == VPHAL_ROTATION_180 ||
1164 m_renderData.SfcRotation == VPHAL_MIRROR_HORIZONTAL ||
1165 m_renderData.SfcRotation == VPHAL_MIRROR_VERTICAL)
1166 {
1167 pSfcStateParams->dwScaledRegionHeight = MOS_MIN(pSfcStateParams->dwScaledRegionHeight, pSfcStateParams->dwOutputFrameHeight);
1168 pSfcStateParams->dwScaledRegionWidth = MOS_MIN(pSfcStateParams->dwScaledRegionWidth, pSfcStateParams->dwOutputFrameWidth);
1169 }
1170 else
1171 {
1172 pSfcStateParams->dwScaledRegionHeight = MOS_MIN(pSfcStateParams->dwScaledRegionHeight, pSfcStateParams->dwOutputFrameWidth);
1173 pSfcStateParams->dwScaledRegionWidth = MOS_MIN(pSfcStateParams->dwScaledRegionWidth, pSfcStateParams->dwOutputFrameHeight);
1174 }
1175
1176 // Refine the Scaling ratios in the X and Y direction. SFC output Scaled size may be changed based on the restriction of SFC alignment.
1177 // The scaling ratio could be changed and not equal to the fScaleX/Y.
1178 // Driver must make sure that the scaling ratio should be matched with the output/input size before send to HW
1179 pSfcStateParams->fAVSXScalingRatio = (float)pSfcStateParams->dwScaledRegionWidth / (float)pSfcStateParams->dwSourceRegionWidth;
1180 pSfcStateParams->fAVSYScalingRatio = (float)pSfcStateParams->dwScaledRegionHeight / (float)pSfcStateParams->dwSourceRegionHeight;
1181
1182 pSfcStateParams->dwScaledRegionVerticalOffset = MOS_ALIGN_FLOOR((uint32_t)pSrcSurface->rcDst.top, wOutputHeightAlignUnit);
1183 pSfcStateParams->dwScaledRegionHorizontalOffset = MOS_ALIGN_FLOOR((uint32_t)pSrcSurface->rcDst.left, wOutputWidthAlignUnit);
1184
1185 // Enable Adaptive Filtering for YUV input only, if it is being upscaled
1186 // in either direction. We must check for this before clamping the SF.
1187 if (IS_YUV_FORMAT(m_renderData.SfcInputFormat) &&
1188 (m_renderData.fScaleX > 1.0F ||
1189 m_renderData.fScaleY > 1.0F))
1190 {
1191 pSfcStateParams->bBypassXAdaptiveFilter = false;
1192 pSfcStateParams->bBypassYAdaptiveFilter = false;
1193
1194 if (MEDIASTATE_SFC_AVS_FILTER_BILINEAR == pSfcStateParams->dwAVSFilterMode)
1195 {
1196 VPHAL_RENDER_NORMALMESSAGE("Legacy Check: bBypassXAdaptiveFilter/bBypassYAdaptiveFilter are set to false for bilinear scaling.");
1197 }
1198 }
1199 else
1200 {
1201 pSfcStateParams->bBypassXAdaptiveFilter = true;
1202 pSfcStateParams->bBypassYAdaptiveFilter = true;
1203 }
1204
1205 if (IS_RGB_FORMAT(m_renderData.SfcInputFormat) &&
1206 pSfcStateParams->b8tapChromafiltering == true)
1207 {
1208 pSfcStateParams->bRGBAdaptive = true;
1209 }
1210 else
1211 {
1212 pSfcStateParams->bRGBAdaptive = false;
1213 }
1214
1215 pSfcStateParams->bAVSChromaUpsamplingEnable = (m_renderData.bScaling || m_renderData.bForcePolyPhaseCoefs);
1216
1217 // Rotation params
1218 if (m_renderData.SfcRotation <= VPHAL_ROTATION_270)
1219 {
1220 // Rotation only
1221 pSfcStateParams->RotationMode = VpHal_GetMhwRotationParam(m_renderData.SfcRotation);
1222 pSfcStateParams->bMirrorEnable = false;
1223 }
1224 else if (m_renderData.SfcRotation <= VPHAL_MIRROR_VERTICAL)
1225 {
1226 // Mirror only
1227 pSfcStateParams->dwMirrorType = VpHal_GetMhwRotationParam(m_renderData.SfcRotation) - 4;
1228 pSfcStateParams->RotationMode = MHW_ROTATION_IDENTITY;
1229 pSfcStateParams->bMirrorEnable = true;
1230 }
1231 else
1232 {
1233 // Rotation + Mirror
1234 pSfcStateParams->dwMirrorType = MHW_MIRROR_HORIZONTAL;
1235 pSfcStateParams->RotationMode = VpHal_GetMhwRotationParam(m_renderData.SfcRotation);
1236 pSfcStateParams->bMirrorEnable = true;
1237 }
1238
1239 VPHAL_RENDER_NORMALMESSAGE("SfcStateParams: dwMirrorType %d, RotationMode %d, bMirrorEnable %d.",
1240 pSfcStateParams->dwMirrorType,
1241 pSfcStateParams->RotationMode,
1242 pSfcStateParams->bMirrorEnable);
1243
1244 // ColorFill params
1245 if (m_renderData.bColorFill)
1246 {
1247 pSfcStateParams->bColorFillEnable = true;
1248
1249 Src.dwValue = m_renderData.pColorFillParams->Color;
1250 src_cspace = m_renderData.pColorFillParams->CSpace;
1251 dst_cspace = pOutSurface->ColorSpace;
1252
1253 // Convert BG color only if not done so before. CSC is expensive!
1254 if ((m_colorFillColorSrc.dwValue != Src.dwValue) ||
1255 (m_colorFillSrcCspace != src_cspace) ||
1256 (m_colorFillRTCspace != dst_cspace))
1257 {
1258 // Clean history Dst BG Color if hit unsupported format
1259 if (!VpHal_CSC_8(&m_colorFillColorDst, &Src, src_cspace, dst_cspace))
1260 {
1261 MOS_ZeroMemory(&m_colorFillColorDst, sizeof(m_colorFillColorDst));
1262 }
1263
1264 // store the values for next iteration
1265 m_colorFillColorSrc = Src;
1266 m_colorFillSrcCspace = src_cspace;
1267 m_colorFillRTCspace = dst_cspace;
1268 }
1269
1270 if (IS_YUV_FORMAT(pOutSurface->Format) || IS_ALPHA_YUV_FORMAT(pOutSurface->Format))
1271 {
1272 pSfcStateParams->fColorFillYRPixel = (float)m_colorFillColorDst.Y / 255.0F;
1273 pSfcStateParams->fColorFillUGPixel = (float)m_colorFillColorDst.U / 255.0F;
1274 pSfcStateParams->fColorFillVBPixel = (float)m_colorFillColorDst.V / 255.0F;
1275 }
1276 else
1277 {
1278 // Swap the channel here because HW only natively supports XBGR output
1279 if ((pOutSurface->Format == Format_A8R8G8B8) ||
1280 (pOutSurface->Format == Format_X8R8G8B8) ||
1281 (pOutSurface->Format == Format_R10G10B10A2) ||
1282 (pOutSurface->Format == Format_A16R16G16B16))
1283 {
1284 pSfcStateParams->fColorFillYRPixel = (float)m_colorFillColorDst.B / 255.0F;
1285 pSfcStateParams->fColorFillUGPixel = (float)m_colorFillColorDst.G / 255.0F;
1286 pSfcStateParams->fColorFillVBPixel = (float)m_colorFillColorDst.R / 255.0F;
1287 }
1288 else
1289 {
1290 pSfcStateParams->fColorFillYRPixel = (float)m_colorFillColorDst.R / 255.0F;
1291 pSfcStateParams->fColorFillUGPixel = (float)m_colorFillColorDst.G / 255.0F;
1292 pSfcStateParams->fColorFillVBPixel = (float)m_colorFillColorDst.B / 255.0F;
1293 }
1294 }
1295 pSfcStateParams->fColorFillAPixel = (float)Src.A / 255.0F;
1296 }
1297
1298 if (pAlphaParams)
1299 {
1300 switch (pAlphaParams->AlphaMode)
1301 {
1302 case VPHAL_ALPHA_FILL_MODE_NONE:
1303 if (pOutSurface->Format == Format_A8R8G8B8 ||
1304 pOutSurface->Format == Format_A8B8G8R8 ||
1305 pOutSurface->Format == Format_R10G10B10A2 ||
1306 pOutSurface->Format == Format_B10G10R10A2 ||
1307 pOutSurface->Format == Format_AYUV ||
1308 pOutSurface->Format == Format_Y410 ||
1309 pOutSurface->Format == Format_Y416)
1310 {
1311 pSfcStateParams->fAlphaPixel = pAlphaParams->fAlpha;
1312 pSfcStateParams->fColorFillAPixel = pAlphaParams->fAlpha;
1313 }
1314 else
1315 {
1316 pSfcStateParams->fAlphaPixel = 1.0F;
1317 }
1318 break;
1319
1320 case VPHAL_ALPHA_FILL_MODE_BACKGROUND:
1321 pSfcStateParams->fAlphaPixel = m_renderData.bColorFill ?
1322 pSfcStateParams->fColorFillAPixel : 1.0F;
1323 break;
1324
1325 case VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM:
1326 case VPHAL_ALPHA_FILL_MODE_OPAQUE:
1327 default:
1328 pSfcStateParams->fAlphaPixel = 1.0F;
1329 pSfcStateParams->fColorFillAPixel = 1.0F;
1330 }
1331 }
1332 else
1333 {
1334 pSfcStateParams->fAlphaPixel = 1.0F;
1335 }
1336
1337 // CSC params
1338 pSfcStateParams->bCSCEnable = m_renderData.bCSC;
1339
1340 // ARGB8,ABGR10 output format need to enable swap
1341 if (pOutSurface->Format == Format_X8R8G8B8 ||
1342 pOutSurface->Format == Format_A8R8G8B8 ||
1343 pOutSurface->Format == Format_R10G10B10A2)
1344 {
1345 pSfcStateParams->bRGBASwapEnable = true;
1346 }
1347 else
1348 {
1349 pSfcStateParams->bRGBASwapEnable = false;
1350 }
1351
1352 if (IS_RGB_CSPACE(pSrcSurface->ColorSpace))
1353 {
1354 pSfcStateParams->bInputColorSpace = true;
1355 }
1356 else
1357 {
1358 pSfcStateParams->bInputColorSpace = false;
1359 }
1360
1361 VPHAL_RENDER_NORMALMESSAGE("SfcStateParams: bCSCEnable %d, bRGBASwapEnable %d, bMirrorEnable %d.",
1362 pSfcStateParams->bCSCEnable,
1363 pSfcStateParams->bRGBASwapEnable,
1364 pSfcStateParams->bMirrorEnable);
1365
1366 // Set MMC status
1367 VPHAL_RENDER_CHK_STATUS(SetSfcMmcStatus(
1368 pRenderData,
1369 pOutSurface,
1370 pSfcStateParams));
1371
1372 VPHAL_RENDER_CHK_STATUS(AllocateResources());
1373
1374 // Set OS resources used by SFC state
1375 pSfcStateParams->pOsResAVSLineBuffer = &m_AVSLineBufferSurface.OsResource;
1376 pSfcStateParams->pOsResIEFLineBuffer = &m_IEFLineBufferSurface.OsResource;
1377 pSfcStateParams->pOsResOutputSurface = &pOutSurface->OsResource;
1378
1379 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
1380
1381 Info.S3dChannel = pOutSurface->Channel;
1382 Info.ArraySlice = m_currentChannel;
1383
1384 VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
1385 pOsInterface,
1386 &Info,
1387 pOutSurface));
1388
1389 pSfcStateParams->dwOutputSurfaceOffset = pOutSurface->YPlaneOffset.iSurfaceOffset;
1390 pSfcStateParams->wOutputSurfaceUXOffset = (uint16_t) pOutSurface->UPlaneOffset.iXOffset;
1391 pSfcStateParams->wOutputSurfaceUYOffset = (uint16_t) pOutSurface->UPlaneOffset.iYOffset;
1392 pSfcStateParams->wOutputSurfaceVXOffset = (uint16_t) pOutSurface->VPlaneOffset.iXOffset;
1393 pSfcStateParams->wOutputSurfaceVYOffset = (uint16_t) pOutSurface->VPlaneOffset.iYOffset;
1394
1395 finish:
1396 return eStatus;
1397 }
1398
SetSfcMmcStatus(PVPHAL_VEBOX_RENDER_DATA renderData,PVPHAL_SURFACE outSurface,PMHW_SFC_STATE_PARAMS sfcStateParams)1399 MOS_STATUS VphalSfcState::SetSfcMmcStatus(
1400 PVPHAL_VEBOX_RENDER_DATA renderData,
1401 PVPHAL_SURFACE outSurface,
1402 PMHW_SFC_STATE_PARAMS sfcStateParams)
1403 {
1404 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1405
1406 if (IsFormatMMCSupported(outSurface->Format) && // SFC output MMC only support several format
1407 (renderData->Component == COMPONENT_VPreP) && // SFC output MMC only enable in Vprep
1408 (renderData->bEnableMMC == true) &&
1409 (outSurface->bCompressible == true) &&
1410 (outSurface->TileType == MOS_TILE_Y))
1411 {
1412 if ((m_renderData.fScaleX >= 0.5F) &&
1413 (m_renderData.fScaleY >= 0.5F))
1414 {
1415 sfcStateParams->bMMCEnable = true;
1416 sfcStateParams->MMCMode = MOS_MMC_HORIZONTAL;
1417 }
1418 else if ((m_renderData.fScaleX < 0.5F) &&
1419 (m_renderData.fScaleY < 0.5F))
1420 {
1421 sfcStateParams->bMMCEnable = true;
1422 sfcStateParams->MMCMode = MOS_MMC_VERTICAL;
1423 }
1424 else
1425 {
1426 sfcStateParams->bMMCEnable = false;
1427 sfcStateParams->MMCMode = MOS_MMC_DISABLED;
1428 }
1429
1430 VPHAL_RENDER_NORMALMESSAGE("SfcStateParams: bMMCEnable %d, MMCMode %d.",
1431 sfcStateParams->bMMCEnable,
1432 sfcStateParams->MMCMode);
1433
1434 // Set mmc status output surface for output surface
1435 m_osInterface->pfnSetMemoryCompressionMode(m_osInterface, &outSurface->OsResource, MOS_MEMCOMP_STATE(sfcStateParams->MMCMode));
1436 }
1437
1438 return eStatus;
1439 }
1440
SetAvsStateParams()1441 MOS_STATUS VphalSfcState::SetAvsStateParams()
1442 {
1443 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1444 PMHW_SFC_AVS_STATE pMhwAvsState = nullptr;
1445
1446 MHW_SCALING_MODE scalingMode = MHW_SCALING_AVS;
1447 bool bUse8x8Filter = false;
1448
1449 VPHAL_RENDER_CHK_NULL(m_sfcInterface);
1450
1451 pMhwAvsState = &m_avsState.AvsStateParams;
1452 MOS_ZeroMemory(pMhwAvsState, sizeof(MHW_SFC_AVS_STATE));
1453
1454 if (m_renderData.bScaling ||
1455 m_renderData.bForcePolyPhaseCoefs)
1456 {
1457 pMhwAvsState->dwInputHorizontalSiting = (m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
1458
1459 pMhwAvsState->dwInputVerticalSitting = (m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
1460
1461 if (m_renderData.SfcSrcChromaSiting == MHW_CHROMA_SITING_NONE)
1462 {
1463 m_renderData.SfcSrcChromaSiting = MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_TOP;
1464
1465 if (VpHal_GetSurfaceColorPack(m_renderData.SfcInputFormat) == VPHAL_COLORPACK_420) // For 420, default is Left & Center, else default is Left & Top
1466 {
1467 pMhwAvsState->dwInputVerticalSitting = SFC_AVS_INPUT_SITING_COEF_4_OVER_8;
1468 }
1469 }
1470
1471 m_renderData.pAvsParams->bForcePolyPhaseCoefs = m_renderData.bForcePolyPhaseCoefs;
1472
1473 scalingMode = VpHal_GetMhwScalingModeParam(m_renderData.SfcScalingMode);
1474 VPHAL_RENDER_CHK_STATUS(m_sfcInterface->SetSfcAVSScalingMode(scalingMode));
1475
1476 if (m_renderData.SfcStateParams)
1477 {
1478 pMhwAvsState->dwAVSFilterMode = m_renderData.SfcStateParams->dwAVSFilterMode;
1479 }
1480 else
1481 {
1482 pMhwAvsState->dwAVSFilterMode = MEDIASTATE_SFC_AVS_FILTER_8x8;
1483 }
1484
1485 if (pMhwAvsState->dwAVSFilterMode == MEDIASTATE_SFC_AVS_FILTER_8x8)
1486 {
1487 bUse8x8Filter = true;
1488 }
1489
1490 VPHAL_RENDER_CHK_STATUS(m_sfcInterface->SetSfcSamplerTable(
1491 &m_avsState.LumaCoeffs,
1492 &m_avsState.ChromaCoeffs,
1493 m_renderData.pAvsParams,
1494 m_renderData.SfcInputFormat,
1495 m_renderData.fScaleX,
1496 m_renderData.fScaleY,
1497 m_renderData.SfcSrcChromaSiting,
1498 bUse8x8Filter,
1499 0,
1500 0));
1501 }
1502
1503 finish:
1504 return eStatus;
1505 }
1506
SetIefStateCscParams(PMHW_SFC_STATE_PARAMS sfcStateParams,PMHW_SFC_IEF_STATE_PARAMS iefStateParams)1507 void VphalSfcState::SetIefStateCscParams(
1508 PMHW_SFC_STATE_PARAMS sfcStateParams,
1509 PMHW_SFC_IEF_STATE_PARAMS iefStateParams)
1510 {
1511
1512 // Setup CSC params
1513 if (m_renderData.bCSC)
1514 {
1515 sfcStateParams->bCSCEnable = true;
1516 iefStateParams->bCSCEnable = true;
1517
1518 // Calculate matrix if not done so before. CSC is expensive!
1519 if ((m_cscInputCspace != m_renderData.SfcInputCspace) ||
1520 (m_cscRTCspace != m_renderData.pSfcPipeOutSurface->ColorSpace))
1521 {
1522 // Get the matrix to use for conversion
1523 VpHal_GetCscMatrix(
1524 m_renderData.SfcInputCspace,
1525 m_renderData.pSfcPipeOutSurface->ColorSpace,
1526 m_cscCoeff,
1527 m_cscInOffset,
1528 m_cscOutOffset);
1529
1530 // Store it for next BLT
1531 m_cscInputCspace = m_renderData.SfcInputCspace;
1532 m_cscRTCspace = m_renderData.pSfcPipeOutSurface->ColorSpace;
1533 }
1534
1535 // Copy the values into IEF Params
1536 iefStateParams->pfCscCoeff = m_cscCoeff;
1537 iefStateParams->pfCscInOffset = m_cscInOffset;
1538 iefStateParams->pfCscOutOffset = m_cscOutOffset;
1539 }
1540
1541 }
1542
SetIefStateParams(PVPHAL_VEBOX_RENDER_DATA veboxRenderData,PMHW_SFC_STATE_PARAMS sfcStateParams,PVPHAL_SURFACE inputSurface)1543 void VphalSfcState::SetIefStateParams(
1544 PVPHAL_VEBOX_RENDER_DATA veboxRenderData,
1545 PMHW_SFC_STATE_PARAMS sfcStateParams,
1546 PVPHAL_SURFACE inputSurface)
1547 {
1548 PMHW_SFC_IEF_STATE_PARAMS iefStateParams;
1549
1550 MOS_UNUSED(veboxRenderData);
1551 VPHAL_RENDER_CHK_NULL_NO_STATUS(sfcStateParams);
1552 VPHAL_RENDER_CHK_NULL_NO_STATUS(inputSurface);
1553
1554 iefStateParams = &m_renderData.IEFStateParams;
1555 MOS_ZeroMemory(iefStateParams, sizeof(*iefStateParams));
1556
1557 // Setup IEF and STE params
1558 if (m_renderData.bIEF)
1559 {
1560 Ief ief(
1561 inputSurface);
1562
1563 ief.SetHwState(
1564 sfcStateParams,
1565 iefStateParams);
1566 } // end of setup IEF and STE params
1567
1568 // Setup CSC params
1569 SetIefStateCscParams(
1570 sfcStateParams,
1571 iefStateParams);
1572
1573 finish:
1574 return;
1575 }
1576
UpdateRenderingFlags(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutSurface,PVPHAL_VEBOX_RENDER_DATA pRenderData)1577 MOS_STATUS VphalSfcState::UpdateRenderingFlags(
1578 PVPHAL_SURFACE pSrcSurface,
1579 PVPHAL_SURFACE pOutSurface,
1580 PVPHAL_VEBOX_RENDER_DATA pRenderData)
1581 {
1582 MOS_STATUS eStatus;
1583
1584 MOS_UNUSED(pSrcSurface);
1585 MOS_UNUSED(pOutSurface);
1586 MOS_UNUSED(pRenderData);
1587
1588 eStatus = MOS_STATUS_SUCCESS;
1589
1590 return eStatus;
1591 }
1592
SetupSfcState(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutSurface,PVPHAL_VEBOX_RENDER_DATA pRenderData)1593 MOS_STATUS VphalSfcState::SetupSfcState(
1594 PVPHAL_SURFACE pSrcSurface,
1595 PVPHAL_SURFACE pOutSurface,
1596 PVPHAL_VEBOX_RENDER_DATA pRenderData)
1597 {
1598 MOS_STATUS eStatus;
1599 PMOS_INTERFACE pOsInterface;
1600 PRENDERHAL_INTERFACE pRenderHal;
1601
1602 VPHAL_RENDER_CHK_NULL(pSrcSurface);
1603 VPHAL_RENDER_CHK_NULL(pOutSurface);
1604 VPHAL_RENDER_CHK_NULL(pRenderData);
1605
1606 eStatus = MOS_STATUS_UNKNOWN;
1607 pOsInterface = m_osInterface;
1608 pRenderHal = m_renderHal;
1609
1610 // Update SFC rendering flags if any
1611 VPHAL_RENDER_CHK_STATUS(UpdateRenderingFlags(
1612 pSrcSurface,
1613 pOutSurface,
1614 pRenderData));
1615
1616 // Setup params related to SFC_STATE
1617 VPHAL_RENDER_CHK_STATUS(SetSfcStateParams(
1618 pRenderData,
1619 pSrcSurface,
1620 pOutSurface));
1621
1622 // Setup params related to SFC_AVS_STATE
1623 VPHAL_RENDER_CHK_STATUS(SetAvsStateParams());
1624
1625 // Setup params related to SFC_IEF_STATE
1626 if (m_renderData.bIEF ||
1627 m_renderData.bCSC)
1628 {
1629 SetIefStateParams(
1630 pRenderData,
1631 m_renderData.SfcStateParams,
1632 pSrcSurface);
1633 }
1634
1635 finish:
1636 return eStatus;
1637 }
1638
SendSfcCmd(PVPHAL_VEBOX_RENDER_DATA pRenderData,PMOS_COMMAND_BUFFER pCmdBuffer)1639 MOS_STATUS VphalSfcState::SendSfcCmd(
1640 PVPHAL_VEBOX_RENDER_DATA pRenderData,
1641 PMOS_COMMAND_BUFFER pCmdBuffer)
1642 {
1643 PMHW_SFC_INTERFACE pSfcInterface;
1644 MHW_SFC_LOCK_PARAMS SfcLockParams;
1645 MOS_STATUS eStatus;
1646 MHW_SFC_OUT_SURFACE_PARAMS OutSurfaceParam;
1647
1648 VPHAL_RENDER_CHK_NULL(m_sfcInterface);
1649 VPHAL_RENDER_CHK_NULL(m_osInterface);
1650 VPHAL_RENDER_CHK_NULL(pRenderData);
1651 VPHAL_RENDER_CHK_NULL(pCmdBuffer);
1652
1653 eStatus = MOS_STATUS_SUCCESS;
1654 pSfcInterface = m_sfcInterface;
1655
1656 // Ensure VEBOX can write
1657 m_osInterface->pfnSyncOnResource(
1658 m_osInterface,
1659 &m_renderData.pSfcPipeOutSurface->OsResource,
1660 MOS_GPU_CONTEXT_VEBOX,
1661 true);
1662
1663 if (m_renderData.pSfcPipeOutSurface->bOverlay)
1664 {
1665 m_osInterface->pfnSyncOnOverlayResource(
1666 m_osInterface,
1667 &m_renderData.pSfcPipeOutSurface->OsResource,
1668 MOS_GPU_CONTEXT_VEBOX);
1669 }
1670
1671 // Setup params for SFC Lock command
1672 SfcLockParams.sfcPipeMode = MhwSfcInterface::SFC_PIPE_MODE_VEBOX;
1673 SfcLockParams.bOutputToMemory = (pRenderData->bDeinterlace || pRenderData->bDenoise);
1674
1675 // Send SFC_LOCK command to acquire SFC pipe for Vebox
1676 VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcLock(
1677 pCmdBuffer,
1678 &SfcLockParams));
1679
1680 VPHAL_RENDER_CHK_STATUS(VpHal_InitMhwOutSurfParams(
1681 m_renderData.pSfcPipeOutSurface,
1682 &OutSurfaceParam));
1683
1684 // Send SFC MMCD cmd
1685 VPHAL_RENDER_CHK_STATUS(RenderSfcMmcCMD(
1686 pSfcInterface,
1687 m_renderHal->pMhwMiInterface,
1688 m_osInterface,
1689 &OutSurfaceParam,
1690 pCmdBuffer));
1691
1692 // Send SFC_STATE command
1693 VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcState(
1694 pCmdBuffer,
1695 m_renderData.SfcStateParams,
1696 &OutSurfaceParam));
1697
1698 // Send SFC_AVS_STATE command
1699 VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcAvsState(
1700 pCmdBuffer,
1701 &m_avsState.AvsStateParams));
1702
1703 if (m_renderData.bScaling ||
1704 m_renderData.bForcePolyPhaseCoefs)
1705 {
1706
1707 // Send SFC_AVS_LUMA_TABLE command
1708 VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcAvsLumaTable(
1709 pCmdBuffer,
1710 &m_avsState.LumaCoeffs));
1711
1712 // Send SFC_AVS_CHROMA_TABLE command
1713 VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcAvsChromaTable(
1714 pCmdBuffer,
1715 &m_avsState.ChromaCoeffs));
1716 }
1717
1718 // Send SFC_IEF_STATE command
1719 if (m_renderData.bIEF || m_renderData.bCSC)
1720 {
1721 VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcIefState(
1722 pCmdBuffer,
1723 &m_renderData.IEFStateParams));
1724 }
1725
1726 // Send SFC_FRAME_START command to start processing a frame
1727 VPHAL_RENDER_CHK_STATUS(pSfcInterface->AddSfcFrameStart(
1728 pCmdBuffer,
1729 MhwSfcInterface::SFC_PIPE_MODE_VEBOX));
1730
1731 finish:
1732 return eStatus;
1733 }
1734
1735 #endif // __VPHAL_SFC_SUPPORTED
1736