1 /*
2 * Copyright (c) 2022-2024, 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 vp_render_sfc_base.cpp
24 //! \brief 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
30 #include "vp_render_sfc_base.h"
31 #include "vp_utils.h"
32 #include "mhw_vebox.h"
33 #include "mhw_sfc.h"
34 #include "vp_render_ief.h"
35 #include "mos_interface.h"
36 #include "mhw_sfc_itf.h"
37 #include "mhw_mi_itf.h"
38 #include "vp_platform_interface.h"
39 #include "vp_hal_ddi_utils.h"
40
41 namespace vp {
42
SfcRenderBase(VP_MHWINTERFACE & vpMhwinterface,PVpAllocator & allocator,bool disbaleSfcDithering)43 SfcRenderBase::SfcRenderBase(
44 VP_MHWINTERFACE &vpMhwinterface,
45 PVpAllocator &allocator,
46 bool disbaleSfcDithering) :
47 m_allocator(allocator),
48 m_disableSfcDithering(disbaleSfcDithering)
49 {
50 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(vpMhwinterface.m_osInterface);
51 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(vpMhwinterface.m_skuTable);
52 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(vpMhwinterface.m_waTable);
53 m_osInterface = vpMhwinterface.m_osInterface;
54 m_skuTable = vpMhwinterface.m_skuTable;
55 m_waTable = vpMhwinterface.m_waTable;
56
57 // Allocate AVS state
58 InitAVSParams(
59 &m_AvsParameters,
60 k_YCoefficientTableSize,
61 k_UVCoefficientTableSize);
62
63 m_sfcItf = vpMhwinterface.m_vpPlatformInterface->GetMhwSfcItf();
64 m_miItf = vpMhwinterface.m_vpPlatformInterface->GetMhwMiItf();
65 }
66
~SfcRenderBase()67 SfcRenderBase::~SfcRenderBase()
68 {
69 DestroyAVSParams(&m_AvsParameters);
70
71 if (m_sfcStateParams)
72 {
73 MOS_FreeMemAndSetNull(m_sfcStateParams);
74 }
75
76 FreeResources();
77
78 if (m_iefObj)
79 {
80 MOS_Delete(m_iefObj);
81 }
82 }
83
Init()84 MOS_STATUS SfcRenderBase::Init()
85 {
86 VP_FUNC_CALL();
87
88 MOS_ZeroMemory(&m_renderData, sizeof(m_renderData));
89
90 m_bVdboxToSfc = false;
91 m_pipeMode = mhw::sfc::SFC_PIPE_MODE_VEBOX;
92
93 m_scalabilityParams.numPipe = 1;
94 m_scalabilityParams.curPipe = 0;
95
96 MOS_ZeroMemory(&m_histogramSurf, sizeof(m_histogramSurf));
97
98 return InitSfcStateParams();
99 }
100
SetCodecPipeMode(CODECHAL_STANDARD codecStandard)101 MOS_STATUS SfcRenderBase::SetCodecPipeMode(CODECHAL_STANDARD codecStandard)
102 {
103 VP_FUNC_CALL();
104
105 if (CODECHAL_VC1 == codecStandard ||
106 CODECHAL_AVC == codecStandard ||
107 CODECHAL_VP8 == codecStandard ||
108 CODECHAL_JPEG == codecStandard)
109 {
110 m_pipeMode = mhw::sfc::SFC_PIPE_MODE_VDBOX;
111 }
112 else
113 {
114 return MOS_STATUS_INVALID_PARAMETER;
115 }
116 return MOS_STATUS_SUCCESS;
117 }
118
Init(VIDEO_PARAMS & videoParams)119 MOS_STATUS SfcRenderBase::Init(VIDEO_PARAMS &videoParams)
120 {
121 VP_FUNC_CALL();
122
123 MOS_ZeroMemory(&m_renderData, sizeof(m_renderData));
124
125 m_bVdboxToSfc = true;
126
127 m_videoConfig = videoParams;
128
129 m_videoConfig.scalabilityParams.numPipe = (0 == m_videoConfig.scalabilityParams.numPipe ? 1 : m_videoConfig.scalabilityParams.numPipe);
130 if (m_videoConfig.scalabilityParams.curPipe >= m_videoConfig.scalabilityParams.numPipe)
131 {
132 VP_RENDER_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
133 }
134
135 m_scalabilityParams = m_videoConfig.scalabilityParams;
136
137 VP_PUBLIC_CHK_STATUS_RETURN(SetCodecPipeMode(m_videoConfig.codecStandard));
138
139 MOS_ZeroMemory(&m_histogramSurf, sizeof(m_histogramSurf));
140
141 return InitSfcStateParams();
142 }
143
SetRotationAndMirrowParams(mhw::sfc::SFC_STATE_PAR * psfcStateParams)144 void SfcRenderBase::SetRotationAndMirrowParams(mhw::sfc::SFC_STATE_PAR *psfcStateParams)
145 {
146 VP_FUNC_CALL();
147
148 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(psfcStateParams);
149
150 psfcStateParams->RotationMode = (MHW_ROTATION)m_renderData.SfcRotation;
151 psfcStateParams->bMirrorEnable = m_renderData.bMirrorEnable;
152 psfcStateParams->dwMirrorType = m_renderData.mirrorType;
153 }
154
SetChromasitingParams(mhw::sfc::SFC_STATE_PAR * psfcStateParams)155 void SfcRenderBase::SetChromasitingParams(mhw::sfc::SFC_STATE_PAR *psfcStateParams)
156 {
157 VP_FUNC_CALL();
158
159 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(psfcStateParams);
160 SetSfcStateInputChromaSubSampling(psfcStateParams);
161 SetSfcStateInputOrderingMode(psfcStateParams);
162 }
163
SetColorFillParams(mhw::sfc::SFC_STATE_PAR * psfcStateParams)164 void SfcRenderBase::SetColorFillParams(
165 mhw::sfc::SFC_STATE_PAR *psfcStateParams)
166 {
167 VP_FUNC_CALL();
168
169 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(m_renderData.pColorFillParams);
170
171 psfcStateParams->bColorFillEnable = m_renderData.pColorFillParams->bColorfillEnable;
172
173 if (psfcStateParams->bColorFillEnable)
174 {
175 psfcStateParams->fColorFillYRPixel = m_renderData.pColorFillParams->fColorFillYRPixel;
176 psfcStateParams->fColorFillUGPixel = m_renderData.pColorFillParams->fColorFillUGPixel;
177 psfcStateParams->fColorFillVBPixel = m_renderData.pColorFillParams->fColorFillVBPixel;
178 psfcStateParams->fColorFillAPixel = m_renderData.pColorFillParams->fColorFillAPixel;
179 }
180 }
181
SetXYAdaptiveFilter(mhw::sfc::SFC_STATE_PAR * psfcStateParams)182 void SfcRenderBase::SetXYAdaptiveFilter(
183 mhw::sfc::SFC_STATE_PAR *psfcStateParams)
184 {
185 VP_FUNC_CALL();
186
187 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(psfcStateParams);
188
189 // Enable Adaptive Filtering for YUV input only, if it is being upscaled
190 // in either direction. We must check for this before clamping the SF.
191 if ((IS_YUV_FORMAT(m_renderData.SfcInputFormat) ||
192 m_renderData.SfcInputFormat == Format_AYUV) &&
193 (m_renderData.fScaleX > 1.0F ||
194 m_renderData.fScaleY > 1.0F) &&
195 psfcStateParams->dwAVSFilterMode != MEDIASTATE_SFC_AVS_FILTER_BILINEAR)
196 {
197 //For AVS, we need set psfcStateParams->bBypassXAdaptiveFilter and bBypassYAdaptiveFilter as false;
198 psfcStateParams->bBypassXAdaptiveFilter = false;
199 psfcStateParams->bBypassYAdaptiveFilter = false;
200 }
201 else
202 {
203 psfcStateParams->bBypassXAdaptiveFilter = true;
204 psfcStateParams->bBypassYAdaptiveFilter = true;
205 }
206 }
207
SetRGBAdaptive(mhw::sfc::SFC_STATE_PAR * psfcStateParams)208 void SfcRenderBase::SetRGBAdaptive(
209 mhw::sfc::SFC_STATE_PAR *psfcStateParams)
210 {
211 VP_FUNC_CALL();
212
213 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(psfcStateParams);
214
215 if (IS_RGB_FORMAT(m_renderData.SfcInputFormat) &&
216 psfcStateParams->b8tapChromafiltering == true)
217 {
218 psfcStateParams->bRGBAdaptive = true;
219 }
220 else
221 {
222 psfcStateParams->bRGBAdaptive = false;
223 }
224 }
225
SetIefStateCscParams(mhw::sfc::SFC_STATE_PAR * psfcStateParams,mhw::sfc::SFC_IEF_STATE_PAR * pIEFStateParams)226 MOS_STATUS SfcRenderBase::SetIefStateCscParams(
227 mhw::sfc::SFC_STATE_PAR *psfcStateParams,
228 mhw::sfc::SFC_IEF_STATE_PAR *pIEFStateParams)
229 {
230 VP_FUNC_CALL();
231
232 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
233
234 VP_RENDER_CHK_NULL_RETURN(psfcStateParams);
235 VP_RENDER_CHK_NULL_RETURN(pIEFStateParams);
236
237 if (m_renderData.bCSC)
238 {
239 psfcStateParams->bCSCEnable = true;
240 pIEFStateParams->bCSCEnable = true;
241 if (m_bVdboxToSfc)
242 {
243 m_cscInputSwapNeeded = false;
244 if (m_videoConfig.jpeg.jpegChromaType == jpegRGB && m_videoConfig.codecStandard == CODECHAL_JPEG)
245 {
246 m_cscCoeff[0] = 1.000000000f;
247 m_cscCoeff[1] = 0.000000000f;
248 m_cscCoeff[2] = 0.000000000f;
249 m_cscCoeff[3] = 0.000000000f;
250 m_cscCoeff[4] = 1.000000000f;
251 m_cscCoeff[5] = 0.000000000f;
252 m_cscCoeff[6] = 0.000000000f;
253 m_cscCoeff[7] = 0.000000000f;
254 m_cscCoeff[8] = 1.000000000f;
255
256 m_cscInOffset[0] = 0.000000000f; // Adjusted to S8.2 to accommodate VPHAL
257 m_cscInOffset[1] = 0.000000000f; // Adjusted to S8.2 to accommodate VPHAL
258 m_cscInOffset[2] = 0.000000000f; // Adjusted to S8.2 to accommodate VPHAL
259 }
260 else
261 {
262 if (m_renderData.SfcInputFormat != Format_400P)
263 {
264 m_cscCoeff[0] = 1.16438353f;
265 m_cscCoeff[1] = 0.000000000f;
266 m_cscCoeff[2] = 1.59602666f;
267 m_cscCoeff[3] = 1.16438353f;
268 m_cscCoeff[4] = -0.391761959f;
269 m_cscCoeff[5] = -0.812967300f;
270 m_cscCoeff[6] = 1.16438353f;
271 m_cscCoeff[7] = 2.01723218f;
272 m_cscCoeff[8] = 0.000000000f;
273 }
274 else
275 {
276 m_cscCoeff[0] = 1.16438353f;
277 m_cscCoeff[1] = 0.000000000f;
278 m_cscCoeff[2] = 0.000000000f;
279 m_cscCoeff[3] = 1.16438353f;
280 m_cscCoeff[4] = 0.000000000f;
281 m_cscCoeff[5] = 0.000000000f;
282 m_cscCoeff[6] = 1.16438353f;
283 m_cscCoeff[7] = 0.000000000f;
284 m_cscCoeff[8] = 0.000000000f;
285 }
286 m_cscInOffset[0] = -16.000000f; // Adjusted to S8.2 to accommodate VPHAL
287 m_cscInOffset[1] = -128.000000f; // Adjusted to S8.2 to accommodate VPHAL
288 m_cscInOffset[2] = -128.000000f; // Adjusted to S8.2 to accommodate VPHAL
289 }
290 m_cscOutOffset[0] = 0.000000000f; // Adjusted to S8.2 to accommodate VPHAL
291 m_cscOutOffset[1] = 0.000000000f; // Adjusted to S8.2 to accommodate VPHAL
292 m_cscOutOffset[2] = 0.000000000f; // Adjusted to S8.2 to accommodate VPHAL
293 }
294 else if ((m_cscInputCspace != m_renderData.SfcInputCspace) ||
295 (m_renderData.pSfcPipeOutSurface && m_cscRTCspace != m_renderData.pSfcPipeOutSurface->ColorSpace))
296 {
297 VpUtils::GetCscMatrixForVeSfc8Bit(
298 m_renderData.SfcInputCspace,
299 m_renderData.pSfcPipeOutSurface->ColorSpace,
300 m_cscCoeff,
301 m_cscInOffset,
302 m_cscOutOffset);
303
304 // swap the 1st and 3rd columns of the transfer matrix for A8R8G8B8 and X8R8G8B8
305 // to ensure SFC input being A8B8G8R8.
306 if (IsInputChannelSwapNeeded(m_renderData.SfcInputFormat))
307 {
308 float fTemp[3] = {};
309 fTemp[0] = m_cscCoeff[0];
310 fTemp[1] = m_cscCoeff[3];
311 fTemp[2] = m_cscCoeff[6];
312
313 m_cscCoeff[0] = m_cscCoeff[2];
314 m_cscCoeff[3] = m_cscCoeff[5];
315 m_cscCoeff[6] = m_cscCoeff[8];
316
317 m_cscCoeff[2] = fTemp[0];
318 m_cscCoeff[5] = fTemp[1];
319 m_cscCoeff[8] = fTemp[2];
320 m_cscInputSwapNeeded = true;
321 }
322 else
323 {
324 m_cscInputSwapNeeded = false;
325 }
326
327 VP_RENDER_NORMALMESSAGE("sfc csc coeff calculated. (sfcInputCspace, cscRTCspace) current (%d, %d), previous (%d, %d), swap flag %d",
328 m_renderData.SfcInputCspace, m_renderData.pSfcPipeOutSurface->ColorSpace,
329 m_cscInputCspace, m_cscRTCspace, m_cscInputSwapNeeded ? 1 :0);
330
331 m_cscInputCspace = m_renderData.SfcInputCspace;
332 m_cscRTCspace = m_renderData.pSfcPipeOutSurface->ColorSpace;
333 }
334 else if (m_cscInputSwapNeeded != IsInputChannelSwapNeeded(m_renderData.SfcInputFormat))
335 {
336 float fTemp[3] = {};
337 fTemp[0] = m_cscCoeff[0];
338 fTemp[1] = m_cscCoeff[3];
339 fTemp[2] = m_cscCoeff[6];
340
341 m_cscCoeff[0] = m_cscCoeff[2];
342 m_cscCoeff[3] = m_cscCoeff[5];
343 m_cscCoeff[6] = m_cscCoeff[8];
344
345 m_cscCoeff[2] = fTemp[0];
346 m_cscCoeff[5] = fTemp[1];
347 m_cscCoeff[8] = fTemp[2];
348
349 m_cscInputSwapNeeded = IsInputChannelSwapNeeded(m_renderData.SfcInputFormat);
350
351 VP_RENDER_NORMALMESSAGE("sfc csc coeff swap flag need be updated to %d. sfcInputFormat %d, sfcInputCspace %d, cscRTCspace %d",
352 (m_cscInputSwapNeeded ? 1 : 0),
353 m_renderData.SfcInputFormat, m_cscInputCspace, m_cscRTCspace);
354 }
355 else
356 {
357 VP_RENDER_NORMALMESSAGE("sfc csc coeff reused. sfcInputFormat %d, sfcInputCspace %d, cscRTCspace %d, swap flag %d",
358 m_renderData.SfcInputFormat, m_cscInputCspace, m_cscRTCspace, (m_cscInputSwapNeeded ? 1 : 0));
359 }
360
361 pIEFStateParams->pfCscCoeff = m_cscCoeff;
362 pIEFStateParams->pfCscInOffset = m_cscInOffset;
363 pIEFStateParams->pfCscOutOffset = m_cscOutOffset;
364 }
365 return eStatus;
366 }
367
SetIefStateParams(mhw::sfc::SFC_STATE_PAR * psfcStateParams)368 MOS_STATUS SfcRenderBase::SetIefStateParams(
369 mhw::sfc::SFC_STATE_PAR *psfcStateParams)
370 {
371 VP_FUNC_CALL();
372
373 mhw::sfc::SFC_IEF_STATE_PAR *pIefStateParams = nullptr;
374 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
375
376 VP_RENDER_CHK_NULL_RETURN(psfcStateParams);
377
378 auto &iefStateParams = m_sfcItf->MHW_GETPAR_F(SFC_IEF_STATE)();
379 pIefStateParams = &iefStateParams;
380 MOS_ZeroMemory(pIefStateParams, sizeof(*pIefStateParams));
381 pIefStateParams->sfcPipeMode = m_pipeMode;
382
383 // Setup IEF and STE params
384 if (m_renderData.bIEF && m_renderData.pIefParams)
385 {
386 VP_RENDER_CHK_NULL_RETURN(m_iefObj);
387 m_iefObj->Init(m_renderData.pIefParams, m_renderData.SfcInputFormat, m_renderData.fScaleX, m_renderData.fScaleY);
388 m_iefObj->SetHwState(psfcStateParams, pIefStateParams);
389 } // end of setup IEF and STE params
390
391 // Setup CSC params
392 VP_RENDER_CHK_STATUS_RETURN(SetIefStateCscParams(
393 psfcStateParams,
394 pIefStateParams));
395
396 return eStatus;
397 }
398
SetAvsStateParams()399 MOS_STATUS SfcRenderBase::SetAvsStateParams()
400 {
401 VP_FUNC_CALL();
402
403 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
404 mhw::sfc::SFC_AVS_STATE_PAR *pMhwAvsState = nullptr;
405 MHW_SCALING_MODE scalingMode = MHW_SCALING_AVS;
406 bool bUse8x8Filter = false;
407
408 auto &avsStateParams = m_sfcItf->MHW_GETPAR_F(SFC_AVS_STATE)();
409 pMhwAvsState = &avsStateParams;
410 MOS_ZeroMemory(pMhwAvsState, sizeof(MHW_SFC_AVS_STATE));
411 pMhwAvsState->sfcPipeMode = m_pipeMode;
412
413 VP_RENDER_NORMALMESSAGE("bScaling %d, bForcePolyPhaseCoefs %d",
414 (m_renderData.bScaling ? 1 :0),
415 (m_renderData.bForcePolyPhaseCoefs ? 1 : 0));
416
417 if (m_renderData.bScaling ||
418 m_renderData.bForcePolyPhaseCoefs)
419 {
420 if (m_renderData.SfcSrcChromaSiting == MHW_CHROMA_SITING_NONE)
421 {
422 if (VpHalDDIUtils::GetSurfaceColorPack(m_renderData.SfcInputFormat) == VPHAL_COLORPACK_420) // For 420, default is Left & Center, else default is Left & Top
423 {
424 m_renderData.SfcSrcChromaSiting = MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_CENTER;
425 }
426 else
427 {
428 m_renderData.SfcSrcChromaSiting = MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_TOP;
429 }
430 }
431
432 pMhwAvsState->dwInputHorizontalSiting = (m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 :
433 ((m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 :
434 SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
435
436 pMhwAvsState->dwInputVerticalSitting = (m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 :
437 ((m_renderData.SfcSrcChromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 :
438 SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
439
440 if (m_renderData.SfcScalingMode == VPHAL_SCALING_NEAREST)
441 {
442 scalingMode = MHW_SCALING_NEAREST;
443 }
444 else if (m_renderData.SfcScalingMode == VPHAL_SCALING_BILINEAR)
445 {
446 scalingMode = MHW_SCALING_BILINEAR;
447 }
448 else
449 {
450 scalingMode = MHW_SCALING_AVS;
451 }
452 VP_RENDER_CHK_STATUS_RETURN(SetSfcAVSScalingMode(scalingMode));
453
454 if (m_renderData.sfcStateParams)
455 {
456 pMhwAvsState->dwAVSFilterMode = m_renderData.sfcStateParams->dwAVSFilterMode;
457 }
458 else
459 {
460 pMhwAvsState->dwAVSFilterMode = MEDIASTATE_SFC_AVS_FILTER_8x8;
461 }
462
463 if (pMhwAvsState->dwAVSFilterMode == MEDIASTATE_SFC_AVS_FILTER_8x8)
464 {
465 bUse8x8Filter = true;
466 }
467
468 // directly get the par of SFC_AVS_LUMA_Coeff_Table_PAR and initialize.
469 auto &lumaCoeffs = m_sfcItf->MHW_GETPAR_F(SFC_AVS_LUMA_Coeff_Table)();
470
471 // directly get the par of SFC_AVS_CHROMA_Coeff_Table and initialize.
472 auto &chromaCoeffs = m_sfcItf->MHW_GETPAR_F(SFC_AVS_CHROMA_Coeff_Table)();
473
474 lumaCoeffs.sfcPipeMode = m_pipeMode;
475 chromaCoeffs.sfcPipeMode = m_pipeMode;
476
477 VP_RENDER_CHK_STATUS_RETURN(SetSfcSamplerTable(
478 &lumaCoeffs,
479 &chromaCoeffs,
480 m_renderData.pAvsParams,
481 m_renderData.SfcInputFormat,
482 m_renderData.fScaleX,
483 m_renderData.fScaleY,
484 m_renderData.SfcSrcChromaSiting,
485 bUse8x8Filter,
486 0,
487 0));
488 }
489
490 return eStatus;
491 }
492
SetLineBuffer(PMOS_RESOURCE & osResLineBuffer,VP_SURFACE * lineBuffer)493 MOS_STATUS SfcRenderBase::SetLineBuffer(PMOS_RESOURCE &osResLineBuffer, VP_SURFACE *lineBuffer)
494 {
495 VP_FUNC_CALL();
496
497 if (lineBuffer)
498 {
499 if (nullptr == lineBuffer->osSurface || Mos_ResourceIsNull(&lineBuffer->osSurface->OsResource))
500 {
501 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_NULL_POINTER);
502 }
503 osResLineBuffer = &lineBuffer->osSurface->OsResource;
504 }
505 else
506 {
507 osResLineBuffer = nullptr;
508 }
509 return MOS_STATUS_SUCCESS;
510 }
511
SetupSfcState(PVP_SURFACE targetSurface)512 MOS_STATUS SfcRenderBase::SetupSfcState(PVP_SURFACE targetSurface)
513 {
514 VP_FUNC_CALL();
515
516 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
517
518 VP_RENDER_CHK_NULL_RETURN(targetSurface);
519 VP_RENDER_CHK_NULL_RETURN(targetSurface->osSurface);
520
521 //---------------------------------
522 // Set SFC State: common properties
523 //---------------------------------
524 m_renderData.sfcStateParams->sfcPipeMode = (MEDIASTATE_SFC_PIPE_MODE)m_pipeMode;
525
526 m_renderData.sfcStateParams->InputFrameFormat = m_renderData.SfcInputFormat;
527 m_renderData.sfcStateParams->OutputFrameFormat = targetSurface->osSurface->Format;
528 m_renderData.sfcStateParams->dwOutputSurfaceOffset = targetSurface->osSurface->YPlaneOffset.iSurfaceOffset;
529 m_renderData.sfcStateParams->wOutputSurfaceUXOffset = (uint16_t) targetSurface->osSurface->UPlaneOffset.iXOffset;
530 m_renderData.sfcStateParams->wOutputSurfaceUYOffset = (uint16_t) targetSurface->osSurface->UPlaneOffset.iYOffset;
531 m_renderData.sfcStateParams->wOutputSurfaceVXOffset = (uint16_t) targetSurface->osSurface->VPlaneOffset.iXOffset;
532 m_renderData.sfcStateParams->wOutputSurfaceVYOffset = (uint16_t) targetSurface->osSurface->VPlaneOffset.iYOffset;
533
534 m_renderData.pSfcPipeOutSurface = targetSurface;
535 m_renderData.pAvsParams = &m_AvsParameters;
536
537 //---------------------------------
538 // Set SFC State: Scaling
539 //---------------------------------
540 m_AvsParameters.bForcePolyPhaseCoefs = m_renderData.bForcePolyPhaseCoefs;
541 VP_RENDER_CHK_STATUS_RETURN(SetAvsStateParams());
542 m_renderData.sfcStateParams->bAVSChromaUpsamplingEnable = m_renderData.bScaling ||
543 m_renderData.bForcePolyPhaseCoefs;
544
545 //---------------------------------
546 // Set SFC State: CSC/IEF
547 //---------------------------------
548 if (m_renderData.bIEF ||
549 m_renderData.bCSC)
550 {
551 VP_RENDER_CHK_STATUS_RETURN(SetIefStateParams(
552 m_renderData.sfcStateParams));
553 }
554
555 //---------------------------------
556 // Set SFC State: Rotation/Mirror
557 //---------------------------------
558 SetRotationAndMirrowParams(m_renderData.sfcStateParams);
559
560 //---------------------------------
561 // Set SFC State: Chromasiting
562 //---------------------------------
563 SetChromasitingParams(m_renderData.sfcStateParams);
564
565 //---------------------------------
566 // Set SFC State: XY Adaptive Filter
567 //---------------------------------
568 SetXYAdaptiveFilter(m_renderData.sfcStateParams);
569
570 //---------------------------------
571 // Set SFC State: RGB Adaptive Filter
572 //---------------------------------
573 SetRGBAdaptive(m_renderData.sfcStateParams);
574
575 //---------------------------------
576 // Set SFC State: Colorfill
577 //---------------------------------
578 SetColorFillParams(m_renderData.sfcStateParams);
579
580 VP_RENDER_CHK_STATUS_RETURN(AllocateResources());
581
582 m_renderData.sfcStateParams->pOsResOutputSurface = &targetSurface->osSurface->OsResource;
583
584 if (m_renderData.b1stPassOfSfc2PassScaling)
585 {
586 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(m_renderData.sfcStateParams->pOsResAVSLineBuffer, m_AVSLineBufferSurfaceArrayfor1stPassofSfc2Pass[m_scalabilityParams.curPipe]));
587 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(m_renderData.sfcStateParams->pOsResIEFLineBuffer, m_IEFLineBufferSurfaceArrayfor1stPassofSfc2Pass[m_scalabilityParams.curPipe]));
588 }
589 else
590 {
591 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(m_renderData.sfcStateParams->pOsResAVSLineBuffer, m_AVSLineBufferSurfaceArray[m_scalabilityParams.curPipe]));
592 VP_RENDER_CHK_STATUS_RETURN(SetLineBuffer(m_renderData.sfcStateParams->pOsResIEFLineBuffer, m_IEFLineBufferSurfaceArray[m_scalabilityParams.curPipe]));
593 }
594
595 VP_RENDER_CHK_STATUS_RETURN(SetupScalabilityParams());
596
597 return eStatus;
598 }
599
SetScalingParams(PSFC_SCALING_PARAMS scalingParams)600 MOS_STATUS SfcRenderBase::SetScalingParams(PSFC_SCALING_PARAMS scalingParams)
601 {
602 VP_FUNC_CALL();
603
604 VP_PUBLIC_CHK_NULL_RETURN(scalingParams);
605
606 if (mhw::sfc::SFC_PIPE_MODE_VEBOX != m_pipeMode &&
607 (scalingParams->dwInputFrameHeight != scalingParams->dwSourceRegionHeight ||
608 scalingParams->dwInputFrameWidth != scalingParams->dwSourceRegionWidth))
609 {
610 // For Integral Image Mode, this source region width/height is Reserved.
611 // In VD modes, source region width/height must be programmed to same value as input frame resolution width/height.
612 VP_PUBLIC_ASSERTMESSAGE("Source region crop is not supported by Integral Image Mode and VD Mode!!");
613 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
614 }
615
616 // Adjust output width/height according to rotation.
617 if (VPHAL_ROTATION_90 == m_renderData.SfcRotation ||
618 VPHAL_ROTATION_270 == m_renderData.SfcRotation ||
619 VPHAL_ROTATE_90_MIRROR_VERTICAL == m_renderData.SfcRotation ||
620 VPHAL_ROTATE_90_MIRROR_HORIZONTAL == m_renderData.SfcRotation)
621 {
622 m_renderData.sfcStateParams->dwOutputFrameWidth = scalingParams->dwOutputFrameHeight;
623 m_renderData.sfcStateParams->dwOutputFrameHeight = scalingParams->dwOutputFrameWidth;
624 }
625 else
626 {
627 m_renderData.sfcStateParams->dwOutputFrameWidth = scalingParams->dwOutputFrameWidth;
628 m_renderData.sfcStateParams->dwOutputFrameHeight = scalingParams->dwOutputFrameHeight;
629 }
630
631 m_renderData.sfcStateParams->dwInputFrameHeight = scalingParams->dwInputFrameHeight;
632 m_renderData.sfcStateParams->dwInputFrameWidth = scalingParams->dwInputFrameWidth;
633 m_renderData.sfcStateParams->dwAVSFilterMode = scalingParams->bBilinearScaling ?
634 MEDIASTATE_SFC_AVS_FILTER_BILINEAR :
635 (mhw::sfc::SFC_PIPE_MODE_VDBOX == m_pipeMode ?
636 MEDIASTATE_SFC_AVS_FILTER_5x5 : MEDIASTATE_SFC_AVS_FILTER_8x8);
637 m_renderData.sfcStateParams->dwSourceRegionHeight = scalingParams->dwSourceRegionHeight;
638 m_renderData.sfcStateParams->dwSourceRegionWidth = scalingParams->dwSourceRegionWidth;
639 m_renderData.sfcStateParams->dwSourceRegionVerticalOffset = scalingParams->dwSourceRegionVerticalOffset;
640 m_renderData.sfcStateParams->dwSourceRegionHorizontalOffset = scalingParams->dwSourceRegionHorizontalOffset;
641 m_renderData.sfcStateParams->dwScaledRegionHeight = scalingParams->dwScaledRegionHeight;
642 m_renderData.sfcStateParams->dwScaledRegionWidth = scalingParams->dwScaledRegionWidth;
643 m_renderData.sfcStateParams->dwScaledRegionVerticalOffset = scalingParams->dwScaledRegionVerticalOffset;
644 m_renderData.sfcStateParams->dwScaledRegionHorizontalOffset = scalingParams->dwScaledRegionHorizontalOffset;
645 if (scalingParams->bRectangleEnabled)
646 {
647 m_renderData.sfcStateParams->bRectangleEnabled = true;
648 m_renderData.sfcStateParams->dwTargetRectangleStartHorizontalOffset = scalingParams->dwTargetRectangleStartHorizontalOffset;
649 m_renderData.sfcStateParams->dwTargetRectangleStartVerticalOffset = scalingParams->dwTargetRectangleStartVerticalOffset;
650 m_renderData.sfcStateParams->dwTargetRectangleEndHorizontalOffset = scalingParams->dwTargetRectangleEndHorizontalOffset;
651 m_renderData.sfcStateParams->dwTargetRectangleEndVerticalOffset = scalingParams->dwTargetRectangleEndVerticalOffset;
652 }
653 else
654 {
655 m_renderData.sfcStateParams->bRectangleEnabled = false;
656 }
657 m_renderData.sfcStateParams->fAVSXScalingRatio = scalingParams->fAVSXScalingRatio;
658 m_renderData.sfcStateParams->fAVSYScalingRatio = scalingParams->fAVSYScalingRatio;
659
660 m_renderData.bScaling = ((scalingParams->fAVSXScalingRatio == 1.0F) && (scalingParams->fAVSYScalingRatio == 1.0F)) ?
661 false : true;
662
663 m_renderData.fScaleX = scalingParams->fAVSXScalingRatio;
664 m_renderData.fScaleY = scalingParams->fAVSYScalingRatio;
665 m_renderData.SfcScalingMode = scalingParams->sfcScalingMode;
666
667 // ColorFill/Alpha settings
668 m_renderData.pColorFillParams = &(scalingParams->sfcColorfillParams);
669 m_renderData.sfcStateParams->fAlphaPixel = scalingParams->sfcColorfillParams.fAlphaPixel;
670 m_renderData.sfcStateParams->fColorFillAPixel = scalingParams->sfcColorfillParams.fColorFillAPixel;
671 m_renderData.sfcStateParams->fColorFillUGPixel = scalingParams->sfcColorfillParams.fColorFillUGPixel;
672 m_renderData.sfcStateParams->fColorFillVBPixel = scalingParams->sfcColorfillParams.fColorFillVBPixel;
673 m_renderData.sfcStateParams->fColorFillYRPixel = scalingParams->sfcColorfillParams.fColorFillYRPixel;
674 m_renderData.sfcStateParams->isDemosaicEnabled = scalingParams->isDemosaicNeeded;
675
676 // SfcInputFormat should be initialized during SetCscParams if SfcInputFormat not being Format_Any.
677 if (Format_Any == m_renderData.SfcInputFormat)
678 {
679 m_renderData.SfcInputFormat = scalingParams->inputFrameFormat;
680 }
681 else if (m_renderData.SfcInputFormat != scalingParams->inputFrameFormat)
682 {
683 VP_PUBLIC_ASSERTMESSAGE("Input formats configured during SetCscParams and SetScalingParams are not same!");
684 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
685 }
686
687 m_renderData.b1stPassOfSfc2PassScaling = scalingParams->b1stPassOfSfc2PassScaling;
688
689 VP_RENDER_NORMALMESSAGE("fScaleX %f, fScaleY %f, bScaling %d, SfcScalingMode %d, SfcInputFormat %d, bRectangleEnabled",
690 m_renderData.fScaleX, m_renderData.fScaleY,
691 (m_renderData.bScaling ? 1 : 0),
692 m_renderData.SfcScalingMode,
693 m_renderData.SfcInputFormat,
694 (scalingParams->bRectangleEnabled ? 1: 0));
695
696 return MOS_STATUS_SUCCESS;
697 }
698
IsVdboxSfcInputFormatSupported(CODECHAL_STANDARD codecStandard,MOS_FORMAT inputFormat)699 bool SfcRenderBase::IsVdboxSfcInputFormatSupported(
700 CODECHAL_STANDARD codecStandard,
701 MOS_FORMAT inputFormat)
702 {
703 VP_FUNC_CALL();
704
705 if (CODECHAL_AVC == codecStandard || CODECHAL_HEVC == codecStandard ||
706 CODECHAL_VP9 == codecStandard || CODECHAL_AV1 == codecStandard)
707 {
708 if ((inputFormat != Format_NV12) &&
709 (inputFormat != Format_400P) &&
710 (inputFormat != Format_IMC3) &&
711 (inputFormat != Format_422H) &&
712 (inputFormat != Format_444P) &&
713 (inputFormat != Format_P010) &&
714 (inputFormat != Format_YUY2) &&
715 (inputFormat != Format_AYUV) &&
716 (inputFormat != Format_Y210) &&
717 (inputFormat != Format_Y410) &&
718 (inputFormat != Format_P016) &&
719 (inputFormat != Format_Y216) &&
720 (inputFormat != Format_Y416))
721 {
722 VP_PUBLIC_ASSERTMESSAGE("Unsupported Output Format '0x%08x' for SFC.", inputFormat);
723 return false;
724 }
725 }
726 else if (codecStandard < CODECHAL_HCP_BASE) // For other legacy standard.
727 {
728 if ((inputFormat != Format_NV12) &&
729 (inputFormat != Format_400P) &&
730 (inputFormat != Format_IMC3) &&
731 (inputFormat != Format_422H) &&
732 (inputFormat != Format_444P) &&
733 (inputFormat != Format_P010))
734 {
735 VP_PUBLIC_ASSERTMESSAGE("Unsupported Input Format '0x%08x' for SFC.", inputFormat);
736 return false;
737 }
738 }
739 else
740 {
741 VP_PUBLIC_ASSERTMESSAGE("Unsupported standard '0x%08x' for SFC.", codecStandard);
742 return false;
743 }
744
745 return true;
746 }
747
IsVdboxSfcOutputFormatSupported(CODECHAL_STANDARD codecStandard,MOS_FORMAT outputFormat,MOS_TILE_TYPE tileType)748 bool SfcRenderBase::IsVdboxSfcOutputFormatSupported(
749 CODECHAL_STANDARD codecStandard,
750 MOS_FORMAT outputFormat,
751 MOS_TILE_TYPE tileType)
752 {
753 VP_FUNC_CALL();
754
755 if (tileType == MOS_TILE_LINEAR && (outputFormat == Format_NV12 || outputFormat == Format_P010))
756 {
757 VP_PUBLIC_ASSERTMESSAGE("Unsupported output format '0x%08x' on tile type '0x%08x'", outputFormat, tileType)
758 return false;
759 }
760
761 if (CODECHAL_AVC == codecStandard || CODECHAL_HEVC == codecStandard ||
762 CODECHAL_VP9 == codecStandard || CODECHAL_AV1 == codecStandard)
763 {
764 if ((outputFormat != Format_A8R8G8B8) &&
765 (outputFormat != Format_NV12) &&
766 (outputFormat != Format_P010) &&
767 (outputFormat != Format_YUY2) &&
768 (outputFormat != Format_AYUV) &&
769 (outputFormat != Format_P016) &&
770 (outputFormat != Format_Y210) &&
771 (outputFormat != Format_Y216) &&
772 (outputFormat != Format_Y410) &&
773 (outputFormat != Format_Y416))
774 {
775 VP_PUBLIC_ASSERTMESSAGE("Unsupported Output Format '0x%08x' for SFC.", outputFormat);
776 return false;
777 }
778 }
779 else if (codecStandard < CODECHAL_HCP_BASE) // For other legacy standard.
780 {
781 if (outputFormat != Format_A8R8G8B8 &&
782 outputFormat != Format_NV12 &&
783 outputFormat != Format_P010 &&
784 outputFormat != Format_YUY2)
785 {
786 VP_PUBLIC_ASSERTMESSAGE("Unsupported Output Format '0x%08x' for SFC.", outputFormat);
787 return false;
788 }
789 }
790 else
791 {
792 VP_PUBLIC_ASSERTMESSAGE("Unsupported standard '0x%08x' for SFC.", codecStandard);
793 return false;
794 }
795
796 return true;
797 }
798
IsInputChannelSwapNeeded(MOS_FORMAT inputFormat)799 bool SfcRenderBase::IsInputChannelSwapNeeded(MOS_FORMAT inputFormat)
800 {
801 VP_FUNC_CALL();
802
803 // 1st and 3rd columns of A8R8G8B8 and X8R8G8B8 need be swapped
804 // to ensure SFC input being A8B8G8R8.
805 if (inputFormat == Format_A8R8G8B8 ||
806 inputFormat == Format_X8R8G8B8)
807 {
808 return true;
809 }
810 else
811 {
812 return false;
813 }
814 }
815
UpdateIefParams(PVPHAL_IEF_PARAMS iefParams)816 MOS_STATUS SfcRenderBase::UpdateIefParams(PVPHAL_IEF_PARAMS iefParams)
817 {
818 VP_FUNC_CALL();
819 m_renderData.bIEF = (iefParams &&
820 iefParams->bEnabled &&
821 iefParams->fIEFFactor > 0.0F);
822 m_renderData.pIefParams = iefParams;
823 return MOS_STATUS_SUCCESS;
824 }
825
UpdateCscParams(FeatureParamCsc & cscParams)826 MOS_STATUS SfcRenderBase::UpdateCscParams(FeatureParamCsc &cscParams)
827 {
828 VP_RENDER_CHK_STATUS_RETURN(UpdateIefParams(cscParams.pIEFParams));
829 return MOS_STATUS_SUCCESS;
830 }
831
SetCSCParams(PSFC_CSC_PARAMS cscParams)832 MOS_STATUS SfcRenderBase::SetCSCParams(PSFC_CSC_PARAMS cscParams)
833 {
834 VP_FUNC_CALL();
835
836 VP_PUBLIC_CHK_NULL_RETURN(cscParams);
837
838 if (mhw::sfc::SFC_PIPE_MODE_VEBOX == m_pipeMode)
839 {
840 m_renderData.bIEF = cscParams->bIEFEnable;
841 m_renderData.pIefParams = cscParams->iefParams;
842 }
843 else
844 {
845 if (cscParams->bIEFEnable)
846 {
847 VP_PUBLIC_ASSERTMESSAGE("IEF is not supported by Integral Image Mode and VD Mode!");
848 }
849 m_renderData.bIEF = false;
850 m_renderData.pIefParams = nullptr;
851 }
852 m_renderData.bCSC = IsCscNeeded(*cscParams);
853 m_renderData.SfcInputCspace = cscParams->inputColorSpace;
854 m_renderData.SfcInputFormat = cscParams->inputFormat;
855
856 m_renderData.sfcStateParams->bRGBASwapEnable = IsOutputChannelSwapNeeded(cscParams->outputFormat);
857 m_renderData.sfcStateParams->bInputColorSpace = cscParams->isInputColorSpaceRGB;
858 m_renderData.sfcStateParams->isFullRgbG10P709 = cscParams->isFullRgbG10P709;
859 m_renderData.sfcStateParams->isDemosaicEnabled = cscParams->isDemosaicNeeded;
860
861 // Dithering parameter
862 if (cscParams->isDitheringNeeded && !m_disableSfcDithering)
863 {
864 m_renderData.sfcStateParams->ditheringEn = true;
865 }
866 else
867 {
868 m_renderData.sfcStateParams->ditheringEn = false;
869 }
870
871 // Chromasitting config
872 // VEBOX use polyphase coefficients for 1x scaling for better quality,
873 // VDBOX dosen't use polyphase coefficients.
874 if (mhw::sfc::SFC_PIPE_MODE_VEBOX == m_pipeMode)
875 {
876 m_renderData.bForcePolyPhaseCoefs = cscParams->bChromaUpSamplingEnable;
877 }
878 else
879 {
880 m_renderData.bForcePolyPhaseCoefs = false;
881 }
882 m_renderData.SfcSrcChromaSiting = cscParams->sfcSrcChromaSiting;
883
884 // 8-Tap chroma filter enabled or not
885 m_renderData.sfcStateParams->b8tapChromafiltering = cscParams->b8tapChromafiltering;
886
887 // config SFC chroma down sampling
888 m_renderData.sfcStateParams->dwChromaDownSamplingHorizontalCoef = cscParams->chromaDownSamplingHorizontalCoef;
889 m_renderData.sfcStateParams->dwChromaDownSamplingVerticalCoef = cscParams->chromaDownSamplingVerticalCoef;
890
891 VP_RENDER_NORMALMESSAGE("cscParams.isDitheringNeeded %d, m_disableSfcDithering %d, ditheringEn %d, bForcePolyPhaseCoefs %d",
892 cscParams->isDitheringNeeded, m_disableSfcDithering, m_renderData.sfcStateParams->ditheringEn,
893 (m_renderData.bForcePolyPhaseCoefs ? 1 : 0));
894
895 return MOS_STATUS_SUCCESS;
896 }
897
SetRotMirParams(PSFC_ROT_MIR_PARAMS rotMirParams)898 MOS_STATUS SfcRenderBase::SetRotMirParams(PSFC_ROT_MIR_PARAMS rotMirParams)
899 {
900
901 VP_FUNC_CALL();
902
903 VP_PUBLIC_CHK_NULL_RETURN(rotMirParams);
904
905 if (mhw::sfc::SFC_PIPE_MODE_VEBOX != m_pipeMode &&
906 VPHAL_ROTATION_IDENTITY != rotMirParams->rotationMode &&
907 VPHAL_MIRROR_HORIZONTAL != rotMirParams->rotationMode)
908 {
909 VP_PUBLIC_ASSERTMESSAGE("Rotation is not supported by Integral Image Mode and VD Mode!");
910 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
911 }
912
913 m_renderData.SfcRotation = rotMirParams->rotationMode;
914 m_renderData.bMirrorEnable = rotMirParams->bMirrorEnable;
915 m_renderData.mirrorType = rotMirParams->mirrorType;
916
917 // Adjust output width/height according to rotation.
918 if (VPHAL_ROTATION_90 == m_renderData.SfcRotation ||
919 VPHAL_ROTATION_270 == m_renderData.SfcRotation ||
920 VPHAL_ROTATE_90_MIRROR_VERTICAL == m_renderData.SfcRotation ||
921 VPHAL_ROTATE_90_MIRROR_HORIZONTAL == m_renderData.SfcRotation)
922 {
923 uint32_t width = m_renderData.sfcStateParams->dwOutputFrameWidth;
924 m_renderData.sfcStateParams->dwOutputFrameWidth = m_renderData.sfcStateParams->dwOutputFrameHeight;
925 m_renderData.sfcStateParams->dwOutputFrameHeight = width;
926 }
927
928 return MOS_STATUS_SUCCESS;
929 }
930
SetMmcParams(PMOS_SURFACE renderTarget,bool isFormalMmcSupported,bool isMmcEnabled)931 MOS_STATUS SfcRenderBase::SetMmcParams(PMOS_SURFACE renderTarget, bool isFormalMmcSupported, bool isMmcEnabled)
932 {
933 VP_FUNC_CALL();
934
935 VP_PUBLIC_CHK_NULL_RETURN(renderTarget);
936 VP_PUBLIC_CHK_NULL_RETURN(m_renderData.sfcStateParams);
937
938 if (renderTarget->CompressionMode &&
939 isFormalMmcSupported &&
940 renderTarget->TileType == MOS_TILE_Y &&
941 isMmcEnabled)
942 {
943 m_renderData.sfcStateParams->bMMCEnable = true;
944 m_renderData.sfcStateParams->MMCMode = renderTarget->CompressionMode;
945
946 if (renderTarget->OsResource.bUncompressedWriteNeeded)
947 {
948 m_renderData.sfcStateParams->MMCMode = MOS_MMC_RC;
949 }
950 }
951 else
952 {
953 m_renderData.sfcStateParams->bMMCEnable = false;
954 m_renderData.sfcStateParams->MMCMode = MOS_MMC_DISABLED;
955 }
956
957 return MOS_STATUS_SUCCESS;
958 }
959
SetSfcStateInputChromaSubSampling(mhw::sfc::SFC_STATE_PAR * sfcStateParams)960 MOS_STATUS SfcRenderBase::SetSfcStateInputChromaSubSampling(
961 mhw::sfc::SFC_STATE_PAR *sfcStateParams)
962 {
963 VP_FUNC_CALL();
964
965 VP_PUBLIC_CHK_NULL_RETURN(sfcStateParams);
966 VPHAL_COLORPACK colorPack = VpHalDDIUtils::GetSurfaceColorPack(m_renderData.SfcInputFormat);
967 if (VPHAL_COLORPACK_400 == colorPack)
968 {
969 sfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_400;
970 }
971 else if (VPHAL_COLORPACK_411 == colorPack)
972 {
973 sfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_411;
974 }
975 else if (VPHAL_COLORPACK_420 == colorPack)
976 {
977 sfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_420;
978 }
979 else if (VPHAL_COLORPACK_422 == colorPack)
980 {
981 sfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
982 }
983 else if (VPHAL_COLORPACK_444 == colorPack)
984 {
985 sfcStateParams->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444;
986 }
987 else
988 {
989 return MOS_STATUS_INVALID_PARAMETER;
990 }
991 return MOS_STATUS_SUCCESS;
992 }
993
SetSfcStateInputOrderingMode(mhw::sfc::SFC_STATE_PAR * sfcStateParams)994 MOS_STATUS SfcRenderBase::SetSfcStateInputOrderingMode(
995 mhw::sfc::SFC_STATE_PAR *sfcStateParams)
996 {
997 VP_FUNC_CALL();
998
999 VP_PUBLIC_CHK_NULL_RETURN(sfcStateParams);
1000
1001 if (m_bVdboxToSfc)
1002 {
1003 VP_PUBLIC_CHK_STATUS_RETURN(SetSfcStateInputOrderingModeVdbox(sfcStateParams));
1004 }
1005 else if (mhw::sfc::SFC_PIPE_MODE_VEBOX == m_pipeMode)
1006 {
1007 if (m_renderData.sfcStateParams && m_renderData.sfcStateParams->isDemosaicEnabled)
1008 {
1009 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VE_4x4;
1010 }
1011 else
1012 {
1013 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VE_4x8;
1014 }
1015 }
1016 else if (MEDIASTATE_SFC_PIPE_VE_TO_SFC_INTEGRAL == m_pipeMode)
1017 {
1018 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VE_4x4;
1019 }
1020 else
1021 {
1022 return MOS_STATUS_INVALID_PARAMETER;
1023 }
1024 return MOS_STATUS_SUCCESS;
1025 }
1026
SetSfcStateInputOrderingModeVdbox(mhw::sfc::SFC_STATE_PAR * sfcStateParams)1027 MOS_STATUS SfcRenderBase::SetSfcStateInputOrderingModeVdbox(
1028 mhw::sfc::SFC_STATE_PAR *sfcStateParams)
1029 {
1030 VP_FUNC_CALL();
1031
1032 VP_PUBLIC_CHK_NULL_RETURN(sfcStateParams);
1033 switch (m_videoConfig.codecStandard)
1034 {
1035 case CODECHAL_VC1:
1036 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_NOSHIFT;
1037 break;
1038 case CODECHAL_AVC:
1039 sfcStateParams->dwVDVEInputOrderingMode = m_videoConfig.avc.deblockingEnabled ? MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_SHIFT :
1040 MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_NOSHIFT;
1041 break;
1042 case CODECHAL_VP8:
1043 sfcStateParams->dwVDVEInputOrderingMode = m_videoConfig.vp8.deblockingEnabled ? MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_SHIFT :
1044 MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_VP8;
1045 break;
1046 case CODECHAL_JPEG:
1047 return SetSfcStateInputOrderingModeJpeg(sfcStateParams);
1048 case CODECHAL_HEVC:
1049 case CODECHAL_VP9:
1050 return SetSfcStateInputOrderingModeHcp(sfcStateParams);
1051 default:
1052 VP_PUBLIC_ASSERTMESSAGE("Unsupported codec standard.");
1053 return MOS_STATUS_INVALID_PARAMETER;
1054 }
1055 return MOS_STATUS_SUCCESS;
1056 }
1057
SetSfcStateInputOrderingModeJpeg(mhw::sfc::SFC_STATE_PAR * sfcStateParams)1058 MOS_STATUS SfcRenderBase::SetSfcStateInputOrderingModeJpeg(
1059 mhw::sfc::SFC_STATE_PAR *sfcStateParams)
1060 {
1061 VP_FUNC_CALL();
1062
1063 VP_PUBLIC_CHK_NULL_RETURN(sfcStateParams);
1064 if (CODECHAL_JPEG != m_videoConfig.codecStandard)
1065 {
1066 return MOS_STATUS_INVALID_PARAMETER;
1067 }
1068 switch (m_videoConfig.jpeg.jpegChromaType)
1069 {
1070 case jpegYUV400:
1071 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
1072 break;
1073 case jpegYUV411:
1074 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
1075 break;
1076 case jpegYUV420:
1077 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_JPEG;
1078 break;
1079 case jpegYUV422H2Y:
1080 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
1081 break;
1082 case jpegYUV422H4Y:
1083 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_JPEG;
1084 break;
1085 case jpegYUV444:
1086 case jpegRGB:
1087 case jpegBGR:
1088 sfcStateParams->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
1089 break;
1090 default:
1091 VP_PUBLIC_ASSERTMESSAGE("Unsupported input format of SFC.");
1092 return MOS_STATUS_INVALID_PARAMETER;
1093 }
1094 return MOS_STATUS_SUCCESS;
1095 }
1096
SetSfcStateInputOrderingModeHcp(mhw::sfc::SFC_STATE_PAR * pSfcStateParams)1097 MOS_STATUS SfcRenderBase::SetSfcStateInputOrderingModeHcp(
1098 mhw::sfc::SFC_STATE_PAR* pSfcStateParams)
1099 {
1100 return MOS_STATUS_UNIMPLEMENTED;
1101 }
1102
InitMhwOutSurfParams(PVP_SURFACE pSfcPipeOutSurface,PMHW_SFC_OUT_SURFACE_PARAMS pMhwOutSurfParams)1103 MOS_STATUS SfcRenderBase::InitMhwOutSurfParams(
1104 PVP_SURFACE pSfcPipeOutSurface,
1105 PMHW_SFC_OUT_SURFACE_PARAMS pMhwOutSurfParams)
1106 {
1107 VP_FUNC_CALL();
1108
1109 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1110 VP_RENDER_CHK_NULL_RETURN(pSfcPipeOutSurface);
1111 VP_RENDER_CHK_NULL_RETURN(pSfcPipeOutSurface->osSurface);
1112 VP_RENDER_CHK_NULL_RETURN(pMhwOutSurfParams);
1113
1114 MOS_ZeroMemory(pMhwOutSurfParams, sizeof(*pMhwOutSurfParams));
1115
1116 pMhwOutSurfParams->ChromaSiting = pSfcPipeOutSurface->ChromaSiting;
1117 pMhwOutSurfParams->dwWidth = pSfcPipeOutSurface->osSurface->dwWidth;
1118 pMhwOutSurfParams->dwHeight = pSfcPipeOutSurface->osSurface->dwHeight;
1119 pMhwOutSurfParams->dwPitch = pSfcPipeOutSurface->osSurface->dwPitch;
1120 pMhwOutSurfParams->TileType = pSfcPipeOutSurface->osSurface->TileType;
1121 pMhwOutSurfParams->TileModeGMM = pSfcPipeOutSurface->osSurface->TileModeGMM;
1122 pMhwOutSurfParams->bGMMTileEnabled = pSfcPipeOutSurface->osSurface->bGMMTileEnabled;
1123 pMhwOutSurfParams->pOsResource = &(pSfcPipeOutSurface->osSurface->OsResource);
1124 pMhwOutSurfParams->Format = pSfcPipeOutSurface->osSurface->Format;
1125 pMhwOutSurfParams->bCompressible = pSfcPipeOutSurface->osSurface->bCompressible;
1126 pMhwOutSurfParams->dwCompressionFormat = pSfcPipeOutSurface->osSurface->CompressionFormat;
1127 pMhwOutSurfParams->dwSurfaceXOffset = pSfcPipeOutSurface->osSurface->YPlaneOffset.iXOffset;
1128 pMhwOutSurfParams->dwSurfaceYOffset = pSfcPipeOutSurface->osSurface->YPlaneOffset.iYOffset;
1129
1130 if (pSfcPipeOutSurface->osSurface->dwPitch > 0)
1131 {
1132 pMhwOutSurfParams->dwUYoffset = ((pSfcPipeOutSurface->osSurface->UPlaneOffset.iSurfaceOffset - pSfcPipeOutSurface->osSurface->YPlaneOffset.iSurfaceOffset)
1133 / pSfcPipeOutSurface->osSurface->dwPitch) + pSfcPipeOutSurface->osSurface->UPlaneOffset.iYOffset;
1134
1135 pMhwOutSurfParams->dwVUoffset = ((pSfcPipeOutSurface->osSurface->VPlaneOffset.iSurfaceOffset - pSfcPipeOutSurface->osSurface->UPlaneOffset.iSurfaceOffset)
1136 / pSfcPipeOutSurface->osSurface->dwPitch) + pSfcPipeOutSurface->osSurface->VPlaneOffset.iYOffset;
1137 }
1138
1139 return eStatus;
1140 }
1141
SendSfcCmd(bool bOutputToMemory,PMOS_COMMAND_BUFFER pCmdBuffer)1142 MOS_STATUS SfcRenderBase::SendSfcCmd(
1143 bool bOutputToMemory,
1144 PMOS_COMMAND_BUFFER pCmdBuffer)
1145 {
1146 VP_FUNC_CALL();
1147
1148 mhw::sfc::SFC_LOCK_PAR SfcLockParams;
1149 MOS_STATUS eStatus;
1150 MHW_SFC_OUT_SURFACE_PARAMS OutSurfaceParam;
1151
1152 VP_RENDER_CHK_NULL_RETURN(pCmdBuffer);
1153
1154 eStatus = MOS_STATUS_SUCCESS;
1155
1156 SfcLockParams.sfcPipeMode = m_pipeMode;
1157 SfcLockParams.bOutputToMemory = bOutputToMemory;
1158
1159 // Send SFC_LOCK command to acquire SFC pipe for Vebox
1160 VP_RENDER_CHK_STATUS_RETURN(AddSfcLock(
1161 pCmdBuffer,
1162 &SfcLockParams));
1163
1164 VP_RENDER_CHK_STATUS_RETURN(InitMhwOutSurfParams(
1165 m_renderData.pSfcPipeOutSurface,
1166 &OutSurfaceParam));
1167
1168 // Send SFC_STATE command
1169 VP_RENDER_CHK_STATUS_RETURN(AddSfcState(
1170 pCmdBuffer,
1171 m_renderData.sfcStateParams,
1172 &OutSurfaceParam));
1173
1174 // Send SFC_AVS_STATE command
1175 VP_RENDER_CHK_STATUS_RETURN(AddSfcAvsState(
1176 pCmdBuffer));
1177
1178 if (m_renderData.bScaling ||
1179 m_renderData.bForcePolyPhaseCoefs)
1180 {
1181 // Send SFC_AVS_LUMA_TABLE command
1182 VP_RENDER_CHK_STATUS_RETURN(AddSfcAvsLumaTable(
1183 pCmdBuffer));
1184
1185 // Send SFC_AVS_CHROMA_TABLE command
1186 VP_RENDER_CHK_STATUS_RETURN(AddSfcAvsChromaTable(
1187 pCmdBuffer));
1188 }
1189
1190 // Send SFC_IEF_STATE command
1191 if (m_renderData.bIEF || m_renderData.bCSC)
1192 {
1193 // Will modified when enable IEF/CSC
1194 VP_RENDER_CHK_STATUS_RETURN(AddSfcIefState(
1195 pCmdBuffer));
1196 //SETPAR_AND_ADDCMD(SFC_IEF_STATE, sfcItf, pCmdBuffer);
1197 }
1198
1199 // Send SFC_FRAME_START command to start processing a frame
1200 VP_RENDER_CHK_STATUS_RETURN(AddSfcFrameStart(
1201 pCmdBuffer,
1202 m_pipeMode));
1203
1204 return eStatus;
1205 }
1206
InitAVSParams(PMHW_AVS_PARAMS pAVS_Params,uint32_t uiYCoeffTableSize,uint32_t uiUVCoeffTableSize)1207 void SfcRenderBase::InitAVSParams(
1208 PMHW_AVS_PARAMS pAVS_Params,
1209 uint32_t uiYCoeffTableSize,
1210 uint32_t uiUVCoeffTableSize)
1211 {
1212
1213 VP_FUNC_CALL();
1214
1215 int32_t size;
1216 char* ptr;
1217
1218 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(pAVS_Params);
1219 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN((void*)(uiYCoeffTableSize > 0));
1220 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN((void*)(uiUVCoeffTableSize > 0));
1221
1222 // Init AVS parameters
1223 pAVS_Params->Format = Format_None;
1224 pAVS_Params->fScaleX = 0.0F;
1225 pAVS_Params->fScaleY = 0.0F;
1226 pAVS_Params->piYCoefsX = nullptr;
1227
1228 // Allocate AVS coefficients, One set each for X and Y
1229 size = (uiYCoeffTableSize + uiUVCoeffTableSize) * 2;
1230
1231 ptr = (char*)MOS_AllocAndZeroMemory(size);
1232 if (ptr == nullptr)
1233 {
1234 VP_RENDER_ASSERTMESSAGE("No memory to allocate AVS coefficient tables.");
1235 return;
1236 }
1237
1238 pAVS_Params->piYCoefsX = (int32_t*)ptr;
1239
1240 ptr += uiYCoeffTableSize;
1241 pAVS_Params->piUVCoefsX = (int32_t*)ptr;
1242
1243 ptr += uiUVCoeffTableSize;
1244 pAVS_Params->piYCoefsY = (int32_t*)ptr;
1245
1246 ptr += uiYCoeffTableSize;
1247 pAVS_Params->piUVCoefsY = (int32_t*)ptr;
1248 }
1249
DestroyAVSParams(PMHW_AVS_PARAMS pAVS_Params)1250 void SfcRenderBase::DestroyAVSParams(
1251 PMHW_AVS_PARAMS pAVS_Params)
1252 {
1253 VP_FUNC_CALL();
1254
1255 VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(pAVS_Params);
1256 MOS_SafeFreeMemory(pAVS_Params->piYCoefsX);
1257 pAVS_Params->piYCoefsX = nullptr;
1258 }
1259
GetAvsLineBufferSize(bool lineTiledBuffer,bool b8tapChromafiltering,uint32_t width,uint32_t height)1260 uint32_t SfcRenderBase::GetAvsLineBufferSize(bool lineTiledBuffer, bool b8tapChromafiltering, uint32_t width, uint32_t height)
1261 {
1262 VP_FUNC_CALL();
1263
1264 uint32_t size = 0;
1265 uint32_t linebufferSizePerPixel = 0;
1266
1267 if (mhw::sfc::SFC_PIPE_MODE_VDBOX == m_pipeMode)
1268 {
1269 if (b8tapChromafiltering)
1270 {
1271 linebufferSizePerPixel = SFC_AVS_LINEBUFFER_SIZE_PER_PIXEL_8_TAP_8BIT;
1272 }
1273 else
1274 {
1275 linebufferSizePerPixel = SFC_AVS_LINEBUFFER_SIZE_PER_PIXEL_4_TAP_8BIT;
1276 }
1277 }
1278 else
1279 {
1280 // For vebox and hcp.
1281 if (b8tapChromafiltering)
1282 {
1283 linebufferSizePerPixel = SFC_AVS_LINEBUFFER_SIZE_PER_PIXEL_8_TAP_12BIT;
1284 }
1285 else
1286 {
1287 linebufferSizePerPixel = SFC_AVS_LINEBUFFER_SIZE_PER_PIXEL_4_TAP_12BIT;
1288 }
1289 }
1290
1291 // For VD+SFC mode, width needs be used. For VE+SFC mode, height needs be used.
1292 if (mhw::sfc::SFC_PIPE_MODE_VEBOX == m_pipeMode)
1293 {
1294 size = height * linebufferSizePerPixel;
1295 }
1296 else
1297 {
1298 // Align width to 8 for AVS buffer size compute according to VDBOX SFC requirement.
1299 size = MOS_ALIGN_CEIL(width, 8) * linebufferSizePerPixel;
1300 }
1301
1302 // For tile column storage, based on above calcuation, an extra 1K CL need to be added as a buffer.
1303 // size == 0 means line buffer not needed.
1304 if (lineTiledBuffer && size > 0)
1305 {
1306 size += 1024 * MHW_SFC_CACHELINE_SIZE;
1307 }
1308
1309 return size;
1310 }
1311
GetIefLineBufferSize(bool lineTiledBuffer,uint32_t heightOutput)1312 uint32_t SfcRenderBase::GetIefLineBufferSize(bool lineTiledBuffer, uint32_t heightOutput)
1313 {
1314 VP_FUNC_CALL();
1315
1316 uint32_t size = 0;
1317
1318 // For VE+SFC mode, height needs be used.
1319 if (mhw::sfc::SFC_PIPE_MODE_VEBOX == m_pipeMode)
1320 {
1321 size = heightOutput * SFC_IEF_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL;
1322 }
1323 else
1324 {
1325 return 0;
1326 }
1327
1328 // For tile column storage, based on above calcuation, an extra 1K CL need to be added as a buffer.
1329 // size == 0 means line buffer not needed.
1330 if (lineTiledBuffer && size > 0)
1331 {
1332 size += 1024 * MHW_SFC_CACHELINE_SIZE;
1333 }
1334
1335 return size;
1336 }
1337
GetSfdLineBufferSize(bool lineTiledBuffer,MOS_FORMAT formatOutput,uint32_t widthOutput,uint32_t heightOutput)1338 uint32_t SfcRenderBase::GetSfdLineBufferSize(bool lineTiledBuffer, MOS_FORMAT formatOutput, uint32_t widthOutput, uint32_t heightOutput)
1339 {
1340 VP_FUNC_CALL();
1341
1342 int size = 0;
1343
1344 // For VD+SFC mode, width needs be used. For VE+SFC mode, height needs be used.
1345 if (mhw::sfc::SFC_PIPE_MODE_VEBOX == m_pipeMode)
1346 {
1347 size = (VPHAL_COLORPACK_444 == VpHalDDIUtils::GetSurfaceColorPack(formatOutput)) ? 0 : (heightOutput * SFC_SFD_LINEBUFFER_SIZE_PER_PIXEL);
1348 }
1349 else
1350 {
1351 size = MOS_ROUNDUP_DIVIDE(widthOutput, 10) * SFC_CACHELINE_SIZE_IN_BYTES;
1352 size *= 2; //double for safe
1353 }
1354
1355 // For tile column storage, based on above calcuation, an extra 1K CL need to be added as a buffer.
1356 // size == 0 means line buffer not needed.
1357 if (lineTiledBuffer && size > 0)
1358 {
1359 size += 1024 * MHW_SFC_CACHELINE_SIZE;
1360 }
1361
1362 return size;
1363 }
1364
AllocateLineBuffer(VP_SURFACE * & lineBuffer,uint32_t size,const char * bufName)1365 MOS_STATUS SfcRenderBase::AllocateLineBuffer(VP_SURFACE *&lineBuffer, uint32_t size, const char *bufName)
1366 {
1367 VP_FUNC_CALL();
1368
1369 bool allocated = false;
1370 MEDIA_FEATURE_TABLE *skuTable = nullptr;
1371 Mos_MemPool memTypeSurfVideoMem = MOS_MEMPOOL_VIDEOMEMORY;
1372
1373 VP_PUBLIC_CHK_NULL_RETURN(m_osInterface)
1374
1375 skuTable = m_osInterface->pfnGetSkuTable(m_osInterface);
1376
1377 if (skuTable && MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
1378 {
1379 memTypeSurfVideoMem = MOS_MEMPOOL_DEVICEMEMORY;
1380 }
1381
1382 if (size)
1383 {
1384 VP_RENDER_CHK_STATUS_RETURN(m_allocator->ReAllocateSurface(
1385 lineBuffer,
1386 bufName,
1387 Format_Buffer,
1388 MOS_GFXRES_BUFFER,
1389 MOS_TILE_LINEAR,
1390 size,
1391 1,
1392 false,
1393 MOS_MMC_DISABLED,
1394 allocated,
1395 false,
1396 true,
1397 MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF,
1398 MOS_TILE_UNSET_GMM,
1399 memTypeSurfVideoMem,
1400 VPP_INTER_RESOURCE_NOTLOCKABLE));
1401 }
1402 else if (lineBuffer)
1403 {
1404 VP_RENDER_CHK_STATUS_RETURN(m_allocator->DestroyVpSurface(lineBuffer));
1405 }
1406 return MOS_STATUS_SUCCESS;
1407 }
1408
AllocateLineBufferArray(VP_SURFACE ** & lineBufferArray,uint32_t size,const char * bufName)1409 MOS_STATUS SfcRenderBase::AllocateLineBufferArray(VP_SURFACE **&lineBufferArray, uint32_t size, const char *bufName)
1410 {
1411 VP_FUNC_CALL();
1412
1413 bool allocated = false;
1414 VP_RENDER_CHK_NULL_RETURN(lineBufferArray);
1415 // Use numPipe instead of m_lineBufferAllocatedInArray to only allocate surface in use.
1416 for (int32_t i = 0; i < m_scalabilityParams.numPipe; ++i)
1417 {
1418 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBuffer(lineBufferArray[i], size, bufName));
1419 }
1420 return MOS_STATUS_SUCCESS;
1421 }
1422
AllocateResources()1423 MOS_STATUS SfcRenderBase::AllocateResources()
1424 {
1425 VP_FUNC_CALL();
1426
1427 uint32_t size;
1428
1429 VP_RENDER_CHK_NULL_RETURN(m_allocator);
1430 VP_RENDER_CHK_NULL_RETURN(m_renderData.sfcStateParams);
1431
1432 // for 1st pass of Sfc 2Pass case, use the standalone line buffer array to avoid line buffer reallocation
1433 if (m_renderData.b1stPassOfSfc2PassScaling)
1434 {
1435 if (m_scalabilityParams.numPipe > m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass ||
1436 nullptr == m_AVSLineBufferSurfaceArrayfor1stPassofSfc2Pass ||
1437 nullptr == m_IEFLineBufferSurfaceArrayfor1stPassofSfc2Pass ||
1438 nullptr == m_SFDLineBufferSurfaceArrayfor1stPassofSfc2Pass)
1439 {
1440 DestroyLineBufferArray(m_AVSLineBufferSurfaceArrayfor1stPassofSfc2Pass, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1441 DestroyLineBufferArray(m_IEFLineBufferSurfaceArrayfor1stPassofSfc2Pass, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1442 DestroyLineBufferArray(m_SFDLineBufferSurfaceArrayfor1stPassofSfc2Pass, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1443 m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass = m_scalabilityParams.numPipe;
1444 m_AVSLineBufferSurfaceArrayfor1stPassofSfc2Pass = MOS_NewArray(VP_SURFACE*, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1445 VP_RENDER_CHK_NULL_RETURN(m_AVSLineBufferSurfaceArrayfor1stPassofSfc2Pass);
1446 m_IEFLineBufferSurfaceArrayfor1stPassofSfc2Pass = MOS_NewArray(VP_SURFACE*, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1447 VP_RENDER_CHK_NULL_RETURN(m_IEFLineBufferSurfaceArrayfor1stPassofSfc2Pass);
1448 m_SFDLineBufferSurfaceArrayfor1stPassofSfc2Pass = MOS_NewArray(VP_SURFACE*, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1449 VP_RENDER_CHK_NULL_RETURN(m_SFDLineBufferSurfaceArrayfor1stPassofSfc2Pass);
1450 }
1451
1452 // for AVSLineBuffer, IEFLineBuffer and SFDLineBuffer, they are only needed when surface allocation bigger than 4150.
1453 // for AVSLineTileBuffer, IEFLineTileBuffer and SFDLineTileBuffer, they are only needed for VdBox SFC scalability case and not needed for VeBox SFC case.
1454
1455 // Allocate AVS Line Buffer surface----------------------------------------------
1456 size = GetAvsLineBufferSize(false, m_renderData.sfcStateParams->b8tapChromafiltering, m_renderData.sfcStateParams->dwInputFrameWidth, m_renderData.sfcStateParams->dwInputFrameHeight);
1457 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBufferArray(m_AVSLineBufferSurfaceArrayfor1stPassofSfc2Pass, size, "SfcAVSLineBufferSurfacefor1stPassofSfc2Pass"));
1458
1459 // Allocate IEF Line Buffer surface----------------------------------------------
1460 size = GetIefLineBufferSize(false, m_renderData.sfcStateParams->dwScaledRegionHeight);
1461 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBufferArray(m_IEFLineBufferSurfaceArrayfor1stPassofSfc2Pass, size, "SfcIEFLineBufferSurfacefor1stPassofSfc2Pass"));
1462
1463 if (m_bVdboxToSfc || m_renderData.sfcStateParams->dwScaledRegionHeight > SFC_LINEBUFEER_SIZE_LIMITED)
1464 {
1465 // Allocate SFD Line Buffer surface
1466 size = GetSfdLineBufferSize(false, m_renderData.sfcStateParams->OutputFrameFormat, m_renderData.sfcStateParams->dwScaledRegionWidth, m_renderData.sfcStateParams->dwScaledRegionHeight);
1467 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBufferArray(m_SFDLineBufferSurfaceArrayfor1stPassofSfc2Pass, size, "SfcSFDLineBufferSurfacefor1stPassofSfc2Pass"));
1468 }
1469 }
1470 else
1471 {
1472 if (m_scalabilityParams.numPipe > m_lineBufferAllocatedInArray ||
1473 nullptr == m_AVSLineBufferSurfaceArray ||
1474 nullptr == m_IEFLineBufferSurfaceArray ||
1475 nullptr == m_SFDLineBufferSurfaceArray)
1476 {
1477 DestroyLineBufferArray(m_AVSLineBufferSurfaceArray, m_lineBufferAllocatedInArray);
1478 DestroyLineBufferArray(m_IEFLineBufferSurfaceArray, m_lineBufferAllocatedInArray);
1479 DestroyLineBufferArray(m_SFDLineBufferSurfaceArray, m_lineBufferAllocatedInArray);
1480 m_lineBufferAllocatedInArray = m_scalabilityParams.numPipe;
1481 m_AVSLineBufferSurfaceArray = MOS_NewArray(VP_SURFACE*, m_lineBufferAllocatedInArray);
1482 VP_RENDER_CHK_NULL_RETURN(m_AVSLineBufferSurfaceArray);
1483 m_IEFLineBufferSurfaceArray = MOS_NewArray(VP_SURFACE*, m_lineBufferAllocatedInArray);
1484 VP_RENDER_CHK_NULL_RETURN(m_IEFLineBufferSurfaceArray);
1485 m_SFDLineBufferSurfaceArray = MOS_NewArray(VP_SURFACE*, m_lineBufferAllocatedInArray);
1486 VP_RENDER_CHK_NULL_RETURN(m_SFDLineBufferSurfaceArray);
1487 }
1488
1489 // for AVSLineBuffer, IEFLineBuffer and SFDLineBuffer, they are only needed when surface allocation bigger than 4150.
1490 // for AVSLineTileBuffer, IEFLineTileBuffer and SFDLineTileBuffer, they are only needed for VdBox SFC scalability case and not needed for VeBox SFC case.
1491
1492 // Allocate AVS Line Buffer surface----------------------------------------------
1493 size = GetAvsLineBufferSize(false, m_renderData.sfcStateParams->b8tapChromafiltering, m_renderData.sfcStateParams->dwInputFrameWidth, m_renderData.sfcStateParams->dwInputFrameHeight);
1494 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBufferArray(m_AVSLineBufferSurfaceArray, size, "SfcAVSLineBufferSurface"));
1495
1496 // Allocate IEF Line Buffer surface----------------------------------------------
1497 size = GetIefLineBufferSize(false, m_renderData.sfcStateParams->dwScaledRegionHeight);
1498 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBufferArray(m_IEFLineBufferSurfaceArray, size, "SfcIEFLineBufferSurface"));
1499
1500 if (m_bVdboxToSfc || m_renderData.sfcStateParams->dwScaledRegionHeight > SFC_LINEBUFEER_SIZE_LIMITED)
1501 {
1502 // Allocate SFD Line Buffer surface
1503 size = GetSfdLineBufferSize(false, m_renderData.sfcStateParams->OutputFrameFormat, m_renderData.sfcStateParams->dwScaledRegionWidth, m_renderData.sfcStateParams->dwScaledRegionHeight);
1504 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBufferArray(m_SFDLineBufferSurfaceArray, size, "SfcSFDLineBufferSurface"));
1505 }
1506 }
1507
1508 if (m_bVdboxToSfc)
1509 {
1510 // Allocate AVS Line Tile Buffer surface----------------------------------------------
1511 size = GetAvsLineBufferSize(true, m_renderData.sfcStateParams->b8tapChromafiltering, m_renderData.sfcStateParams->dwInputFrameWidth, m_renderData.sfcStateParams->dwInputFrameHeight);
1512 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBuffer(m_AVSLineTileBufferSurface, size, "SfcAVSLineTileBufferSurface"));
1513
1514 // Allocate IEF Line Tile Buffer surface----------------------------------------------
1515 size = GetIefLineBufferSize(true, m_renderData.sfcStateParams->dwScaledRegionHeight);
1516 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBuffer(m_IEFLineTileBufferSurface, size, "SfcIEFLineTileBufferSurface"));
1517
1518 // Allocate SFD Line Tile Buffer surface
1519 size = GetSfdLineBufferSize(true, m_renderData.sfcStateParams->OutputFrameFormat, m_renderData.sfcStateParams->dwScaledRegionWidth, m_renderData.sfcStateParams->dwScaledRegionHeight);
1520 VP_RENDER_CHK_STATUS_RETURN(AllocateLineBuffer(m_SFDLineTileBufferSurface, size, "SfcSFDLineTileBufferSurface"));
1521 }
1522 return MOS_STATUS_SUCCESS;
1523 }
1524
DestroyLineBufferArray(VP_SURFACE ** & lineBufferArray,int32_t count)1525 MOS_STATUS SfcRenderBase::DestroyLineBufferArray(VP_SURFACE **&lineBufferArray, int32_t count)
1526 {
1527 VP_FUNC_CALL();
1528
1529 if (nullptr == lineBufferArray)
1530 {
1531 return MOS_STATUS_SUCCESS;
1532 }
1533 // Use count instead of numPipe to destroy all surfaces.
1534 for (int32_t i = 0; i < count; ++i)
1535 {
1536 if (lineBufferArray[i])
1537 {
1538 m_allocator->DestroyVpSurface(lineBufferArray[i]);
1539 }
1540 }
1541 MOS_DeleteArray(lineBufferArray);
1542 return MOS_STATUS_SUCCESS;
1543 }
1544
FreeResources()1545 MOS_STATUS SfcRenderBase::FreeResources()
1546 {
1547 VP_FUNC_CALL();
1548
1549 VP_RENDER_CHK_NULL_RETURN(m_allocator);
1550 // Free AVS Line Buffer surface for SFC
1551 DestroyLineBufferArray(m_AVSLineBufferSurfaceArray, m_lineBufferAllocatedInArray);
1552
1553 // Free IEF Line Buffer surface for SFC
1554 DestroyLineBufferArray(m_IEFLineBufferSurfaceArray, m_lineBufferAllocatedInArray);
1555
1556 // Free SFD Line Buffer surface for SFC
1557 DestroyLineBufferArray(m_SFDLineBufferSurfaceArray, m_lineBufferAllocatedInArray);
1558
1559 // Free AVS Line Tile Buffer surface for SFC
1560 m_allocator->DestroyVpSurface(m_AVSLineTileBufferSurface);
1561
1562 // Free IEF Line Tile Buffer surface for SFC
1563 m_allocator->DestroyVpSurface(m_IEFLineTileBufferSurface);
1564
1565 // Free SFD Line Tile Buffer surface for SFC
1566 m_allocator->DestroyVpSurface(m_SFDLineTileBufferSurface);
1567
1568 // Free AVS Line Buffer surface for SFC 1st Pass of Sfc 2Pass
1569 DestroyLineBufferArray(m_AVSLineBufferSurfaceArrayfor1stPassofSfc2Pass, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1570
1571 // Free IEF Line Buffer surface for SFC 1st Pass of Sfc 2Pass
1572 DestroyLineBufferArray(m_IEFLineBufferSurfaceArrayfor1stPassofSfc2Pass, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1573
1574 // Free SFD Line Buffer surface for SFC 1st Pass of Sfc 2Pass
1575 DestroyLineBufferArray(m_SFDLineBufferSurfaceArrayfor1stPassofSfc2Pass, m_lineBufferAllocatedInArrayfor1stPassofSfc2Pass);
1576
1577 return MOS_STATUS_SUCCESS;
1578 }
1579
SetHistogramBuf(PMOS_BUFFER histogramBuf)1580 MOS_STATUS SfcRenderBase::SetHistogramBuf(PMOS_BUFFER histogramBuf)
1581 {
1582 VP_FUNC_CALL();
1583
1584 if (histogramBuf != nullptr)
1585 {
1586 m_histogramSurf.OsResource = histogramBuf->OsResource;
1587 }
1588
1589 return MOS_STATUS_SUCCESS;
1590 }
1591
AddSfcLock(PMOS_COMMAND_BUFFER pCmdBuffer,mhw::sfc::SFC_LOCK_PAR * sfcLockParams)1592 MOS_STATUS SfcRenderBase::AddSfcLock(
1593 PMOS_COMMAND_BUFFER pCmdBuffer,
1594 mhw::sfc::SFC_LOCK_PAR *sfcLockParams)
1595 {
1596 VP_FUNC_CALL();
1597
1598 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1599
1600 auto& params = m_sfcItf->MHW_GETPAR_F(SFC_LOCK)();
1601 params = *sfcLockParams;
1602
1603 // Send SFC_LOCK command to acquire SFC pipe for Vebox
1604 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->MHW_ADDCMD_F(SFC_LOCK)(pCmdBuffer));
1605
1606 return MOS_STATUS_SUCCESS;
1607 }
1608
AddSfcState(PMOS_COMMAND_BUFFER pCmdBuffer,mhw::sfc::SFC_STATE_PAR * pSfcStateParams,PMHW_SFC_OUT_SURFACE_PARAMS pOutSurface)1609 MOS_STATUS SfcRenderBase::AddSfcState(
1610 PMOS_COMMAND_BUFFER pCmdBuffer,
1611 mhw::sfc::SFC_STATE_PAR *pSfcStateParams,
1612 PMHW_SFC_OUT_SURFACE_PARAMS pOutSurface)
1613 {
1614 VP_FUNC_CALL();
1615
1616 VP_RENDER_CHK_NULL_RETURN(pSfcStateParams);
1617 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1618
1619 auto& params = m_sfcItf->MHW_GETPAR_F(SFC_STATE)();
1620 params = {};
1621 params = *pSfcStateParams;
1622 params.pOutSurface = pOutSurface;
1623
1624 // Send SFC_LOCK command to acquire SFC pipe for Vebox
1625 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->MHW_ADDCMD_F(SFC_STATE)(pCmdBuffer));
1626
1627 return MOS_STATUS_SUCCESS;
1628 }
1629
AddSfcAvsState(PMOS_COMMAND_BUFFER pCmdBuffer)1630 MOS_STATUS SfcRenderBase::AddSfcAvsState(
1631 PMOS_COMMAND_BUFFER pCmdBuffer)
1632 {
1633 VP_FUNC_CALL();
1634 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1635
1636 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->MHW_ADDCMD_F(SFC_AVS_STATE)(pCmdBuffer));
1637
1638 return MOS_STATUS_SUCCESS;
1639 }
1640
AddSfcIefState(PMOS_COMMAND_BUFFER pCmdBuffer)1641 MOS_STATUS SfcRenderBase::AddSfcIefState(
1642 PMOS_COMMAND_BUFFER pCmdBuffer)
1643 {
1644 VP_FUNC_CALL();
1645 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1646
1647 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->MHW_ADDCMD_F(SFC_IEF_STATE)(pCmdBuffer));
1648
1649 return MOS_STATUS_SUCCESS;
1650 }
1651
AddSfcAvsLumaTable(PMOS_COMMAND_BUFFER pCmdBuffer)1652 MOS_STATUS SfcRenderBase::AddSfcAvsLumaTable(
1653 PMOS_COMMAND_BUFFER pCmdBuffer)
1654 {
1655 VP_FUNC_CALL();
1656
1657 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1658
1659 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->MHW_ADDCMD_F(SFC_AVS_LUMA_Coeff_Table)(pCmdBuffer));
1660 return MOS_STATUS_SUCCESS;
1661 }
1662
AddSfcAvsChromaTable(PMOS_COMMAND_BUFFER pCmdBuffer)1663 MOS_STATUS SfcRenderBase::AddSfcAvsChromaTable(
1664 PMOS_COMMAND_BUFFER pCmdBuffer)
1665 {
1666 VP_FUNC_CALL();
1667 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1668
1669 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->MHW_ADDCMD_F(SFC_AVS_CHROMA_Coeff_Table)(pCmdBuffer));
1670
1671 return MOS_STATUS_SUCCESS;
1672 }
1673
AddSfcFrameStart(PMOS_COMMAND_BUFFER pCmdBuffer,uint8_t sfcPipeMode)1674 MOS_STATUS SfcRenderBase::AddSfcFrameStart(
1675 PMOS_COMMAND_BUFFER pCmdBuffer,
1676 uint8_t sfcPipeMode)
1677 {
1678 VP_FUNC_CALL();
1679 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1680
1681 auto& SfcFrameStartParams = m_sfcItf->MHW_GETPAR_F(SFC_FRAME_START)();
1682 SfcFrameStartParams = {};
1683 SfcFrameStartParams.sfcPipeMode = m_pipeMode;
1684 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->MHW_ADDCMD_F(SFC_FRAME_START)(pCmdBuffer));
1685 return MOS_STATUS_SUCCESS;
1686 }
1687
SetSfcAVSScalingMode(MHW_SCALING_MODE ScalingMode)1688 MOS_STATUS SfcRenderBase::SetSfcAVSScalingMode(
1689 MHW_SCALING_MODE ScalingMode)
1690 {
1691 VP_FUNC_CALL();
1692
1693 MOS_STATUS eStatus;
1694
1695 eStatus = MOS_STATUS_SUCCESS;
1696 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1697
1698 // Send SFC_FRAME_START command to start processing a frame
1699 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->SetSfcAVSScalingMode(
1700 ScalingMode));
1701
1702 return eStatus;
1703 }
1704
SetSfcSamplerTable(mhw::sfc::SFC_AVS_LUMA_Coeff_Table_PAR * pLumaTable,mhw::sfc::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)1705 MOS_STATUS SfcRenderBase::SetSfcSamplerTable(
1706 mhw::sfc::SFC_AVS_LUMA_Coeff_Table_PAR *pLumaTable,
1707 mhw::sfc::SFC_AVS_CHROMA_Coeff_Table_PAR *pChromaTable,
1708 PMHW_AVS_PARAMS pAvsParams,
1709 MOS_FORMAT SrcFormat,
1710 float fScaleX,
1711 float fScaleY,
1712 uint32_t dwChromaSiting,
1713 bool bUse8x8Filter,
1714 float fHPStrength,
1715 float fLanczosT)
1716 {
1717 VP_FUNC_CALL();
1718
1719 MOS_STATUS eStatus;
1720
1721 eStatus = MOS_STATUS_SUCCESS;
1722 VP_RENDER_CHK_NULL_RETURN(m_sfcItf);
1723 VP_RENDER_CHK_NULL_RETURN(pLumaTable);
1724 VP_RENDER_CHK_NULL_RETURN(pChromaTable);
1725 VP_RENDER_CHK_NULL_RETURN(pAvsParams);
1726
1727 // Send SFC_FRAME_START command to start processing a frame
1728 VP_RENDER_CHK_STATUS_RETURN(m_sfcItf->SetSfcSamplerTable(
1729 pLumaTable,
1730 pChromaTable,
1731 pAvsParams,
1732 SrcFormat,
1733 fScaleX,
1734 fScaleY,
1735 dwChromaSiting,
1736 bUse8x8Filter,
1737 fHPStrength,
1738 fLanczosT));
1739
1740 return eStatus;
1741 }
1742 }
1743