1 /*
2 * Copyright (c) 2011-2019, 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_renderer.cpp
24 //! \brief VPHAL top level rendering component and the entry to low level renderers
25 //! \details The top renderer is responsible for coordinating the sequence of calls to low level renderers, e.g. DNDI or Comp
26 //!
27 #include "vphal_renderer.h"
28 #include "vphal_debug.h"
29 #include "vpkrnheader.h"
30 #include "vphal_render_composite.h"
31
32 // Slice Shutdown User feature keys
33 #define VPHAL_SSD_CONTROL "SSD Control"
34
35 //==<FUNCTIONS>=================================================================
36
37 //!
38 //! \brief Initialize AVS parameters shared by Renderers
39 //! \details Initialize the members of the AVS parameter and allocate memory for its coefficient tables
40 //! \param [in,out] pAVS_Params
41 //! Pointer to MHW AVS parameter
42 //! \param [in] uiYCoeffTableSize
43 //! Size of the Y coefficient table
44 //! \param [in] uiUVCoeffTableSize
45 //! Size of the UV coefficient table
46 //! \return MOS_STATUS
47 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
48 //!
VpHal_RenderInitAVSParams(PMHW_AVS_PARAMS pAVS_Params,uint32_t uiYCoeffTableSize,uint32_t uiUVCoeffTableSize)49 MOS_STATUS VpHal_RenderInitAVSParams(
50 PMHW_AVS_PARAMS pAVS_Params,
51 uint32_t uiYCoeffTableSize,
52 uint32_t uiUVCoeffTableSize)
53 {
54 MOS_STATUS eStatus;
55 int32_t size;
56 char* ptr;
57
58 VPHAL_RENDER_ASSERT(pAVS_Params);
59 VPHAL_RENDER_ASSERT(uiYCoeffTableSize > 0);
60 VPHAL_RENDER_ASSERT(uiUVCoeffTableSize > 0);
61 eStatus = MOS_STATUS_SUCCESS;
62
63 // Init AVS parameters
64 pAVS_Params->Format = Format_None;
65 pAVS_Params->fScaleX = 0.0F;
66 pAVS_Params->fScaleY = 0.0F;
67 pAVS_Params->piYCoefsX = nullptr;
68
69 // Allocate AVS coefficients, One set each for X and Y
70 size = (uiYCoeffTableSize + uiUVCoeffTableSize) * 2;
71
72 ptr = (char*)MOS_AllocAndZeroMemory(size);
73 if (ptr == nullptr)
74 {
75 VPHAL_RENDER_ASSERTMESSAGE("No memory to allocate AVS coefficient tables.");
76 eStatus = MOS_STATUS_NO_SPACE;
77 goto finish;
78 }
79
80 pAVS_Params->piYCoefsX = (int32_t*)ptr;
81
82 ptr += uiYCoeffTableSize;
83 pAVS_Params->piUVCoefsX = (int32_t*)ptr;
84
85 ptr += uiUVCoeffTableSize;
86 pAVS_Params->piYCoefsY = (int32_t*)ptr;
87
88 ptr += uiYCoeffTableSize;
89 pAVS_Params->piUVCoefsY = (int32_t*)ptr;
90
91 finish:
92 return eStatus;
93 }
94
95 //!
96 //! \brief Destroy AVS parameters shared by Renderers
97 //! \details Free the memory of AVS parameter's coefficient tables
98 //! \param [in,out] pAVS_Params
99 //! Pointer to VPHAL AVS parameter
100 //! \return void
101 //!
VpHal_RenderDestroyAVSParams(PMHW_AVS_PARAMS pAVS_Params)102 void VpHal_RenderDestroyAVSParams(
103 PMHW_AVS_PARAMS pAVS_Params)
104 {
105 MOS_SafeFreeMemory(pAVS_Params->piYCoefsX);
106 pAVS_Params->piYCoefsX = nullptr;
107 }
108
109 //!
110 //! \brief Get the size in byte from that in pixel
111 //! \details Size_in_byte = size_in_pixel x byte/pixel
112 //! \param [in] pOsInterface
113 //! Pointer to OS interface
114 //! \param [in] Format
115 //! The format which determines the value of byte/pixel
116 //! \param [in] dwPixels
117 //! The size in pixel
118 //! \return uint32_t
119 //! Return the size in byte
120 //!
VpHal_PixelsToBytes(PMOS_INTERFACE pOsInterface,MOS_FORMAT Format,uint32_t dwPixels)121 uint32_t VpHal_PixelsToBytes(
122 PMOS_INTERFACE pOsInterface,
123 MOS_FORMAT Format,
124 uint32_t dwPixels)
125 {
126 MOS_STATUS eStatus;
127 uint32_t iBpp;
128 uint32_t dwBpp;
129
130 eStatus = MOS_STATUS_SUCCESS;
131 dwBpp = 0;
132 VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetBitsPerPixel(pOsInterface, Format, &iBpp));
133 dwBpp = dwPixels * (iBpp>>3);
134
135 finish:
136 return dwBpp;
137 }
138
139 //!
140 //! \brief Save/Restore fwd references for the primary
141 //! \details Based on the flag passed in to save or restore the forward references
142 //! of the primary
143 //! \param [in,out] pRenderer
144 //! VPHAL renderer pointer
145 //! \param [in,out] pPrimarySurf
146 //! Pointer to the primary surface
147 //! \param [in] bSave
148 //! Save - true or restore - false the fwd references
149 //! \return void
150 //!
VpHal_SaveRestorePrimaryFwdRefs(VphalRenderer * pRenderer,PVPHAL_SURFACE pPrimarySurf,bool bSave)151 void VpHal_SaveRestorePrimaryFwdRefs(
152 VphalRenderer *pRenderer,
153 PVPHAL_SURFACE pPrimarySurf,
154 bool bSave)
155 {
156 PVPHAL_SURFACE pFwdRef;
157 uint32_t uiSources;
158 uint32_t uiIndex;
159
160 VPHAL_RENDER_ASSERT(pRenderer);
161 VPHAL_RENDER_ASSERT(pPrimarySurf && (pPrimarySurf->SurfType == SURF_IN_PRIMARY));
162
163 pFwdRef = nullptr;
164 uiSources = 0;
165 uiIndex = 0;
166
167 if (bSave)
168 {
169 pFwdRef = pPrimarySurf->pFwdRef;
170
171 while(pFwdRef)
172 {
173 pRenderer->pPrimaryFwdRef[uiIndex] = pFwdRef;
174 pFwdRef = pFwdRef->pFwdRef;
175 uiIndex++;
176 if (uiIndex >= VPHAL_MAX_FUTURE_FRAMES)
177 {
178 break;
179 }
180 }
181 }
182 else
183 {
184 pFwdRef = pPrimarySurf;
185
186 while (pRenderer->pPrimaryFwdRef[uiIndex])
187 {
188 pFwdRef->pFwdRef = pRenderer->pPrimaryFwdRef[uiIndex];
189 pRenderer->pPrimaryFwdRef[uiIndex] = nullptr;
190 pFwdRef = pFwdRef->pFwdRef;
191 uiIndex++;
192 if (uiIndex >= VPHAL_MAX_FUTURE_FRAMES)
193 {
194 break;
195 }
196 }
197 }
198 }
199
200 //!
201 //! \brief Align the src/dst surface rectangle and surface width/height
202 //! \details The surface rects and width/height need to be aligned according to the surface format
203 //! \param [in,out] pSurface
204 //! Pointer to the surface
205 //! \param [in] formatForDstRect
206 //! Format for Dst Rect
207 //! \return MOS_STATUS
208 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
209 //!
VpHal_RndrRectSurfaceAlignment(PVPHAL_SURFACE pSurface,MOS_FORMAT formatForDstRect)210 MOS_STATUS VpHal_RndrRectSurfaceAlignment(
211 PVPHAL_SURFACE pSurface,
212 MOS_FORMAT formatForDstRect)
213 {
214 uint16_t wWidthAlignUnit;
215 uint16_t wHeightAlignUnit;
216 uint16_t wWidthAlignUnitForDstRect;
217 uint16_t wHeightAlignUnitForDstRect;
218 MOS_STATUS eStatus;
219
220 eStatus = MOS_STATUS_SUCCESS;
221
222 VpHal_RndrGetAlignUnit(&wWidthAlignUnit, &wHeightAlignUnit, pSurface->Format);
223 VpHal_RndrGetAlignUnit(&wWidthAlignUnitForDstRect, &wHeightAlignUnitForDstRect, formatForDstRect);
224
225 // The source rectangle is floored to the aligned unit to
226 // get rid of invalid data(ex: an odd numbered src rectangle with NV12 format
227 // will have invalid UV data for the last line of Y data).
228 pSurface->rcSrc.bottom = MOS_ALIGN_FLOOR((uint32_t)pSurface->rcSrc.bottom, wHeightAlignUnit);
229 pSurface->rcSrc.right = MOS_ALIGN_FLOOR((uint32_t)pSurface->rcSrc.right, wWidthAlignUnit);
230
231 pSurface->rcSrc.top = MOS_ALIGN_CEIL((uint32_t)pSurface->rcSrc.top, wHeightAlignUnit);
232 pSurface->rcSrc.left = MOS_ALIGN_CEIL((uint32_t)pSurface->rcSrc.left, wWidthAlignUnit);
233
234 // The Destination rectangle is rounded to the upper alignment unit to prevent the loss of
235 // data which was present in the source rectangle
236 pSurface->rcDst.bottom = MOS_ALIGN_CEIL((uint32_t)pSurface->rcDst.bottom, wHeightAlignUnitForDstRect);
237 pSurface->rcDst.right = MOS_ALIGN_CEIL((uint32_t)pSurface->rcDst.right, wWidthAlignUnitForDstRect);
238
239 pSurface->rcDst.top = MOS_ALIGN_FLOOR((uint32_t)pSurface->rcDst.top, wHeightAlignUnitForDstRect);
240 pSurface->rcDst.left = MOS_ALIGN_FLOOR((uint32_t)pSurface->rcDst.left, wWidthAlignUnitForDstRect);
241
242 if (pSurface->SurfType == SURF_OUT_RENDERTARGET)
243 {
244 pSurface->dwHeight = MOS_ALIGN_CEIL(pSurface->dwHeight, wHeightAlignUnit);
245 pSurface->dwWidth = MOS_ALIGN_CEIL(pSurface->dwWidth, wWidthAlignUnit);
246 }
247 else
248 {
249 pSurface->dwHeight = MOS_ALIGN_FLOOR(pSurface->dwHeight, wHeightAlignUnit);
250 pSurface->dwWidth = MOS_ALIGN_FLOOR(pSurface->dwWidth, wWidthAlignUnit);
251 }
252
253 if ((pSurface->rcSrc.top == pSurface->rcSrc.bottom) ||
254 (pSurface->rcSrc.left == pSurface->rcSrc.right) ||
255 (pSurface->rcDst.top == pSurface->rcDst.bottom) ||
256 (pSurface->rcDst.left == pSurface->rcDst.right) ||
257 (pSurface->dwWidth == 0) ||
258 (pSurface->dwHeight == 0))
259 {
260 VPHAL_RENDER_ASSERTMESSAGE("Surface Parameter is invalid.");
261 eStatus = MOS_STATUS_INVALID_PARAMETER;
262 }
263
264 return eStatus;
265 }
266
267 //!
268 //! \brief Prepare input surface list for top level render processing
269 //! \details Prepare the inputs, e.g. adjust src/dst rectangles of stereo input or allocate
270 //! and copy intermediate surfaces.
271 //! \param [in,out] pRenderParams
272 //! Pointer to VPHAL render parameter
273 //! \param [in,out] pSrcLeft
274 //! Pointer to left frame list
275 //! \param [in,out] pSrcRight
276 //! Pointer to right frame list
277 //! \param [out] puiRenderPasses
278 //! Pointer to times of the rendering.
279 //! The value is 2 for S3D and 1 for the other cases.
280 //! \return MOS_STATUS
281 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
282 //!
PrepareSources(PVPHAL_RENDER_PARAMS pRenderParams,PVPHAL_SURFACE * pSrcLeft,PVPHAL_SURFACE * pSrcRight,uint32_t * puiRenderPasses)283 MOS_STATUS VphalRenderer::PrepareSources(
284 PVPHAL_RENDER_PARAMS pRenderParams,
285 PVPHAL_SURFACE *pSrcLeft,
286 PVPHAL_SURFACE *pSrcRight,
287 uint32_t *puiRenderPasses)
288 {
289 MOS_STATUS eStatus;
290 PVPHAL_SURFACE pcSrc;
291 uint32_t uiLeftCount;
292 uint32_t uiRightCount;
293 uint32_t uiSources;
294 uint32_t uiTargets;
295 uint32_t uiIndex;
296 PMOS_RESOURCE ppSource[VPHAL_MAX_SOURCES] = { nullptr };
297 PMOS_RESOURCE ppTarget[VPHAL_MAX_TARGETS] = { nullptr };
298 eStatus = MOS_STATUS_SUCCESS;
299 uiLeftCount = 0;
300 uiRightCount = 0;
301 uiIndex = 0;
302 uiSources = 0;
303 uiTargets = 0;
304
305 VPHAL_RENDER_CHK_NULL(m_pOsInterface);
306
307 for (uiSources=0, uiIndex=0;
308 (uiIndex < pRenderParams->uSrcCount) && (uiIndex < VPHAL_MAX_SOURCES);
309 uiIndex++)
310 {
311 pcSrc = pRenderParams->pSrc[uiIndex];
312
313 if (pcSrc == nullptr)
314 {
315 continue;
316 }
317
318 ppSource[uiSources] = &pcSrc->OsResource;
319
320 pSrcLeft[uiLeftCount++] = pcSrc;
321
322 uiSources++;
323 }
324
325 //gather render target list
326 for (uiTargets = 0, uiIndex = 0;
327 (uiIndex < pRenderParams->uDstCount) && (uiIndex < VPHAL_MAX_TARGETS);
328 uiIndex++)
329 {
330 pcSrc = pRenderParams->pTarget[uiIndex];
331
332 if (pcSrc)
333 {
334 ppTarget[uiTargets] = &pcSrc->OsResource;
335 uiTargets++;
336 }
337 }
338
339 VPHAL_RENDER_ASSERT(uiRightCount == 0);
340
341 pRenderParams->uSrcCount = uiLeftCount;
342 *puiRenderPasses = 1;
343
344 finish:
345 VPHAL_RENDER_ASSERT(eStatus == MOS_STATUS_SUCCESS);
346
347 if ((nullptr != m_pOsInterface) && (nullptr != m_pOsInterface->osCpInterface))
348 {
349 eStatus = m_pOsInterface->osCpInterface->PrepareResources(
350 (void **)ppSource, uiSources,
351 (void **)ppTarget, uiTargets);
352 }
353 return eStatus;
354 }
355
356 //!
357 //! \brief Get surface info for all input source
358 //! \details Get surface info for the input surface and its reference surfaces
359 //! \param [in] pRenderParams
360 //! Pointer to VPHAL render parameter
361 //! \return MOS_STATUS
362 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
363 //!
GetSurfaceInfoForSrc(PVPHAL_RENDER_PARAMS pRenderParams)364 MOS_STATUS VphalRenderer::GetSurfaceInfoForSrc(
365 PVPHAL_RENDER_PARAMS pRenderParams)
366 {
367 MOS_STATUS eStatus;
368 PVPHAL_SURFACE pSrcSurface; // Current source surface
369 PVPHAL_SURFACE pSurface; // Ptr to surface
370 uint32_t uiSources; // Number of Sources
371 uint32_t uiIndex; // Current source index
372 uint32_t i;
373 VPHAL_GET_SURFACE_INFO Info;
374
375 eStatus = MOS_STATUS_SUCCESS;
376 pSrcSurface = nullptr;
377
378 // Loop through the sources
379 for (uiSources = 0, uiIndex = 0;
380 uiSources < pRenderParams->uSrcCount && uiIndex < VPHAL_MAX_SOURCES;
381 uiIndex++)
382 {
383 pSrcSurface = pRenderParams->pSrc[uiIndex];
384
385 if (pSrcSurface == nullptr)
386 {
387 continue;
388 }
389 uiSources++;
390
391 if (Mos_ResourceIsNull(&pSrcSurface->OsResource))
392 {
393 VPHAL_RENDER_ASSERTMESSAGE("Input resource is not valid.");
394 eStatus = MOS_STATUS_UNKNOWN;
395 goto finish;
396 }
397
398 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
399
400 VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
401 m_pOsInterface,
402 &Info,
403 pSrcSurface));
404
405 // Get resource info for Backward References, if any
406 pSurface = pSrcSurface->pBwdRef;
407 for (i = 0; i < pSrcSurface->uBwdRefCount; i++)
408 {
409 VPHAL_RENDER_ASSERT(pSurface); // Must have valid reference pointer
410 if (pSurface)
411 {
412 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
413
414 VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
415 m_pOsInterface,
416 &Info,
417 pSurface));
418
419 // point to the next bwd ref
420 pSurface = pSurface->pBwdRef;
421 }
422 }
423
424 // Get resource info for Forward References, if any
425 pSurface = pSrcSurface->pFwdRef;
426 for (i = 0; i < pSrcSurface->uFwdRefCount; i++)
427 {
428 VPHAL_RENDER_ASSERT(pSurface); // Must have valid reference pointer
429 if (pSurface)
430 {
431 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
432
433 VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
434 m_pOsInterface,
435 &Info,
436 pSurface));
437
438 // point to the next fwd ref
439 pSurface = pSurface->pFwdRef;
440 }
441 }
442 }
443
444 finish:
445 return eStatus;
446 }
447
448 //!
449 //! \brief Adjust surface parameter
450 //! \param [in] pRenderParams
451 //! Pointer to VPHAL render parameter
452 //! \param [in,out] pSrcSurface
453 //! Pointer to VPHAL surface
454 //! \param [in] pGtSystemInfo
455 //! Pointer to GT system information structure
456 //! \param [in] bHybridDecoderFlag
457 //! Hybrid Decoder or not
458 //! \return MOS_STATUS
459 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
460 //!
AdjustSurfaceParam(PVPHAL_RENDER_PARAMS pRenderParams,PVPHAL_SURFACE pSrcSurface,MEDIA_SYSTEM_INFO * pGtSystemInfo,bool bHybridDecoderFlag)461 MOS_STATUS VphalRenderer::AdjustSurfaceParam(
462 PVPHAL_RENDER_PARAMS pRenderParams,
463 PVPHAL_SURFACE pSrcSurface,
464 MEDIA_SYSTEM_INFO *pGtSystemInfo,
465 bool bHybridDecoderFlag)
466 {
467 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
468
469 VPHAL_RENDER_CHK_NULL(pSrcSurface);
470 VPHAL_RENDER_CHK_NULL(pRenderParams);
471 VPHAL_RENDER_CHK_NULL(pGtSystemInfo);
472
473 // Disable VP features for 4K (Sku flag or Hybrid)
474 if (pSrcSurface->rcSrc.bottom >= pSrcSurface->rcSrc.top + VPHAL_RNDR_4K_HEIGHT)
475 {
476 // VEBOX timing on KBL ULT might be about 2x ms when DN is on, and it seems to be
477 // in relation to the lag problem on WMP after scaling up & down the playback window.
478 // Disable DN for 4K to resolve this phenomenon.
479 if (bSkuDisableDNFor4K &&
480 pSrcSurface->pDenoiseParams)
481 {
482 pSrcSurface->pDenoiseParams->bAutoDetect = false;
483 pSrcSurface->pDenoiseParams->bEnableChroma = false;
484 pSrcSurface->pDenoiseParams->bEnableLuma = false;
485 }
486
487 // Disable features if needed
488 if (bSkuDisableVpFor4K || bHybridDecoderFlag)
489 {
490 // Denoise
491 if (pSrcSurface->pDenoiseParams)
492 {
493 pSrcSurface->pDenoiseParams->bAutoDetect = false;
494 pSrcSurface->pDenoiseParams->bEnableChroma = false;
495 pSrcSurface->pDenoiseParams->bEnableLuma = false;
496 }
497
498 // Sharpness(IEF)
499 if (pSrcSurface->pIEFParams)
500 {
501 pSrcSurface->pIEFParams->bEnabled = false;
502 }
503
504 // STE, TCC
505 if (pSrcSurface->pColorPipeParams)
506 {
507 pSrcSurface->pColorPipeParams->bEnableSTE = false;
508 pSrcSurface->pColorPipeParams->bEnableTCC = false;
509 }
510 }
511 }
512
513 // IEF is only for Y luma component
514 if (IS_RGB_FORMAT(pSrcSurface->Format) && pSrcSurface->pIEFParams)
515 {
516 VPHAL_RENDER_NORMALMESSAGE("IEF is only for Y luma component, and IEF is always disabled for RGB input.");
517 pSrcSurface->pIEFParams->bEnabled = false;
518 pSrcSurface->pIEFParams->fIEFFactor = 0.0f;
519 }
520
521 finish:
522 return eStatus;
523 }
524
525 //!
526 //! \brief Process render parameter
527 //! \param [in,out] pRenderParams
528 //! Pointer to VPHAL render parameter
529 //! \param [in,out] pRenderPassData
530 //! Pointer to the VPHAL render pass data
531 //! \return MOS_STATUS
532 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
533 //!
ProcessRenderParameter(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)534 MOS_STATUS VphalRenderer::ProcessRenderParameter(
535 PVPHAL_RENDER_PARAMS pRenderParams,
536 RenderpassData *pRenderPassData)
537 {
538 MOS_STATUS eStatus;
539 MEDIA_SYSTEM_INFO *pGtSystemInfo;
540 uint32_t uiIndex;
541 PVPHAL_SURFACE pSrcSurface;
542 PVPHAL_SURFACE pPrimarySurface;
543 PVPHAL_PROCAMP_PARAMS pProcampParams;
544 bool bSingleSliceMode;
545 bool bSliceReconfig;
546 bool bHybridDecoderFlag;
547 int32_t decoderFlag;
548
549 #ifdef ANDROID
550 RECT PrimOrigDstRect;
551 bool bDstRectWANeeded = false;
552 #endif
553
554 eStatus = MOS_STATUS_SUCCESS;
555 bHybridDecoderFlag = false;
556 bSliceReconfig = false;
557 pPrimarySurface = nullptr;
558
559 // Get the hybrid decoder flag
560 VPHAL_RENDER_CHK_STATUS(m_pOsInterface->pfnGetHybridDecoderRunningFlag(m_pOsInterface, &decoderFlag));
561 bHybridDecoderFlag = decoderFlag ? true : false;
562
563 // Get the GT system information
564 pGtSystemInfo = m_pOsInterface->pfnGetGtSystemInfo(m_pOsInterface);
565 VPHAL_RENDER_CHK_NULL(pGtSystemInfo);
566
567 pRender[VPHAL_RENDER_ID_COMPOSITE]->SetStatusReportParams(this, pRenderParams);
568 pRender[VPHAL_RENDER_ID_VEBOX+uiCurrentChannel]->SetStatusReportParams(this, pRenderParams);
569
570 // Decide whether Hdr path should be chosen.
571 VPHAL_RENDER_CHK_STATUS(GetHdrPathNeededFlag(pRenderParams, pRenderPassData));
572 if (pRenderPassData->bHdrNeeded)
573 {
574 VPHAL_RNDR_SET_STATUS_REPORT_PARAMS(pHdrState, this, pRenderParams);
575 }
576
577 VPHAL_RNDR_SET_STATUS_REPORT_PARAMS(&Align16State, this, pRenderParams);
578 // Loop through the sources
579 for (uiIndex = 0;
580 uiIndex < VPHAL_MAX_SOURCES && uiIndex < pRenderParams->uSrcCount;
581 uiIndex++)
582 {
583 pSrcSurface = pRenderParams->pSrc[uiIndex];
584
585 if (pSrcSurface == nullptr)
586 {
587 continue;
588 }
589
590 // We need to block invalid frame sizes of 0 or negative values from
591 // entering the VP render core since IVB hardware had problem of
592 // handling these cases. EU payload of the same values, U, V,
593 // deltaU, deltaV, are all 0s, and are the same for 16 thread entries,
594 // which will be discarded by the kernel.
595 if ((pSrcSurface->rcSrc.top >= pSrcSurface->rcSrc.bottom) ||
596 (pSrcSurface->rcSrc.left >= pSrcSurface->rcSrc.right) ||
597 (pSrcSurface->rcDst.top >= pSrcSurface->rcDst.bottom) ||
598 (pSrcSurface->rcDst.left >= pSrcSurface->rcDst.right))
599 {
600 eStatus = MOS_STATUS_INVALID_PARAMETER;
601 VPHAL_RENDER_ASSERTMESSAGE("Invalid Rectangle Values.");
602 goto finish;
603 }
604
605 #ifdef ANDROID
606 // If the dst rect of primary layer is exactly covered by sublayers, say primary.left == sublayer.left,
607 // the primary layer should not be seen from the left side. But VpHal_RndrRectSurfaceAlignment() might adjust
608 // the primary layer dst rect for alignment. It looks like the primary layer is shifted left for one or two pixels,
609 // and user will see a thin line on the left side, which is a bad user experience.
610 // In such cases, just make the sublayer's dst rect still aligned with primary layer.
611 if (bDstRectWANeeded)
612 {
613 pSrcSurface->rcDst.left = (pSrcSurface->rcDst.left == PrimOrigDstRect.left ) ? pPrimarySurface->rcDst.left : pSrcSurface->rcDst.left;
614 pSrcSurface->rcDst.top = (pSrcSurface->rcDst.top == PrimOrigDstRect.top ) ? pPrimarySurface->rcDst.top : pSrcSurface->rcDst.top;
615 pSrcSurface->rcDst.right = (pSrcSurface->rcDst.right == PrimOrigDstRect.right ) ? pPrimarySurface->rcDst.right : pSrcSurface->rcDst.right;
616 pSrcSurface->rcDst.bottom = (pSrcSurface->rcDst.bottom == PrimOrigDstRect.bottom) ? pPrimarySurface->rcDst.bottom : pSrcSurface->rcDst.bottom;
617 }
618 #endif
619
620 if (pSrcSurface->SurfType == SURF_IN_PRIMARY)
621 {
622 #ifdef ANDROID
623 bDstRectWANeeded = true;
624 PrimOrigDstRect = pSrcSurface->rcDst;
625 #endif
626 pRenderPassData->pPrimarySurface = pPrimarySurface = pSrcSurface;
627 pRenderPassData->uiPrimaryIndex = uiIndex;
628
629 // align rectangle and source surface
630 VPHAL_RENDER_CHK_STATUS(VpHal_RndrRectSurfaceAlignment(pSrcSurface, pRenderParams->pTarget[0] ? pRenderParams->pTarget[0]->Format : pSrcSurface->Format));
631
632 // update max Src rect in both pRenderer and primary surface
633 VpHal_RenderInitMaxRect(this, pSrcSurface);
634 }
635
636 // Add Procamp limitation before Render pass selected
637 // Brightness[-100.0,100.0], Contrast & Saturation[0.0,10.0]
638 pProcampParams = pSrcSurface->pProcampParams;
639 if (pProcampParams && pProcampParams->bEnabled)
640 {
641 pProcampParams->fBrightness = MOS_MIN(MOS_MAX(-100.0f, pProcampParams->fBrightness), 100.0f);
642 pProcampParams->fContrast = MOS_MIN(MOS_MAX( 0.0f, pProcampParams->fContrast), 10.0f);
643 pProcampParams->fSaturation = MOS_MIN(MOS_MAX( 0.0f, pProcampParams->fSaturation), 10.0f);
644 }
645
646 AdjustSurfaceParam(pRenderParams, pSrcSurface, pGtSystemInfo, bHybridDecoderFlag);
647 }
648
649 // Check if Slice Shutdown can be enabled
650 // Vebox performance is not impacted by slice shutdown
651 if (!(pPrimarySurface == nullptr || // Valid Layer
652 pRenderPassData->bHdrNeeded || // HDR Disabled
653 pRenderParams->Component == COMPONENT_VPreP)) // VpostP usage
654 {
655 bSliceReconfig = true;
656 }
657
658 // Check if Slice Shutdown can be enabled
659 if ((uiSsdControl == VPHAL_SSD_ENABLE) || // Force Enable in User feature keys
660 (bSliceReconfig && // Default mode
661 uiSsdControl == VPHAL_SSD_DEFAULT))
662 {
663 bSingleSliceMode = true;
664 }
665 else
666 {
667 bSingleSliceMode = false;
668 }
669
670 pRender[VPHAL_RENDER_ID_COMPOSITE]->SetSingleSliceMode(bSingleSliceMode);
671
672 finish:
673 return eStatus;
674 }
675
676 //!
677 //! \brief Render function for the pass
678 //! \details The render function coordinates the advanced renderers and basic
679 //! renders in one pass
680 //! \param [in,out] pRenderParams
681 //! Pointer to VPHAL render parameter
682 //! \return MOS_STATUS
683 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
684 //!
RenderPass(PVPHAL_RENDER_PARAMS pRenderParams)685 MOS_STATUS VphalRenderer::RenderPass(
686 PVPHAL_RENDER_PARAMS pRenderParams)
687 {
688 MOS_STATUS eStatus;
689 uint32_t uiIndex_in; // Current source index
690 uint32_t uiIndex_out; // current target index
691 PVPHAL_VEBOX_EXEC_STATE pVeboxExecState;
692 RenderpassData RenderPassData;
693
694 VPHAL_RENDER_ASSERT(m_pRenderHal);
695
696 eStatus = MOS_STATUS_SUCCESS;
697 uiIndex_in = 0;
698 uiIndex_out = 0;
699 pVeboxExecState = &VeboxExecState[uiCurrentChannel];
700 MOS_ZeroMemory(&RenderPassData, sizeof(RenderPassData));
701
702 RenderPassData.AllocateTempOutputSurfaces();
703 RenderPassData.bCompNeeded = true;
704
705 // Get surface info for all input source
706 VPHAL_RENDER_CHK_STATUS(GetSurfaceInfoForSrc(pRenderParams));
707
708 // Process render parameters
709 VPHAL_RENDER_CHK_STATUS(ProcessRenderParameter(pRenderParams, &RenderPassData));
710
711 // Loop through the sources
712 for (uiIndex_in = 0; uiIndex_in < pRenderParams->uSrcCount; uiIndex_in++)
713 {
714 if (pRenderParams->pSrc[uiIndex_in] == nullptr)
715 {
716 continue;
717 }
718
719 //------------------------------------------
720 VPHAL_RNDR_DUMP_SURF(
721 this, uiIndex_in, VPHAL_DBG_DUMP_TYPE_PRE_ALL, pRenderParams->pSrc[uiIndex_in]);
722 //------------------------------------------
723
724 RenderPassData.pOriginalSrcSurface = pRenderParams->pSrc[uiIndex_in];
725 RenderPassData.pSrcSurface = pRenderParams->pSrc[uiIndex_in];
726 RenderPassData.uiSrcIndex = uiIndex_in;
727
728 if (VpHal_RndrIsFast1toNSupport(&Fast1toNState, pRenderParams, pRenderParams->pSrc[uiIndex_in]))
729 {
730 // new 1toN path for multi ouput with scaling only case.
731 VPHAL_RENDER_NORMALMESSAGE("Enter fast 1to N render.");
732 VPHAL_RENDER_CHK_STATUS(RenderFast1toNComposite(pRenderParams, &RenderPassData));
733 }
734 else
735 {
736 // loop through the dst for every src input.
737 // backup the render params to execute as dst_count=1 to compatible with legacy logic.
738 VPHAL_RENDER_PARAMS StoreRenderParams = *pRenderParams;
739 pRenderParams->uDstCount = 1;
740 for (uiIndex_out = 0; uiIndex_out < StoreRenderParams.uDstCount; uiIndex_out++)
741 {
742 if (StoreRenderParams.pTarget[uiIndex_out] == nullptr)
743 {
744 continue;
745 }
746 // update the first target point
747 pRenderParams->pTarget[0] = StoreRenderParams.pTarget[uiIndex_out];
748 pRenderParams->pTarget[0]->b16UsrPtr = StoreRenderParams.pTarget[uiIndex_out]->b16UsrPtr;
749 if (StoreRenderParams.uDstCount > 1)
750 {
751 // for multi output, support different scaling ratio but doesn't support cropping.
752 RenderPassData.pSrcSurface->rcDst.top = pRenderParams->pTarget[0]->rcSrc.top;
753 RenderPassData.pSrcSurface->rcDst.left = pRenderParams->pTarget[0]->rcSrc.left;
754 RenderPassData.pSrcSurface->rcDst.bottom = pRenderParams->pTarget[0]->rcSrc.bottom;
755 RenderPassData.pSrcSurface->rcDst.right = pRenderParams->pTarget[0]->rcSrc.right;
756 }
757
758 RenderSingleStream(pRenderParams, &RenderPassData);
759
760 if (!RenderPassData.bCompNeeded &&
761 pRenderParams->pTarget[0] &&
762 pRenderParams->pTarget[0]->bFastColorFill)
763 {
764 // with fast color fill enabled, we seperate target surface into two parts:
765 // (1) upper rectangle rendered by vebox
766 // (2) bottom rectangle with back ground color fill by composition
767 pRenderParams->uSrcCount = 0; // set to zero for color fill
768 pRenderParams->pTarget[0]->rcDst.top = pRenderParams->pSrc[0]->rcDst.bottom;
769 RenderPassData.bCompNeeded = true;
770 VPHAL_RENDER_ASSERTMESSAGE("Critical: enter fast color fill");
771 }
772 if (RenderPassData.bCompNeeded &&
773 (uiIndex_in == pRenderParams->uSrcCount-1 || // compatible with N:1 case, only render at the last input.
774 pRenderParams->uSrcCount == 0)) // fast color fill
775 {
776 VPHAL_RENDER_CHK_STATUS(RenderComposite(pRenderParams, &RenderPassData));
777 }
778 else if (VpHal_RndrIsHdrPathNeeded(this, pRenderParams, &RenderPassData) &&
779 (pHdrState &&
780 !pHdrState->bBypassHdrKernelPath))
781 {
782 VPHAL_RENDER_CHK_STATUS(VpHal_RndrRenderHDR(this, pRenderParams, &RenderPassData));
783 }
784 }
785 // restore render pointer and count.
786 pRenderParams->pTarget[0] = StoreRenderParams.pTarget[0];
787 pRenderParams->pTarget[0]->b16UsrPtr = StoreRenderParams.pTarget[0]->b16UsrPtr;
788 pRenderParams->uDstCount = StoreRenderParams.uDstCount;
789 }
790 }
791
792 // Report Render modes
793 UpdateReport(pRenderParams, &RenderPassData);
794
795 //------------------------------------------
796 VPHAL_RNDR_DUMP_SURF_PTR_ARRAY(
797 this, pRenderParams->pTarget, VPHAL_MAX_TARGETS,
798 pRenderParams->uDstCount, VPHAL_DBG_DUMP_TYPE_POST_ALL);
799 //------------------------------------------
800
801 if (RenderPassData.pPrimarySurface)
802 {
803 VpHal_SaveRestorePrimaryFwdRefs(
804 this,
805 pRenderParams->pSrc[RenderPassData.uiPrimaryIndex] = RenderPassData.pPrimarySurface,
806 false /*restore*/);
807 }
808
809 finish:
810 return eStatus;
811 }
812
813 //!
814 //! \brief Render single stream
815 //! \param [in] pRenderParams
816 //! Pointer to VPHAL render parameter
817 //! \param [in,out] pRenderPassData
818 //! Pointer to the VPHAL render pass data
819 //! \return MOS_STATUS
820 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
821 //!
RenderSingleStream(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)822 MOS_STATUS VphalRenderer::RenderSingleStream(
823 PVPHAL_RENDER_PARAMS pRenderParams,
824 RenderpassData *pRenderPassData)
825 {
826 MOS_STATUS eStatus;
827
828 eStatus = MOS_STATUS_SUCCESS;
829
830 if (pRenderPassData->pSrcSurface->SurfType == SURF_IN_PRIMARY)
831 {
832
833 VpHal_SaveRestorePrimaryFwdRefs(
834 this,
835 pRenderPassData->pPrimarySurface,
836 true /*save*/);
837
838 //-- DNDI/IECP-----------------------------------------------------
839 VPHAL_RNDR_DUMP_SURF(
840 this, pRenderPassData->uiSrcIndex, VPHAL_DBG_DUMP_TYPE_PRE_DNDI, pRenderPassData->pSrcSurface);
841
842 VPHAL_RENDER_CHK_STATUS(VpHal_RndrRenderVebox(
843 this,
844 pRenderParams,
845 pRenderPassData));
846
847 if (pRenderPassData->bSFCScalingOnly)
848 {
849 // set the output surface which from the Vebox+SFC as input surface, and let comp to do composite.
850 VPHAL_RENDER_CHK_NULL(pRenderPassData->pOutSurface);
851 pRenderPassData->bCompNeeded = true;
852 pRenderPassData->bSFCScalingOnly = false;
853 pRenderPassData->pSrcSurface = pRenderPassData->pOutSurface;
854 pRenderPassData->pSrcSurface->SurfType = SURF_IN_PRIMARY;
855 }
856
857 if (pRenderPassData->bOutputGenerated)
858 {
859 pRenderPassData->pSrcSurface = pRenderPassData->pOutSurface;
860 pRenderPassData->MoveToNextTempOutputSurface();
861 }
862 else
863 {
864 // Do not perform any more operations if Comp is not needed
865 if (pRenderPassData->bCompNeeded == false)
866 {
867 VPHAL_RENDER_NORMALMESSAGE("VEBOX/SFC modified Render Target, skipping further processing.");
868 goto finish;
869 }
870 }
871
872 VPHAL_RNDR_DUMP_SURF(
873 this, pRenderPassData->uiSrcIndex, VPHAL_DBG_DUMP_TYPE_POST_DNDI, pRenderPassData->pSrcSurface);
874
875 // We'll continue even if Advanced render fails
876 if ((eStatus == MOS_STATUS_SUCCESS) && (pRenderPassData->bCompNeeded || pRenderPassData->bHdrNeeded))
877 {
878 pRenderParams->pSrc[pRenderPassData->uiSrcIndex] = pRenderPassData->pSrcSurface;
879 }
880
881 if (pRenderPassData->bHdrNeeded && (pHdrState && !pHdrState->bBypassHdrKernelPath))
882 {
883 pRenderPassData->bCompNeeded = false;
884 }
885 }
886
887 finish:
888 return eStatus;
889 }
890
891 //!
892 //! \brief Compose input streams as fast 1toN
893 //! \details Use composite render to multi output streams
894 //! \param [in] pRenderParams
895 //! Pointer to VPHAL render parameter
896 //! \param [in,out] pRenderPassData
897 //! Pointer to the VPHAL render pass data
898 //! \return MOS_STATUS
899 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
900 //!
RenderFast1toNComposite(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)901 MOS_STATUS VphalRenderer::RenderFast1toNComposite(
902 PVPHAL_RENDER_PARAMS pRenderParams,
903 RenderpassData *pRenderPassData)
904 {
905 MOS_STATUS eStatus;
906 eStatus = MOS_STATUS_SUCCESS;
907 if (pRenderPassData->pSrcSurface->SurfType == SURF_IN_PRIMARY)
908 {
909 VpHal_SaveRestorePrimaryFwdRefs(
910 this,
911 pRenderPassData->pPrimarySurface,
912 true /*save*/);
913 pRenderParams->pSrc[pRenderPassData->uiSrcIndex] = pRenderPassData->pSrcSurface;
914 eStatus = Fast1toNState.pfnRender(&Fast1toNState, pRenderParams);
915 }
916
917 return eStatus;
918 }
919
920 //!
921 //! \brief Compose input streams
922 //! \details Use composite render to compose input streams
923 //! \param [in] pRenderParams
924 //! Pointer to VPHAL render parameter
925 //! \param [in,out] pRenderPassData
926 //! Pointer to the VPHAL render pass data
927 //! \return MOS_STATUS
928 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
929 //!
RenderComposite(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)930 MOS_STATUS VphalRenderer::RenderComposite(
931 PVPHAL_RENDER_PARAMS pRenderParams,
932 RenderpassData *pRenderPassData)
933 {
934 MOS_STATUS eStatus;
935
936 eStatus = MOS_STATUS_SUCCESS;
937
938 //------------------------------------------
939 VPHAL_RNDR_DUMP_SURF_PTR_ARRAY(
940 this, pRenderParams->pSrc, VPHAL_MAX_SOURCES,
941 pRenderParams->uSrcCount, VPHAL_DBG_DUMP_TYPE_PRE_COMP);
942 //------------------------------------------
943
944 if (pRenderPassData->pSrcSurface &&
945 (pRenderPassData->pSrcSurface->b16UsrPtr ||
946 pRenderParams->pTarget[0]->b16UsrPtr) &&
947 (VpHal_RndrIs16Align(&Align16State, pRenderParams)))
948 {
949 // process 16aligned usrptr mode.
950 VPHAL_RENDER_CHK_STATUS(Align16State.pfnRender(&Align16State, pRenderParams));
951 }
952 else
953 {
954 // fallback to legacy path
955 VPHAL_RENDER_CHK_STATUS(pRender[VPHAL_RENDER_ID_COMPOSITE]->Render(pRenderParams, nullptr));
956 }
957
958 //------------------------------------------
959 VPHAL_RNDR_DUMP_SURF_PTR_ARRAY(
960 this, pRenderParams->pSrc, VPHAL_MAX_SOURCES,
961 pRenderParams->uSrcCount, VPHAL_DBG_DUMP_TYPE_POST_COMP);
962
963 VPHAL_RNDR_DUMP_SURF_PTR_ARRAY(
964 this, pRenderParams->pTarget, VPHAL_MAX_TARGETS,
965 pRenderParams->uDstCount, VPHAL_DBG_DUMP_TYPE_POST_COMP);
966 //------------------------------------------
967
968 finish:
969 return eStatus;
970 }
971
972 //!
973 //! \brief Update report data
974 //! \details Update report data from each feature render
975 //! \param [in] pRenderParams
976 //! Pointer to VPHAL render parameter
977 //! \param [in,out] pRenderPassData
978 //! Pointer to the VPHAL render pass data
979 //! \return MOS_STATUS
980 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
981 //!
UpdateReport(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)982 void VphalRenderer::UpdateReport(
983 PVPHAL_RENDER_PARAMS pRenderParams,
984 RenderpassData *pRenderPassData)
985 {
986 VPHAL_GET_SURFACE_INFO Info;
987
988 pRender[VPHAL_RENDER_ID_COMPOSITE]->CopyReporting(m_reporting);
989
990 if (pRenderPassData->pPrimarySurface && pRenderPassData->pPrimarySurface->bCompressible)
991 {
992 m_reporting->PrimaryCompressible = true;
993 m_reporting->PrimaryCompressMode = (uint8_t)(pRenderPassData->pPrimarySurface->CompressionMode);
994 }
995
996 if (pRenderParams->pTarget[0]->bCompressible)
997 {
998 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
999
1000 VpHal_GetSurfaceInfo(m_pOsInterface, &Info, pRenderParams->pTarget[0]);
1001 m_reporting->RTCompressible = true;
1002 m_reporting->RTCompressMode = (uint8_t)(pRenderParams->pTarget[0]->CompressionMode);
1003 }
1004 }
1005
1006 //!
1007 //! \brief Check if Vphal renderer support some formats
1008 //! \param [in] pcRenderParams
1009 //! Const pointer to VPHAL render parameter
1010 //! \return bool
1011 //! Return true if successful, false failed
1012 //!
IsFormatSupported(PCVPHAL_RENDER_PARAMS pcRenderParams)1013 bool VphalRenderer::IsFormatSupported(
1014 PCVPHAL_RENDER_PARAMS pcRenderParams)
1015 {
1016 bool bFormatSupported = true;
1017
1018 VPHAL_RENDER_ASSERT(pcRenderParams);
1019
1020 // Protection mechanism
1021 // P010 output support from SKL+
1022 if (m_pSkuTable)
1023 {
1024 if (pcRenderParams->pTarget[0])
1025 {
1026 switch (pcRenderParams->pTarget[0]->Format)
1027 {
1028 case Format_P010:
1029 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVpP010Output) ? true : false;
1030 break;
1031 case Format_P016:
1032 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVpP010Output) ? true : false;
1033 break;
1034 case Format_Y210:
1035 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVp10BitSupport) ? true : false;
1036 break;
1037 case Format_Y410:
1038 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVp10BitSupport) ? true : false;
1039 break;
1040 case Format_Y216:
1041 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVp16BitSupport) ? true : false;
1042 break;
1043 case Format_Y416:
1044 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVp16BitSupport) ? true : false;
1045 break;
1046 default:
1047 break;
1048 }
1049 }
1050 }
1051
1052 return bFormatSupported;
1053 }
1054
1055 //!
1056 //! \brief Main render function
1057 //! \details The top level renderer function, which may contain multiple
1058 //! passes of rendering
1059 //! \param [in] pcRenderParams
1060 //! Const pointer to VPHAL render parameter
1061 //! \return MOS_STATUS
1062 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1063 //!
Render(PCVPHAL_RENDER_PARAMS pcRenderParams)1064 MOS_STATUS VphalRenderer::Render(
1065 PCVPHAL_RENDER_PARAMS pcRenderParams)
1066 {
1067 MOS_STATUS eStatus;
1068 PMOS_INTERFACE pOsInterface;
1069 PRENDERHAL_INTERFACE pRenderHal;
1070 VPHAL_RENDER_PARAMS RenderParams; // Make a copy of render params
1071 PVPHAL_SURFACE pSrcLeft[VPHAL_MAX_SOURCES]; // Array of sources referring to left view stereo content
1072 PVPHAL_SURFACE pSrcRight[VPHAL_MAX_SOURCES]; // Array of sources referring to right view stereo content
1073 uint32_t uiRenderPasses; // Number of rendering passes in this one call to VpHal_RndrRender()
1074 uint32_t uiCurrentRenderPass; // Current render pass
1075 uint32_t uiDst;
1076 VPHAL_GET_SURFACE_INFO Info;
1077
1078 //--------------------------------------------
1079 VPHAL_RENDER_ASSERT(pcRenderParams);
1080 VPHAL_RENDER_ASSERT(m_pOsInterface);
1081 VPHAL_RENDER_ASSERT(m_pRenderHal);
1082 VPHAL_RENDER_ASSERT(pKernelDllState);
1083 VPHAL_RENDER_ASSERT(pRender[VPHAL_RENDER_ID_COMPOSITE]);
1084 //--------------------------------------------
1085
1086 eStatus = MOS_STATUS_SUCCESS;
1087 pOsInterface = m_pOsInterface;
1088 pRenderHal = m_pRenderHal;
1089
1090 // Validate render target
1091 if (pcRenderParams->pTarget[0] == nullptr ||
1092 Mos_ResourceIsNull(&(pcRenderParams->pTarget[0]->OsResource)))
1093 {
1094 VPHAL_RENDER_ASSERTMESSAGE("Invalid Render Target.");
1095 eStatus = MOS_STATUS_UNKNOWN;
1096 goto finish;
1097 }
1098
1099 // Protection mechanism, Only SKL+ support P010 output.
1100 if (IsFormatSupported(pcRenderParams) == false)
1101 {
1102 VPHAL_RENDER_ASSERTMESSAGE("Invalid Render Target Output Format.");
1103 eStatus = MOS_STATUS_UNKNOWN;
1104 goto finish;
1105 }
1106
1107 VPHAL_DBG_STATE_DUMP_SET_CURRENT_FRAME_COUNT(uiFrameCounter);
1108
1109 // Validate max number sources
1110 if (pcRenderParams->uSrcCount > VPHAL_MAX_SOURCES)
1111 {
1112 VPHAL_RENDER_ASSERTMESSAGE("Invalid number of samples.");
1113 eStatus = MOS_STATUS_UNKNOWN;
1114 goto finish;
1115 }
1116
1117 // Validate max number targets
1118 if (pcRenderParams->uDstCount > VPHAL_MAX_TARGETS)
1119 {
1120 VPHAL_RENDER_ASSERTMESSAGE("Invalid number of targets.");
1121 eStatus = MOS_STATUS_UNKNOWN;
1122 goto finish;
1123 }
1124
1125 // Copy the Render Params structure (so we can update it)
1126 RenderParams = *pcRenderParams;
1127
1128 VPHAL_DBG_PARAMETERS_DUMPPER_DUMP_XML(&RenderParams);
1129
1130 // Get resource information for render target
1131 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
1132
1133 for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
1134 {
1135 VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
1136 m_pOsInterface,
1137 &Info,
1138 RenderParams.pTarget[uiDst]));
1139 }
1140
1141 // Set the component info
1142 m_pOsInterface->Component = pcRenderParams->Component;
1143
1144 // Init component(DDI entry point) info for perf measurement
1145 m_pOsInterface->pfnSetPerfTag(m_pOsInterface, VPHAL_NONE);
1146
1147 // Increment frame ID for performance measurement
1148 m_pOsInterface->pfnIncPerfFrameID(m_pOsInterface);
1149
1150 // Enable Turbo mode if sku present and DDI requests it
1151 if (m_pSkuTable && MEDIA_IS_SKU(m_pSkuTable, FtrMediaTurboMode))
1152 {
1153 m_pRenderHal->bTurboMode = RenderParams.bTurboMode;
1154 }
1155
1156 // Reset feature reporting
1157 m_reporting->InitReportValue();
1158
1159 MOS_ZeroMemory(pSrcLeft, sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
1160 MOS_ZeroMemory(pSrcRight, sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
1161
1162 VPHAL_RENDER_CHK_STATUS(PrepareSources(
1163 &RenderParams,
1164 pSrcLeft,
1165 pSrcRight,
1166 &uiRenderPasses));
1167
1168 //Update GpuContext
1169 if (MEDIA_IS_SKU(m_pSkuTable, FtrCCSNode))
1170 {
1171 MOS_GPU_CONTEXT currentGpuContext = m_pOsInterface->pfnGetGpuContext(m_pOsInterface);
1172 UpdateRenderGpuContext(currentGpuContext);
1173 }
1174 // align rectangle and source surface
1175 for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
1176 {
1177 VPHAL_RENDER_CHK_STATUS(VpHal_RndrRectSurfaceAlignment(RenderParams.pTarget[uiDst], RenderParams.pTarget[uiDst]->Format));
1178 }
1179
1180 for (uiCurrentRenderPass = 0;
1181 uiCurrentRenderPass < uiRenderPasses;
1182 uiCurrentRenderPass++)
1183 {
1184 // Assign source surfaces for current rendering pass
1185 MOS_SecureMemcpy(
1186 RenderParams.pSrc,
1187 sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES,
1188 (uiCurrentRenderPass == 0) ? pSrcLeft : pSrcRight,
1189 sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
1190
1191 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
1192
1193 for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
1194 {
1195 Info.S3dChannel = RenderParams.pTarget[uiDst]->Channel;
1196 Info.ArraySlice = uiCurrentRenderPass;
1197
1198 VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
1199 m_pOsInterface,
1200 &Info,
1201 RenderParams.pTarget[uiDst]));
1202 }
1203
1204 // Update channel. 0 = mono or stereo left, 1 = stereo right
1205 uiCurrentChannel = uiCurrentRenderPass;
1206
1207 VPHAL_RENDER_CHK_STATUS(RenderPass(&RenderParams));
1208 }
1209
1210 #if defined(LINUX)
1211 if (m_reporting)
1212 {
1213 WriteUserFeature(__VPHAL_VEBOX_OUTPUTPIPE_MODE_ID, m_reporting->OutputPipeMode);
1214 WriteUserFeature(__VPHAL_VEBOX_FEATURE_INUSE_ID, m_reporting->VEFeatureInUse);
1215 }
1216 #endif
1217
1218 finish:
1219 uiFrameCounter++;
1220 return eStatus;
1221 }
1222
1223 //!
1224 //! \brief Update Render Gpu Context
1225 //! \details Update Render Gpu Context
1226 //! \param [in] renderGpuContext
1227 //! \return MOS_STATUS
1228 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1229 //!
UpdateRenderGpuContext(MOS_GPU_CONTEXT currentGpuContext)1230 MOS_STATUS VphalRenderer::UpdateRenderGpuContext(MOS_GPU_CONTEXT currentGpuContext)
1231 {
1232 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1233 MOS_GPU_CONTEXT renderGpuContext;
1234 MOS_GPU_NODE renderGpuNode;
1235 MOS_GPUCTX_CREATOPTIONS createOption;
1236 PVPHAL_VEBOX_STATE pVeboxState = nullptr;
1237 int i = 0;
1238
1239 if (m_pOsInterface->osCpInterface->IsCpEnabled() &&
1240 (m_pOsInterface->osCpInterface->IsHMEnabled() || m_pOsInterface->osCpInterface->IsSMEnabled()))
1241 {
1242 if (currentGpuContext == MOS_GPU_CONTEXT_COMPUTE ||
1243 currentGpuContext == MOS_GPU_CONTEXT_COMPUTE_RA) // CCS
1244 {
1245 renderGpuContext = MOS_GPU_CONTEXT_COMPUTE_RA;
1246 renderGpuNode = MOS_GPU_NODE_COMPUTE;
1247 }
1248 else // RCS
1249 {
1250 renderGpuContext = MOS_GPU_CONTEXT_RENDER_RA;
1251 renderGpuNode = MOS_GPU_NODE_3D;
1252 }
1253 createOption.RAMode = 1;
1254 }
1255 else
1256 {
1257 if (currentGpuContext == MOS_GPU_CONTEXT_COMPUTE ||
1258 currentGpuContext == MOS_GPU_CONTEXT_COMPUTE_RA) // CCS
1259 {
1260 renderGpuContext = MOS_GPU_CONTEXT_COMPUTE;
1261 renderGpuNode = MOS_GPU_NODE_COMPUTE;
1262 }
1263 else // RCS
1264 {
1265 renderGpuContext = MOS_GPU_CONTEXT_RENDER;
1266 renderGpuNode = MOS_GPU_NODE_3D;
1267 }
1268 createOption.RAMode = 0;
1269 }
1270
1271 // no gpucontext will be created if the gpu context has been created before.
1272 VPHAL_PUBLIC_CHK_STATUS(m_pOsInterface->pfnCreateGpuContext(
1273 m_pOsInterface,
1274 renderGpuContext,
1275 renderGpuNode,
1276 &createOption));
1277
1278 VPHAL_PUBLIC_CHK_STATUS(m_pOsInterface->pfnSetGpuContext(
1279 m_pOsInterface,
1280 renderGpuContext));
1281
1282 // Register Render GPU context with the event
1283 VPHAL_PUBLIC_CHK_STATUS(m_pOsInterface->pfnRegisterBBCompleteNotifyEvent(
1284 m_pOsInterface,
1285 renderGpuContext));
1286
1287 //update sub render status one by one
1288 for (i = 0; i < VPHAL_RENDER_ID_COUNT - 1; i++)
1289 { // VPHAL_RENDER_ID_COMPOSITE is not inherited from vphal_vebox_state, skip it.
1290 pVeboxState = (PVPHAL_VEBOX_STATE)(pRender[i]);
1291 if (pVeboxState != nullptr)
1292 {
1293 pVeboxState->UpdateRenderGpuContext(renderGpuContext);
1294 }
1295 }
1296 finish:
1297 VPHAL_RENDER_NORMALMESSAGE("gpucontext switch from %d to %d", currentGpuContext, renderGpuContext);
1298 return eStatus;
1299 }
1300 //!
1301 //! \brief Release intermediate surfaces
1302 //! \details Release intermediate surfaces created for main render function
1303 //! \return MOS_STATUS
1304 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1305 //!
FreeIntermediateSurfaces()1306 MOS_STATUS VphalRenderer::FreeIntermediateSurfaces()
1307 {
1308 // Free IntermediateSurface
1309 if (m_pOsInterface)
1310 {
1311 m_pOsInterface->pfnFreeResource(m_pOsInterface, &IntermediateSurface.OsResource);
1312 }
1313
1314 MOS_SafeFreeMemory(IntermediateSurface.pBlendingParams);
1315 MOS_SafeFreeMemory(IntermediateSurface.pIEFParams);
1316 MOS_SafeFreeMemory(IntermediateSurface.pHDRParams);
1317
1318 return MOS_STATUS_SUCCESS;
1319 }
1320
1321 //!
1322 //! \brief Initialize the VPHAL renderer
1323 //! \details Initialize all the renderers supported including VEBOX, Composite.
1324 //! \param [in] pSettings
1325 //! Const pointer to VPHAL settings
1326 //! \return MOS_STATUS
1327 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1328 //!
Initialize(const VphalSettings * pSettings)1329 MOS_STATUS VphalRenderer::Initialize(
1330 const VphalSettings *pSettings)
1331 {
1332 void* pKernelBin;
1333 void* pFcPatchBin;
1334 MOS_STATUS eStatus;
1335 PMOS_INTERFACE pOsInterface;
1336 PRENDERHAL_INTERFACE pRenderHal;
1337 int32_t iResult;
1338 MHW_KERNEL_PARAM MhwKernelParam;
1339 Kdll_KernelCache *pKernelCache;
1340 Kdll_CacheEntry *pCacheEntryTable;
1341
1342 pKernelBin = nullptr;
1343 pFcPatchBin = nullptr;
1344 eStatus = MOS_STATUS_UNKNOWN;
1345 pOsInterface = m_pOsInterface;
1346 pRenderHal = m_pRenderHal;
1347 iResult = 0;
1348 pKernelBin = nullptr;
1349 pFcPatchBin = nullptr;
1350
1351 MOS_ZeroMemory(&MhwKernelParam, sizeof(MHW_KERNEL_PARAM));
1352
1353 //---------------------------------------
1354 VPHAL_RENDER_CHK_NULL(pSettings);
1355 VPHAL_RENDER_CHK_NULL(m_pOsInterface);
1356 VPHAL_RENDER_CHK_NULL(m_pRenderHal);
1357 //---------------------------------------
1358
1359 Align16State.pPerfData = &PerfData;
1360 Fast1toNState.pPerfData = &PerfData;
1361 // Current KDLL expects a writable memory for kernel binary. For that reason,
1362 // we need to copy the memory to a new location so that KDLL can overwrite.
1363 // !!! WARNING !!!
1364 // We MUST NOT create a writable global memory since it can cause issues
1365 // in multi-device cases (multiple threads operating on the memory)
1366 // NOTE: KDLL will release the allocated memory.
1367 pKernelBin = MOS_AllocMemory(dwKernelBinSize);
1368 VPHAL_RENDER_CHK_NULL(pKernelBin);
1369 MOS_SecureMemcpy(pKernelBin,
1370 dwKernelBinSize,
1371 pcKernelBin,
1372 dwKernelBinSize);
1373
1374 if ((pcFcPatchBin != nullptr) && (dwFcPatchBinSize != 0))
1375 {
1376 pFcPatchBin = MOS_AllocMemory(dwFcPatchBinSize);
1377 VPHAL_RENDER_CHK_NULL(pFcPatchBin);
1378 MOS_SecureMemcpy(pFcPatchBin,
1379 dwFcPatchBinSize,
1380 pcFcPatchBin,
1381 dwFcPatchBinSize);
1382 }
1383
1384 // Allocate KDLL state (Kernel Dynamic Linking)
1385 pKernelDllState = KernelDll_AllocateStates(
1386 pKernelBin,
1387 dwKernelBinSize,
1388 pFcPatchBin,
1389 dwFcPatchBinSize,
1390 pKernelDllRules,
1391 m_modifyKdllFunctionPointers);
1392 if (!pKernelDllState)
1393 {
1394 VPHAL_RENDER_ASSERTMESSAGE("Failed to allocate KDLL state.");
1395 goto finish;
1396 }
1397
1398 // Set up SIP debug kernel if enabled
1399 if (m_pRenderHal->bIsaAsmDebugEnable)
1400 {
1401 pKernelCache = &pKernelDllState->ComponentKernelCache;
1402 pCacheEntryTable = pKernelCache->pCacheEntries;
1403 VPHAL_RENDER_CHK_NULL(pCacheEntryTable);
1404
1405 MOS_ZeroMemory(&MhwKernelParam, sizeof(MhwKernelParam));
1406 MhwKernelParam.pBinary = pCacheEntryTable[IDR_VP_SIP_Debug].pBinary;
1407 MhwKernelParam.iSize = pCacheEntryTable[IDR_VP_SIP_Debug].iSize;
1408 iResult = m_pRenderHal->pfnLoadDebugKernel(
1409 m_pRenderHal,
1410 &MhwKernelParam);
1411
1412 if (iResult != 0)
1413 {
1414 m_pRenderHal->bIsaAsmDebugEnable = false;
1415 }
1416 }
1417
1418 VeboxExecState[0].Mode = VEBOX_EXEC_MODE_0;
1419 VeboxExecState[0].bDIOutputPair01 = true;
1420 VeboxExecState[0].bSpeculativeCopy = false;
1421 VeboxExecState[0].bEnable = (pSettings->veboxParallelExecution == VEBOX_EXECUTION_OVERRIDE_ENABLE);
1422 VeboxExecState[1] = VeboxExecState[0];
1423
1424 // Initialize VEBOX renderer
1425 VPHAL_RENDER_CHK_STATUS(pRender[VPHAL_RENDER_ID_VEBOX]->Initialize(
1426 pSettings,
1427 pKernelDllState));
1428
1429 VPHAL_RENDER_CHK_STATUS(pRender[VPHAL_RENDER_ID_VEBOX2]->Initialize(
1430 pSettings,
1431 pKernelDllState));
1432
1433 // Initialize Compositing renderer
1434 VPHAL_RENDER_CHK_STATUS(pRender[VPHAL_RENDER_ID_COMPOSITE]->Initialize(
1435 pSettings,
1436 pKernelDllState));
1437
1438 // Initialize 16 Alignment Interface and renderer
1439 VpHal_16AlignInitInterface(&Align16State, m_pRenderHal);
1440 VPHAL_RENDER_CHK_STATUS(Align16State.pfnInitialize(
1441 &Align16State,
1442 pSettings,
1443 pKernelDllState))
1444
1445 // Initialize fast 1to N Interface and render
1446 VpHal_Fast1toNInitInterface(&Fast1toNState, m_pRenderHal);
1447 VPHAL_RENDER_CHK_STATUS(Fast1toNState.pfnInitialize(
1448 &Fast1toNState,
1449 pSettings,
1450 pKernelDllState))
1451
1452 eStatus = AllocateDebugDumper();
1453 if (eStatus != MOS_STATUS_SUCCESS)
1454 {
1455 VPHAL_RENDER_ASSERTMESSAGE("Debug dumper allocate failed!");
1456 goto finish;
1457 }
1458
1459 if (MEDIA_IS_SKU(m_pSkuTable, FtrVpDisableFor4K))
1460 {
1461 bSkuDisableVpFor4K = true;
1462 }
1463 else
1464 {
1465 bSkuDisableVpFor4K = false;
1466 }
1467
1468 // Initialize Hdr renderer
1469 if (MEDIA_IS_SKU(m_pSkuTable, FtrHDR) && pHdrState)
1470 {
1471 VPHAL_RENDER_CHK_STATUS(pHdrState->pfnInitialize(
1472 pHdrState,
1473 pSettings,
1474 pKernelDllState));
1475 }
1476
1477 eStatus = MOS_STATUS_SUCCESS;
1478
1479 finish:
1480 if (eStatus != MOS_STATUS_SUCCESS)
1481 {
1482 if (pKernelBin)
1483 {
1484 MOS_SafeFreeMemory(pKernelBin);
1485 if (pKernelDllState && pKernelDllState->ComponentKernelCache.pCache == pKernelBin)
1486 {
1487 pKernelDllState->ComponentKernelCache.pCache = nullptr;
1488 }
1489 pKernelBin = nullptr;
1490 }
1491
1492 if (pFcPatchBin)
1493 {
1494 MOS_SafeFreeMemory(pFcPatchBin);
1495 if (pKernelDllState && pKernelDllState->CmFcPatchCache.pCache == pFcPatchBin)
1496 {
1497 pKernelDllState->CmFcPatchCache.pCache = nullptr;
1498 }
1499 pFcPatchBin = nullptr;
1500 }
1501 }
1502 return eStatus;
1503 }
1504
1505 //!
1506 //! \brief VPHAL renderer destructor
1507 //! \details Destory the resources allocated for the renderers
1508 //! including VEBOX and Composite.
1509 //!
~VphalRenderer()1510 VphalRenderer::~VphalRenderer()
1511 {
1512 VPHAL_RENDER_CHK_NULL_NO_STATUS(m_pOsInterface);
1513
1514 FreeIntermediateSurfaces();
1515
1516 MOS_Delete(m_reporting);
1517
1518 for (int32_t i = 0; i < VPHAL_RENDER_ID_COUNT; i++)
1519 {
1520 if (pRender[i])
1521 {
1522 pRender[i]->Destroy();
1523 MOS_Delete(pRender[i]);
1524 pRender[i] = nullptr;
1525 }
1526 }
1527
1528 // Destroy Kernel DLL objects (cache, hash table, states)
1529 if (pKernelDllState)
1530 {
1531 KernelDll_ReleaseStates(pKernelDllState);
1532 }
1533
1534 // Destroy resources allocated for 16 Alignment
1535 if (Align16State.pfnDestroy)
1536 {
1537 Align16State.pfnDestroy(&Align16State);
1538 }
1539
1540 // Destory resources allocated for fast1toN
1541 if (Fast1toNState.pfnDestroy)
1542 {
1543 Fast1toNState.pfnDestroy(&Fast1toNState);
1544 }
1545
1546 // Destroy resources allocated for Hdr
1547 if (MEDIA_IS_SKU(m_pSkuTable, FtrHDR) && pHdrState && pHdrState->pfnDestroy)
1548 {
1549 pHdrState->pfnDestroy(pHdrState);
1550 MOS_Delete(pHdrState);
1551 }
1552
1553 // Destroy surface dumper
1554 VPHAL_DBG_SURF_DUMP_DESTORY(m_surfaceDumper);
1555
1556 // Destroy state dumper
1557 VPHAL_DBG_STATE_DUMPPER_DESTORY(m_pRenderHal->pStateDumper);
1558
1559 // Destroy vphal parameter dump
1560 VPHAL_DBG_PARAMETERS_DUMPPER_DESTORY(m_parameterDumper);
1561
1562 finish:
1563 return;
1564 }
1565
1566 //!
1567 //! \brief Get the aligned the surface height and width unit
1568 //! \details Accoring to the format of the surface, get the aligned unit for the surface
1569 //! width and height
1570 //! \param [in,out] pwWidthAlignUnit
1571 //! Pointer to the surface width alignment unit
1572 //! \param [in,out] pwHeightAlignUnit
1573 //! Pointer to the surface height alignment unit
1574 //! \param [in] format
1575 //! The format of the surface
1576 //! \return void
1577 //!
VpHal_RndrGetAlignUnit(uint16_t * pwWidthAlignUnit,uint16_t * pwHeightAlignUnit,MOS_FORMAT format)1578 void VpHal_RndrGetAlignUnit(
1579 uint16_t* pwWidthAlignUnit,
1580 uint16_t* pwHeightAlignUnit,
1581 MOS_FORMAT format)
1582 {
1583 switch (format)
1584 {
1585 case Format_YV12:
1586 case Format_I420:
1587 case Format_IYUV:
1588 case Format_IMC1:
1589 case Format_IMC2:
1590 case Format_IMC3:
1591 case Format_IMC4:
1592 case Format_NV12:
1593 case Format_P010:
1594 case Format_P016:
1595 *pwWidthAlignUnit = 2;
1596 *pwHeightAlignUnit = 2;
1597 break;
1598
1599 case Format_YVU9:
1600 *pwWidthAlignUnit = 4;
1601 *pwHeightAlignUnit = 4;
1602 break;
1603
1604 case Format_YUY2:
1605 case Format_UYVY:
1606 case Format_YUYV:
1607 case Format_YVYU:
1608 case Format_VYUY:
1609 case Format_P208:
1610 case Format_Y210:
1611 case Format_Y216:
1612 *pwWidthAlignUnit = 2;
1613 *pwHeightAlignUnit = 1;
1614 break;
1615
1616 case Format_NV11:
1617 *pwWidthAlignUnit = 4;
1618 *pwHeightAlignUnit = 1;
1619 break;
1620
1621 default:
1622 *pwWidthAlignUnit = 1;
1623 *pwHeightAlignUnit = 1;
1624 break;
1625 }
1626 }
1627
1628 //!
1629 //! \brief Set packed YUV component offsets
1630 //! \details Accoring to the format of the surface, set packed YUV component offsets
1631 //! \param [in] format
1632 //! The format of the surface
1633 //! \param [in,out] pOffsetY
1634 //! The offset of Y
1635 //! \param [in,out] pOffsetU
1636 //! The offset of U
1637 //! \param [in,out] pOffsetV
1638 //! The offset of V
1639 //! \return MOS_STATUS
1640 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1641 //!
VpHal_RndrSetYUVComponents(MOS_FORMAT format,uint8_t * pOffsetY,uint8_t * pOffsetU,uint8_t * pOffsetV)1642 MOS_STATUS VpHal_RndrSetYUVComponents(
1643 MOS_FORMAT format,
1644 uint8_t* pOffsetY,
1645 uint8_t* pOffsetU,
1646 uint8_t* pOffsetV)
1647 {
1648 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1649
1650 switch (format)
1651 {
1652 case Format_PA:
1653 case Format_YUY2:
1654 case Format_YUYV:
1655 *pOffsetY = 0;
1656 *pOffsetU = 1;
1657 *pOffsetV = 3;
1658 break;
1659
1660 case Format_UYVY:
1661 *pOffsetY = 1;
1662 *pOffsetU = 0;
1663 *pOffsetV = 2;
1664 break;
1665
1666 case Format_YVYU:
1667 *pOffsetY = 0;
1668 *pOffsetU = 3;
1669 *pOffsetV = 1;
1670 break;
1671
1672 case Format_VYUY:
1673 *pOffsetY = 1;
1674 *pOffsetU = 2;
1675 *pOffsetV = 0;
1676 break;
1677
1678 case Format_Y210:
1679 *pOffsetY = 0;
1680 *pOffsetU = 2;
1681 *pOffsetV = 6;
1682 break;
1683
1684 default:
1685 VPHAL_RENDER_ASSERTMESSAGE("Unknown Packed YUV Format.");
1686 eStatus = MOS_STATUS_UNKNOWN;
1687 }
1688
1689 return eStatus;
1690 }
1691
1692 //!
1693 //! \brief VphalRenderer constructor
1694 //! \details Based on the HW and OS info, initialize the renderer interfaces
1695 //! \param [in] pRenderHal
1696 //! Pointer to RenderHal Interface Structure
1697 //! \param [in,out] pStatus
1698 //! Pointer to the MOS_STATUS flag.
1699 //! Will assign this flag to MOS_STATUS_SUCCESS if successful, otherwise failed
1700 //!
VphalRenderer(PRENDERHAL_INTERFACE pRenderHal,MOS_STATUS * pStatus)1701 VphalRenderer::VphalRenderer(
1702 PRENDERHAL_INTERFACE pRenderHal,
1703 MOS_STATUS *pStatus) :
1704 Align16State(),
1705 Fast1toNState(),
1706 VeboxExecState(),
1707 pRender(),
1708 pPrimaryFwdRef(),
1709 bVeboxUsedForCapPipe(false),
1710 uiCurrentChannel(0),
1711 pKernelDllRules(nullptr),
1712 pKernelDllState(nullptr),
1713 pcKernelBin(nullptr),
1714 dwKernelBinSize(0),
1715 pcFcPatchBin(nullptr),
1716 dwFcPatchBinSize(0),
1717 uiFrameCounter(0),
1718 #if (_DEBUG || _RELEASE_INTERNAL)
1719 m_surfaceDumper(nullptr),
1720 m_parameterDumper(nullptr),
1721 #endif
1722 m_statusTable(nullptr),
1723 maxSrcRect(),
1724 pHdrState(nullptr),
1725 m_pRenderHal(pRenderHal),
1726 m_pOsInterface(pRenderHal ? pRenderHal->pOsInterface : nullptr),
1727 m_pSkuTable(nullptr),
1728 m_pWaTable(nullptr),
1729 m_modifyKdllFunctionPointers(nullptr),
1730 uiSsdControl(0),
1731 bDpRotationUsed(false),
1732 bSkuDisableVpFor4K(false),
1733 bSkuDisableLaceFor4K(false),
1734 bSkuDisableDNFor4K(false),
1735 PerfData(),
1736 m_reporting(nullptr)
1737 {
1738 MOS_STATUS eStatus;
1739 MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
1740
1741 VPHAL_RENDER_CHK_NULL(m_pRenderHal);
1742 VPHAL_RENDER_CHK_NULL(m_pOsInterface);
1743
1744 MOS_ZeroMemory(&pRender, sizeof(pRender));
1745
1746 // Read Slice Shutdown (SSD Control) User Feature Key once during initialization
1747 MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
1748 eStatus = MOS_UserFeature_ReadValue_ID(
1749 nullptr,
1750 __VPHAL_RNDR_SSD_CONTROL_ID,
1751 &UserFeatureData);
1752 if (eStatus == MOS_STATUS_SUCCESS)
1753 {
1754 uiSsdControl = UserFeatureData.u32Data;
1755 }
1756
1757 // Do not fail if User feature keys is not present
1758 eStatus = MOS_STATUS_SUCCESS;
1759
1760 // Get SKU table
1761 m_pSkuTable = m_pOsInterface->pfnGetSkuTable(m_pOsInterface);
1762 m_pWaTable = m_pOsInterface->pfnGetWaTable(m_pOsInterface);
1763
1764 finish:
1765 if (pStatus)
1766 {
1767 *pStatus = eStatus;
1768 }
1769 }
1770
1771 //!
1772 //! \brief Search for the best match BB according to the render BB arguments
1773 //! \details Based on the params of the BB, search the BB table and try to get
1774 //! the best match
1775 //! \param [in] pBatchBufferTable
1776 //! Point to the BB table to be searched
1777 //! \param [in] pInputBbParams
1778 //! Point to the BB params required for the BB needed
1779 //! \param [in] iBbSize
1780 //! The BB size required for the BB needed
1781 //! \param [out] ppBatchBuffer
1782 //! Point to the addr of the best matched BB. Point to nullptr if there's no.
1783 //! \return MOS_STATUS
1784 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1785 //!
VpHal_RenderGetBestMatchBB(PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,int32_t iBbSize,PMHW_BATCH_BUFFER * ppBatchBuffer)1786 MOS_STATUS VpHal_RenderGetBestMatchBB(
1787 PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,
1788 PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,
1789 int32_t iBbSize,
1790 PMHW_BATCH_BUFFER *ppBatchBuffer)
1791 {
1792 PMHW_BATCH_BUFFER pBbEntry;
1793 PMHW_BATCH_BUFFER pBestMatch;
1794 PVPHAL_BATCH_BUFFER_PARAMS pSearchBbParams;
1795 void* pInputBbArgs;
1796 void* pSearchBbArgs;
1797 VPHAL_BB_TYPE BbType;
1798 int32_t i;
1799 int32_t iBbCount;
1800 int32_t iBbArgSize;
1801 MOS_STATUS eStatus;
1802
1803 pBestMatch = nullptr;
1804 pBbEntry = pBatchBufferTable->pBatchBufferHeader;
1805 iBbCount = *pBatchBufferTable->piBatchBufferCount;
1806 BbType = pInputBbParams->iType;
1807 pInputBbArgs = &pInputBbParams->BbArgs;
1808 iBbArgSize = pInputBbParams->iSize;
1809 eStatus = MOS_STATUS_UNKNOWN;
1810
1811 for (i = iBbCount; i > 0; i--, pBbEntry++)
1812 {
1813 pSearchBbParams = (PVPHAL_BATCH_BUFFER_PARAMS)pBbEntry->pPrivateData;
1814
1815 // Must have adequate size and the batch buffer type must be the same
1816 if (!pSearchBbParams ||
1817 pBbEntry->iSize < iBbSize ||
1818 pSearchBbParams->iType != BbType)
1819 {
1820 continue;
1821 }
1822
1823 // Point to the start address of the union
1824 pSearchBbArgs = &(pSearchBbParams->BbArgs);
1825
1826 // BB args must be the same to find the best match(DnDi, Frc and Istab)
1827 if (memcmp(pInputBbArgs, pSearchBbArgs, iBbArgSize))
1828 {
1829 continue;
1830 }
1831
1832 // Match -> reuse the BB regardless of the running state
1833 pBestMatch = pBbEntry;
1834 ((PVPHAL_BATCH_BUFFER_PARAMS)pBestMatch->pPrivateData)->bMatch = true;
1835
1836 break;
1837 }
1838
1839 *ppBatchBuffer = pBestMatch;
1840 eStatus = MOS_STATUS_SUCCESS;
1841 return eStatus;
1842 }
1843
1844 //!
1845 //! \brief Search from existing BBs for a match. If none, allocate new BB
1846 //! \details Based on the params of the BB, search the BB table and try to get
1847 //! the best match. If none, try to get an old unused BB to reuse. If
1848 //! still none, allocate one new BB
1849 //! \param [in] pBatchBufferTable
1850 //! Pointer to the BB table to be searched
1851 //! \param [in] pInputBbParams
1852 //! Pointer to the BB params required for the BB needed
1853 //! \param [in] iBbSize
1854 //! The BB size required for the BB needed
1855 //! \param [in] pRenderHal
1856 //! Pointer to RenderHal Interface Structure
1857 //! \param [out] ppBatchBuffer
1858 //! Pointer to the addr of the available BB. Point to nullptr if there's no
1859 //! \return MOS_STATUS
1860 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1861 //!
VpHal_RenderAllocateBB(PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,int32_t iBbSize,PRENDERHAL_INTERFACE pRenderHal,PMHW_BATCH_BUFFER * ppBatchBuffer)1862 MOS_STATUS VpHal_RenderAllocateBB(
1863 PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,
1864 PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,
1865 int32_t iBbSize,
1866 PRENDERHAL_INTERFACE pRenderHal,
1867 PMHW_BATCH_BUFFER *ppBatchBuffer)
1868 {
1869 PMHW_BATCH_BUFFER pOldest; // Oldest BB entry
1870 PMHW_BATCH_BUFFER pBatchBuffer; // Available BB allocation
1871 PMHW_BATCH_BUFFER pBbEntry; // 2nd level BBs array entry
1872 PVPHAL_BATCH_BUFFER_PARAMS pSearchBbParams; // Search BB parameters
1873 PVPHAL_BATCH_BUFFER_PARAMS pBbParams;
1874 int32_t i;
1875 int32_t iBbCount;
1876 VPHAL_BB_TYPE BbType;
1877 int32_t iBbArgSize;
1878 MOS_STATUS eStatus;
1879
1880 pOldest = nullptr;
1881 pBatchBuffer = nullptr;
1882 pBbEntry = pBatchBufferTable->pBatchBufferHeader;
1883 iBbCount = *pBatchBufferTable->piBatchBufferCount;
1884 BbType = pInputBbParams->iType;
1885 iBbArgSize = pInputBbParams->iSize;
1886 eStatus = MOS_STATUS_UNKNOWN;
1887
1888 switch (BbType)
1889 {
1890 case VPHAL_BB_TYPE_COMPOSITING:
1891 VPHAL_RENDER_CHK_STATUS(CompositeState::GetBestMatchBB(
1892 pBatchBufferTable,
1893 pInputBbParams,
1894 iBbSize,
1895 &pBatchBuffer));
1896 break;
1897
1898 case VPHAL_BB_TYPE_ADVANCED:
1899 VPHAL_RENDER_CHK_STATUS(VpHal_RenderGetBestMatchBB(
1900 pBatchBufferTable,
1901 pInputBbParams,
1902 iBbSize,
1903 &pBatchBuffer));
1904 break;
1905
1906 case VPHAL_BB_TYPE_GENERIC:
1907 break;
1908
1909 default:
1910 VPHAL_RENDER_ASSERTMESSAGE("Unsupported batch buffer type.");
1911 eStatus = MOS_STATUS_UNKNOWN;
1912 goto finish;
1913 }
1914
1915 if (pBatchBuffer)
1916 {
1917 // Best available batch buffer found
1918 eStatus = MOS_STATUS_SUCCESS;
1919 goto finish;
1920 }
1921
1922 // Search for an old unused BB to reuse
1923 for (i = iBbCount; i > 0; i--, pBbEntry++)
1924 {
1925 pSearchBbParams = (PVPHAL_BATCH_BUFFER_PARAMS)pBbEntry->pPrivateData;
1926
1927 if (pSearchBbParams == nullptr ||
1928 pSearchBbParams->iType != BbType)
1929 {
1930 continue;
1931 }
1932
1933 // Save oldest entry, regardless of size/in-use
1934 if (pOldest == nullptr ||
1935 (int32_t)(pBbEntry->dwSyncTag - pOldest->dwSyncTag) < 0)
1936 {
1937 pOldest = pBbEntry;
1938 }
1939
1940 // Skip busy or small batch buffers
1941 if (pBbEntry->bBusy || pBbEntry->iSize < iBbSize)
1942 {
1943 continue;
1944 }
1945
1946 // Use the oldest BB with suitable size and not in use
1947 if (pBatchBuffer == nullptr ||
1948 (int32_t)(pBbEntry->dwSyncTag - pBatchBuffer->dwSyncTag) < 0)
1949 {
1950 pBatchBuffer = pBbEntry;
1951 pBatchBuffer->iCurrent = 0;
1952 pBatchBuffer->iRemaining = pBatchBuffer->iSize;
1953 }
1954 }
1955
1956 // No available BB to use - allocate new
1957 if (!pBatchBuffer)
1958 {
1959 iBbSize = MOS_ALIGN_CEIL(iBbSize, VPHAL_BB_ALIGN_SIZE);
1960
1961 if (pOldest == nullptr ||
1962 (pOldest->bBusy &&
1963 iBbCount < pBatchBufferTable->iBbCountMax))
1964 {
1965 pOldest = nullptr;
1966 i = iBbCount++;
1967
1968 pBatchBuffer = pBatchBufferTable->pBatchBufferHeader + i;
1969 pBatchBuffer->pPrivateData = pBatchBufferTable->pBbParamsHeader + i;
1970
1971 *pBatchBufferTable->piBatchBufferCount = iBbCount;
1972 }
1973
1974 // Release old buffer - may be even in use (delayed release)
1975 if (pOldest)
1976 {
1977 if (pRenderHal->pfnFreeBB(pRenderHal, pOldest) != MOS_STATUS_SUCCESS)
1978 {
1979 VPHAL_RENDER_ASSERTMESSAGE("Failed to release batch buffer.");
1980 eStatus = MOS_STATUS_UNKNOWN;
1981 goto finish;
1982 }
1983
1984 pBatchBuffer = pOldest;
1985 }
1986
1987 // Allocate new buffer
1988 if (pRenderHal->pfnAllocateBB(pRenderHal, pBatchBuffer, iBbSize) != MOS_STATUS_SUCCESS)
1989 {
1990 VPHAL_RENDER_ASSERTMESSAGE("Failed to allocate batch buffer.");
1991 pBatchBuffer = nullptr;
1992 eStatus = MOS_STATUS_UNKNOWN;
1993 goto finish;
1994 }
1995 }
1996
1997 // Set batch buffer args
1998 pBbParams = (PVPHAL_BATCH_BUFFER_PARAMS)pBatchBuffer->pPrivateData;
1999 pBbParams->bMatch = false;
2000 pBbParams->iType = BbType;
2001 pBbParams->iSize = iBbArgSize;
2002 pBbParams->BbArgs = pInputBbParams->BbArgs;
2003
2004 eStatus = MOS_STATUS_SUCCESS;
2005
2006 finish:
2007 *ppBatchBuffer = pBatchBuffer;
2008 return eStatus;
2009 }
2010
2011 //!
2012 //! \brief Update max src rect in VphalRenderer and primary surface based
2013 //! on src rectangle info from primary video
2014 //! \details Add max src rect for consistent statistics surface layout. Update
2015 //! the max src rect of the surface and its reference surfaces
2016 //! \param [in,out] pRenderer
2017 //! VPHAL renderer pointer
2018 //! \param [in,out] pSurface
2019 //! Pointer to the surface
2020 //! \return void
2021 //!
VpHal_RenderInitMaxRect(VphalRenderer * pRenderer,PVPHAL_SURFACE pSurface)2022 void VpHal_RenderInitMaxRect(
2023 VphalRenderer *pRenderer,
2024 PVPHAL_SURFACE pSurface)
2025 {
2026 PVPHAL_SURFACE pRef;
2027 uint32_t i;
2028
2029 pSurface->bMaxRectChanged =
2030 (pSurface->rcSrc.right > pRenderer->maxSrcRect.right ||
2031 pSurface->rcSrc.bottom > pRenderer->maxSrcRect.bottom) ?
2032 true : false;
2033
2034 // calcualte max srcRect in pRenderParams
2035 pRenderer->maxSrcRect.right = MOS_MAX(
2036 pRenderer->maxSrcRect.right, pSurface->rcSrc.right);
2037 pRenderer->maxSrcRect.bottom = MOS_MAX(
2038 pRenderer->maxSrcRect.bottom, pSurface->rcSrc.bottom);
2039
2040 // copy max src rect to primary video
2041 pSurface->rcMaxSrc = pRenderer->maxSrcRect;
2042
2043 // copy max src rect to forward reference video
2044 pRef = pSurface->pFwdRef;
2045 for (i = 0; i < pSurface->uFwdRefCount; i++)
2046 {
2047 // check surface validity
2048 VPHAL_RENDER_CHK_NULL_NO_STATUS(pRef);
2049
2050 pRef->rcMaxSrc = pRenderer->maxSrcRect;
2051
2052 // get next forward reference
2053 pRef = pRef->pFwdRef;
2054 }
2055
2056 // copy max src rect to backward reference video
2057 pRef = pSurface->pBwdRef;
2058 for (i = 0; i < pSurface->uBwdRefCount; i++)
2059 {
2060 // check surface validity
2061 VPHAL_RENDER_CHK_NULL_NO_STATUS(pRef);
2062
2063 pRef->rcMaxSrc = pRenderer->maxSrcRect;
2064
2065 // get next backward reference
2066 pRef = pRef->pBwdRef;
2067 }
2068
2069 finish:
2070 return;
2071 }
2072
2073 //!
2074 //! \brief Allocate surface dumper
2075 //! \return MOS_STATUS
2076 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
2077 //!
CreateSurfaceDumper()2078 MOS_STATUS VphalRenderer::CreateSurfaceDumper()
2079 {
2080 #if (_DEBUG || _RELEASE_INTERNAL)
2081 VPHAL_DBG_SURF_DUMP_CREATE()
2082 VPHAL_RENDER_CHK_NULL_RETURN(m_surfaceDumper);
2083 #endif
2084 return MOS_STATUS_SUCCESS;
2085 }
2086
AllocateDebugDumper()2087 MOS_STATUS VphalRenderer::AllocateDebugDumper()
2088 {
2089 PRENDERHAL_INTERFACE pRenderHal = m_pRenderHal;
2090 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2091
2092 // Allocate feature report
2093 m_reporting = MOS_New(VphalFeatureReport);
2094 if (m_reporting == nullptr)
2095 {
2096 VPHAL_RENDER_ASSERTMESSAGE("Invalid null pointer!");
2097 eStatus = MOS_STATUS_NULL_POINTER;
2098 goto finish;
2099 }
2100
2101 #if (_DEBUG || _RELEASE_INTERNAL)
2102
2103 // Initialize Surface Dumper
2104 VPHAL_RENDER_CHK_STATUS(CreateSurfaceDumper());
2105
2106 // Initialize State Dumper
2107 VPHAL_DBG_STATE_DUMPPER_CREATE()
2108 if (pRenderHal->pStateDumper == nullptr)
2109 {
2110 VPHAL_RENDER_ASSERTMESSAGE("Invalid null pointer!");
2111 eStatus = MOS_STATUS_NULL_POINTER;
2112 goto finish;
2113 }
2114
2115 VPHAL_DBG_PARAMETERS_DUMPPER_CREATE()
2116 if (m_parameterDumper == nullptr)
2117 {
2118 VPHAL_RENDER_ASSERTMESSAGE("Invalid null pointer!");
2119 eStatus = MOS_STATUS_NULL_POINTER;
2120 goto finish;
2121 }
2122
2123 #endif
2124
2125 finish:
2126 if (eStatus != MOS_STATUS_SUCCESS)
2127 {
2128 if (m_reporting)
2129 {
2130 MOS_Delete(m_reporting);
2131 m_reporting = nullptr;
2132 }
2133
2134 #if (_DEBUG || _RELEASE_INTERNAL)
2135
2136 if (m_surfaceDumper)
2137 {
2138 VPHAL_DBG_SURF_DUMP_DESTORY(m_surfaceDumper)
2139 }
2140
2141 if (pRenderHal->pStateDumper)
2142 {
2143 VPHAL_DBG_STATE_DUMPPER_DESTORY(pRenderHal->pStateDumper)
2144 }
2145 #endif
2146
2147 }
2148
2149 return eStatus;
2150 }
2151
2152 //!
2153 //! \brief Get Hdr path needed flag
2154 //! \details Get Hdr path needed flag
2155 //! \param pRenderParams
2156 //! [in] Pointer to VPHAL render parameter
2157 //! \param pRenderPassData
2158 //! [in,out] Pointer to the VPHAL render pass data
2159 //! \return MOS_STATUS
2160 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
2161 //!
GetHdrPathNeededFlag(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)2162 MOS_STATUS VphalRenderer::GetHdrPathNeededFlag(
2163 PVPHAL_RENDER_PARAMS pRenderParams,
2164 RenderpassData *pRenderPassData)
2165 {
2166 MOS_STATUS eStatus;
2167 uint32_t uiIndex;
2168 PVPHAL_SURFACE pSrcSurface;
2169 PVPHAL_SURFACE pTargetSurface;
2170 bool bToneMapping;
2171 bool bBt2020Output;
2172 bool bMultiLayerBt2020;
2173
2174 //--------------------------------------------
2175 VPHAL_RENDER_CHK_NULL(pRenderParams);
2176 VPHAL_RENDER_CHK_NULL(pRenderPassData);
2177 VPHAL_RENDER_CHK_NULL(pRenderParams->pTarget[0]);
2178 //--------------------------------------------
2179
2180 eStatus = MOS_STATUS_SUCCESS;
2181 uiIndex = 0;
2182 pSrcSurface = nullptr;
2183 pTargetSurface = nullptr;
2184 bToneMapping = false;
2185 bBt2020Output = false;
2186 bMultiLayerBt2020 = false;
2187
2188 // Loop through the sources
2189 for (uiIndex = 0;
2190 uiIndex < VPHAL_MAX_SOURCES && uiIndex < pRenderParams->uSrcCount;
2191 uiIndex++)
2192 {
2193 pSrcSurface = pRenderParams->pSrc[uiIndex];
2194 if (pSrcSurface == nullptr)
2195 {
2196 continue;
2197 }
2198 pTargetSurface = pRenderParams->pTarget[0];
2199
2200 // Need to use HDR to process BT601/BT709->BT2020
2201 if (IS_COLOR_SPACE_BT2020(pRenderParams->pTarget[0]->ColorSpace) &&
2202 !IS_COLOR_SPACE_BT2020(pSrcSurface->ColorSpace))
2203 {
2204 bBt2020Output = true;
2205 }
2206
2207 if ((pSrcSurface->pHDRParams && (pSrcSurface->pHDRParams->EOTF != VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_SDR)) ||
2208 (pTargetSurface->pHDRParams && (pTargetSurface->pHDRParams->EOTF != VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_SDR)))
2209 {
2210 bToneMapping = true;
2211 }
2212
2213 if (IS_COLOR_SPACE_BT2020(pSrcSurface->ColorSpace) && pRenderParams->uSrcCount > 1)
2214 {
2215 bMultiLayerBt2020 = true;
2216 }
2217 }
2218
2219 pRenderPassData->bHdrNeeded = bBt2020Output || bToneMapping || bMultiLayerBt2020;
2220
2221 // Error handling for illegal Hdr cases on unsupported m_Platform
2222 if ((pRenderPassData->bHdrNeeded) && (!MEDIA_IS_SKU(m_pSkuTable, FtrHDR)))
2223 {
2224 eStatus = MOS_STATUS_SUCCESS;
2225 VPHAL_RENDER_ASSERTMESSAGE("Illegal Hdr cases on unsupported m_Platform, turn off HDR.");
2226 pRenderPassData->bHdrNeeded = false;
2227 }
2228
2229 if (pRenderPassData->bHdrNeeded)
2230 {
2231 pRenderPassData->bCompNeeded = false;
2232 }
2233
2234 if (!pRenderPassData->bHdrNeeded &&
2235 pRenderParams->pSrc[0] &&
2236 pRenderParams->pTarget[0] &&
2237 IS_COLOR_SPACE_BT2020(pRenderParams->pSrc[0]->ColorSpace) &&
2238 !IS_COLOR_SPACE_BT2020(pRenderParams->pTarget[0]->ColorSpace) &&
2239 MEDIA_IS_SKU(m_pSkuTable, FtrDisableVEBoxFeatures))
2240 {
2241 eStatus = MOS_STATUS_INVALID_PARAMETER;
2242 VPHAL_RENDER_ASSERTMESSAGE("Invalid Params for This Platform.");
2243 }
2244
2245 finish:
2246 return eStatus;
2247 }
2248