1 /*
2 * Copyright (c) 2011-2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file vphal_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 "vp_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.b2CSCNeeded)
773 {
774 // Second CSC in render, set input of render with output of vebox.
775 pRenderParams->pSrc[uiIndex_in] = RenderPassData.pOutSurface;
776 }
777 if (RenderPassData.bCompNeeded &&
778 (uiIndex_in == pRenderParams->uSrcCount-1 || // compatible with N:1 case, only render at the last input.
779 pRenderParams->uSrcCount == 0)) // fast color fill
780 {
781 VPHAL_RENDER_CHK_STATUS(RenderComposite(pRenderParams, &RenderPassData));
782 }
783 else if (VpHal_RndrIsHdrPathNeeded(this, pRenderParams, &RenderPassData) &&
784 (pHdrState &&
785 !pHdrState->bBypassHdrKernelPath))
786 {
787 VPHAL_RENDER_CHK_STATUS(VpHal_RndrRenderHDR(this, pRenderParams, &RenderPassData));
788 }
789 }
790 // restore render pointer and count.
791 pRenderParams->pTarget[0] = StoreRenderParams.pTarget[0];
792 pRenderParams->pTarget[0]->b16UsrPtr = StoreRenderParams.pTarget[0]->b16UsrPtr;
793 pRenderParams->uDstCount = StoreRenderParams.uDstCount;
794 }
795 }
796
797 // Report Render modes
798 UpdateReport(pRenderParams, &RenderPassData);
799
800 //------------------------------------------
801 VPHAL_RNDR_DUMP_SURF_PTR_ARRAY(
802 this, pRenderParams->pTarget, VPHAL_MAX_TARGETS,
803 pRenderParams->uDstCount, VPHAL_DBG_DUMP_TYPE_POST_ALL);
804 //------------------------------------------
805
806 if (RenderPassData.pPrimarySurface)
807 {
808 VpHal_SaveRestorePrimaryFwdRefs(
809 this,
810 pRenderParams->pSrc[RenderPassData.uiPrimaryIndex] = RenderPassData.pPrimarySurface,
811 false /*restore*/);
812 }
813
814 finish:
815 return eStatus;
816 }
817
818 //!
819 //! \brief Render single stream
820 //! \param [in] pRenderParams
821 //! Pointer to VPHAL render parameter
822 //! \param [in,out] pRenderPassData
823 //! Pointer to the VPHAL render pass data
824 //! \return MOS_STATUS
825 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
826 //!
RenderSingleStream(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)827 MOS_STATUS VphalRenderer::RenderSingleStream(
828 PVPHAL_RENDER_PARAMS pRenderParams,
829 RenderpassData *pRenderPassData)
830 {
831 MOS_STATUS eStatus;
832
833 eStatus = MOS_STATUS_SUCCESS;
834
835 if (pRenderPassData->pSrcSurface->SurfType == SURF_IN_PRIMARY)
836 {
837
838 VpHal_SaveRestorePrimaryFwdRefs(
839 this,
840 pRenderPassData->pPrimarySurface,
841 true /*save*/);
842
843 //-- DNDI/IECP-----------------------------------------------------
844 VPHAL_RNDR_DUMP_SURF(
845 this, pRenderPassData->uiSrcIndex, VPHAL_DBG_DUMP_TYPE_PRE_DNDI, pRenderPassData->pSrcSurface);
846
847 VPHAL_RENDER_CHK_STATUS(VpHal_RndrRenderVebox(
848 this,
849 pRenderParams,
850 pRenderPassData));
851
852 if (pRenderPassData->bSFCScalingOnly)
853 {
854 // set the output surface which from the Vebox+SFC as input surface, and let comp to do composite.
855 VPHAL_RENDER_CHK_NULL(pRenderPassData->pOutSurface);
856 pRenderPassData->bCompNeeded = true;
857 pRenderPassData->bSFCScalingOnly = false;
858 pRenderPassData->pSrcSurface = pRenderPassData->pOutSurface;
859 pRenderPassData->pSrcSurface->SurfType = SURF_IN_PRIMARY;
860 }
861
862 if (pRenderPassData->bOutputGenerated)
863 {
864 pRenderPassData->pSrcSurface = pRenderPassData->pOutSurface;
865 pRenderPassData->MoveToNextTempOutputSurface();
866 }
867 else
868 {
869 // Do not perform any more operations if Comp is not needed
870 if (pRenderPassData->bCompNeeded == false)
871 {
872 VPHAL_RENDER_NORMALMESSAGE("VEBOX/SFC modified Render Target, skipping further processing.");
873 goto finish;
874 }
875 }
876
877 VPHAL_RNDR_DUMP_SURF(
878 this, pRenderPassData->uiSrcIndex, VPHAL_DBG_DUMP_TYPE_POST_DNDI, pRenderPassData->pSrcSurface);
879
880 // We'll continue even if Advanced render fails
881 if ((eStatus == MOS_STATUS_SUCCESS) && (pRenderPassData->bCompNeeded || pRenderPassData->bHdrNeeded))
882 {
883 pRenderParams->pSrc[pRenderPassData->uiSrcIndex] = pRenderPassData->pSrcSurface;
884 }
885
886 if (pRenderPassData->bHdrNeeded && (pHdrState && !pHdrState->bBypassHdrKernelPath))
887 {
888 pRenderPassData->bCompNeeded = false;
889 }
890 }
891
892 finish:
893 return eStatus;
894 }
895
896 //!
897 //! \brief Compose input streams as fast 1toN
898 //! \details Use composite render to multi output streams
899 //! \param [in] pRenderParams
900 //! Pointer to VPHAL render parameter
901 //! \param [in,out] pRenderPassData
902 //! Pointer to the VPHAL render pass data
903 //! \return MOS_STATUS
904 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
905 //!
RenderFast1toNComposite(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)906 MOS_STATUS VphalRenderer::RenderFast1toNComposite(
907 PVPHAL_RENDER_PARAMS pRenderParams,
908 RenderpassData *pRenderPassData)
909 {
910 MOS_STATUS eStatus;
911 eStatus = MOS_STATUS_SUCCESS;
912 if (pRenderPassData->pSrcSurface->SurfType == SURF_IN_PRIMARY)
913 {
914 VpHal_SaveRestorePrimaryFwdRefs(
915 this,
916 pRenderPassData->pPrimarySurface,
917 true /*save*/);
918 pRenderParams->pSrc[pRenderPassData->uiSrcIndex] = pRenderPassData->pSrcSurface;
919 eStatus = Fast1toNState.pfnRender(&Fast1toNState, pRenderParams);
920 }
921
922 return eStatus;
923 }
924
925 //!
926 //! \brief Compose input streams
927 //! \details Use composite render to compose input streams
928 //! \param [in] pRenderParams
929 //! Pointer to VPHAL render parameter
930 //! \param [in,out] pRenderPassData
931 //! Pointer to the VPHAL render pass data
932 //! \return MOS_STATUS
933 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
934 //!
RenderComposite(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)935 MOS_STATUS VphalRenderer::RenderComposite(
936 PVPHAL_RENDER_PARAMS pRenderParams,
937 RenderpassData *pRenderPassData)
938 {
939 MOS_STATUS eStatus;
940
941 eStatus = MOS_STATUS_SUCCESS;
942
943 //------------------------------------------
944 VPHAL_RNDR_DUMP_SURF_PTR_ARRAY(
945 this, pRenderParams->pSrc, VPHAL_MAX_SOURCES,
946 pRenderParams->uSrcCount, VPHAL_DBG_DUMP_TYPE_PRE_COMP);
947 //------------------------------------------
948
949 if (pRenderPassData->pSrcSurface &&
950 (pRenderPassData->pSrcSurface->b16UsrPtr ||
951 pRenderParams->pTarget[0]->b16UsrPtr) &&
952 (VpHal_RndrIs16Align(&Align16State, pRenderParams)))
953 {
954 // process 16aligned usrptr mode.
955 VPHAL_RENDER_CHK_STATUS(Align16State.pfnRender(&Align16State, pRenderParams));
956 }
957 else
958 {
959 // fallback to legacy path
960 VPHAL_RENDER_CHK_STATUS(pRender[VPHAL_RENDER_ID_COMPOSITE]->Render(pRenderParams, nullptr));
961 }
962
963 //------------------------------------------
964 VPHAL_RNDR_DUMP_SURF_PTR_ARRAY(
965 this, pRenderParams->pSrc, VPHAL_MAX_SOURCES,
966 pRenderParams->uSrcCount, VPHAL_DBG_DUMP_TYPE_POST_COMP);
967
968 VPHAL_RNDR_DUMP_SURF_PTR_ARRAY(
969 this, pRenderParams->pTarget, VPHAL_MAX_TARGETS,
970 pRenderParams->uDstCount, VPHAL_DBG_DUMP_TYPE_POST_COMP);
971 //------------------------------------------
972
973 finish:
974 return eStatus;
975 }
976
977 //!
978 //! \brief Update report data
979 //! \details Update report data from each feature render
980 //! \param [in] pRenderParams
981 //! Pointer to VPHAL render parameter
982 //! \param [in,out] pRenderPassData
983 //! Pointer to the VPHAL render pass data
984 //! \return MOS_STATUS
985 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
986 //!
UpdateReport(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)987 void VphalRenderer::UpdateReport(
988 PVPHAL_RENDER_PARAMS pRenderParams,
989 RenderpassData *pRenderPassData)
990 {
991 VPHAL_GET_SURFACE_INFO Info;
992
993 pRender[VPHAL_RENDER_ID_COMPOSITE]->CopyReporting(m_reporting);
994
995 if (pRenderPassData->pPrimarySurface && pRenderPassData->pPrimarySurface->bCompressible)
996 {
997 m_reporting->GetFeatures().primaryCompressible = true;
998 m_reporting->GetFeatures().primaryCompressMode = (uint8_t)(pRenderPassData->pPrimarySurface->CompressionMode);
999 }
1000
1001 if (pRenderParams->pTarget[0]->bCompressible)
1002 {
1003 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
1004
1005 MOS_STATUS status = VpHal_GetSurfaceInfo(m_pOsInterface, &Info, pRenderParams->pTarget[0]);
1006 if (MOS_STATUS_SUCCESS != status)
1007 {
1008 VPHAL_PUBLIC_ASSERTMESSAGE("VpHal_GetSurfaceInfo failed!");
1009 return;
1010 }
1011 m_reporting->GetFeatures().rtCompressible = true;
1012 m_reporting->GetFeatures().rtCompressMode = (uint8_t)(pRenderParams->pTarget[0]->CompressionMode);
1013 }
1014
1015 m_reporting->GetFeatures().rtCacheSetting = (uint8_t)(pRenderParams->pTarget[0]->CacheSetting);
1016 #if (_DEBUG || _RELEASE_INTERNAL)
1017 m_reporting->GetFeatures().rtOldCacheSetting = (uint8_t)(m_pRenderHal->oldCacheSettingForTargetSurface);
1018 #endif
1019 }
1020
1021 //!
1022 //! \brief Check if Vphal renderer support some formats
1023 //! \param [in] pcRenderParams
1024 //! Const pointer to VPHAL render parameter
1025 //! \return bool
1026 //! Return true if successful, false failed
1027 //!
IsFormatSupported(PCVPHAL_RENDER_PARAMS pcRenderParams)1028 bool VphalRenderer::IsFormatSupported(
1029 PCVPHAL_RENDER_PARAMS pcRenderParams)
1030 {
1031 bool bFormatSupported = true;
1032
1033 VPHAL_RENDER_ASSERT(pcRenderParams);
1034
1035 // Protection mechanism
1036 // P010 output support from SKL+
1037 if (m_pSkuTable)
1038 {
1039 if (pcRenderParams->pTarget[0])
1040 {
1041 switch (pcRenderParams->pTarget[0]->Format)
1042 {
1043 case Format_P010:
1044 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVpP010Output) ? true : false;
1045 break;
1046 case Format_P016:
1047 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVpP010Output) ? true : false;
1048 break;
1049 case Format_Y210:
1050 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVp10BitSupport) ? true : false;
1051 break;
1052 case Format_Y410:
1053 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVp10BitSupport) ? true : false;
1054 break;
1055 case Format_Y216:
1056 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVp16BitSupport) ? true : false;
1057 break;
1058 case Format_Y416:
1059 bFormatSupported = MEDIA_IS_SKU(m_pSkuTable, FtrVp16BitSupport) ? true : false;
1060 break;
1061 default:
1062 break;
1063 }
1064 }
1065 }
1066
1067 return bFormatSupported;
1068 }
1069
1070 //!
1071 //! \brief Main render function
1072 //! \details The top level renderer function, which may contain multiple
1073 //! passes of rendering
1074 //! \param [in] pcRenderParams
1075 //! Const pointer to VPHAL render parameter
1076 //! \return MOS_STATUS
1077 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1078 //!
Render(PCVPHAL_RENDER_PARAMS pcRenderParams)1079 MOS_STATUS VphalRenderer::Render(
1080 PCVPHAL_RENDER_PARAMS pcRenderParams)
1081 {
1082 MOS_STATUS eStatus;
1083 PMOS_INTERFACE pOsInterface;
1084 PRENDERHAL_INTERFACE pRenderHal;
1085 VPHAL_RENDER_PARAMS RenderParams; // Make a copy of render params
1086 PVPHAL_SURFACE pSrcLeft[VPHAL_MAX_SOURCES]; // Array of sources referring to left view stereo content
1087 PVPHAL_SURFACE pSrcRight[VPHAL_MAX_SOURCES]; // Array of sources referring to right view stereo content
1088 uint32_t uiRenderPasses; // Number of rendering passes in this one call to VpHal_RndrRender()
1089 uint32_t uiCurrentRenderPass; // Current render pass
1090 uint32_t uiDst;
1091 VPHAL_GET_SURFACE_INFO Info;
1092
1093 //--------------------------------------------
1094 VPHAL_RENDER_ASSERT(pcRenderParams);
1095 VPHAL_RENDER_ASSERT(m_pOsInterface);
1096 VPHAL_RENDER_ASSERT(m_pRenderHal);
1097 VPHAL_RENDER_ASSERT(pKernelDllState);
1098 VPHAL_RENDER_ASSERT(pRender[VPHAL_RENDER_ID_COMPOSITE]);
1099 //--------------------------------------------
1100
1101 eStatus = MOS_STATUS_SUCCESS;
1102 pOsInterface = m_pOsInterface;
1103 pRenderHal = m_pRenderHal;
1104
1105 // Validate render target
1106 if (pcRenderParams->pTarget[0] == nullptr ||
1107 Mos_ResourceIsNull(&(pcRenderParams->pTarget[0]->OsResource)))
1108 {
1109 VPHAL_RENDER_ASSERTMESSAGE("Invalid Render Target.");
1110 eStatus = MOS_STATUS_UNKNOWN;
1111 goto finish;
1112 }
1113
1114 // Protection mechanism, Only SKL+ support P010 output.
1115 if (IsFormatSupported(pcRenderParams) == false)
1116 {
1117 VPHAL_RENDER_ASSERTMESSAGE("Invalid Render Target Output Format.");
1118 eStatus = MOS_STATUS_UNKNOWN;
1119 goto finish;
1120 }
1121
1122 VPHAL_DBG_STATE_DUMP_SET_CURRENT_FRAME_COUNT(uiFrameCounter);
1123
1124 // Validate max number sources
1125 if (pcRenderParams->uSrcCount > VPHAL_MAX_SOURCES)
1126 {
1127 VPHAL_RENDER_ASSERTMESSAGE("Invalid number of samples.");
1128 eStatus = MOS_STATUS_UNKNOWN;
1129 goto finish;
1130 }
1131
1132 // Validate max number targets
1133 if (pcRenderParams->uDstCount > VPHAL_MAX_TARGETS)
1134 {
1135 VPHAL_RENDER_ASSERTMESSAGE("Invalid number of targets.");
1136 eStatus = MOS_STATUS_UNKNOWN;
1137 goto finish;
1138 }
1139
1140 // Copy the Render Params structure (so we can update it)
1141 RenderParams = *pcRenderParams;
1142
1143 VPHAL_DBG_PARAMETERS_DUMPPER_DUMP_XML(&RenderParams);
1144 VPHAL_DBG_OCA_DUMPER_SET_RENDER_PARAM(pRenderHal, &RenderParams);
1145
1146 // Get resource information for render target
1147 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
1148
1149 for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
1150 {
1151 VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
1152 m_pOsInterface,
1153 &Info,
1154 RenderParams.pTarget[uiDst]));
1155 }
1156
1157 // Set the component info
1158 m_pOsInterface->Component = pcRenderParams->Component;
1159
1160 // Init component(DDI entry point) info for perf measurement
1161 m_pOsInterface->pfnSetPerfTag(m_pOsInterface, VPHAL_NONE);
1162
1163 // Increment frame ID for performance measurement
1164 m_pOsInterface->pfnIncPerfFrameID(m_pOsInterface);
1165
1166 // Enable Turbo mode if sku present and DDI requests it
1167 if (m_pSkuTable && MEDIA_IS_SKU(m_pSkuTable, FtrMediaTurboMode))
1168 {
1169 m_pRenderHal->bTurboMode = RenderParams.bTurboMode;
1170 }
1171
1172 // Reset feature reporting
1173 m_reporting->InitReportValue();
1174
1175 MOS_ZeroMemory(pSrcLeft, sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
1176 MOS_ZeroMemory(pSrcRight, sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
1177
1178 VPHAL_RENDER_CHK_STATUS(PrepareSources(
1179 &RenderParams,
1180 pSrcLeft,
1181 pSrcRight,
1182 &uiRenderPasses));
1183
1184 //Update GpuContext
1185 if (MEDIA_IS_SKU(m_pSkuTable, FtrCCSNode))
1186 {
1187 MOS_GPU_CONTEXT currentGpuContext = m_pOsInterface->pfnGetGpuContext(m_pOsInterface);
1188 UpdateRenderGpuContext(currentGpuContext);
1189 }
1190 // align rectangle and source surface
1191 for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
1192 {
1193 VPHAL_RENDER_CHK_STATUS(VpHal_RndrRectSurfaceAlignment(RenderParams.pTarget[uiDst], RenderParams.pTarget[uiDst]->Format));
1194 }
1195
1196 for (uiCurrentRenderPass = 0;
1197 uiCurrentRenderPass < uiRenderPasses;
1198 uiCurrentRenderPass++)
1199 {
1200 // Assign source surfaces for current rendering pass
1201 MOS_SecureMemcpy(
1202 RenderParams.pSrc,
1203 sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES,
1204 (uiCurrentRenderPass == 0) ? pSrcLeft : pSrcRight,
1205 sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
1206
1207 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
1208
1209 for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
1210 {
1211 Info.S3dChannel = RenderParams.pTarget[uiDst]->Channel;
1212 Info.ArraySlice = uiCurrentRenderPass;
1213
1214 VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
1215 m_pOsInterface,
1216 &Info,
1217 RenderParams.pTarget[uiDst]));
1218 }
1219
1220 // Update channel. 0 = mono or stereo left, 1 = stereo right
1221 uiCurrentChannel = uiCurrentRenderPass;
1222
1223 VPHAL_RENDER_CHK_STATUS(RenderPass(&RenderParams));
1224 }
1225
1226 finish:
1227 uiFrameCounter++;
1228 return eStatus;
1229 }
1230
1231 //!
1232 //! \brief Update Render Gpu Context
1233 //! \details Update Render Gpu Context
1234 //! \param [in] renderGpuContext
1235 //! \return MOS_STATUS
1236 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1237 //!
UpdateRenderGpuContext(MOS_GPU_CONTEXT currentGpuContext)1238 MOS_STATUS VphalRenderer::UpdateRenderGpuContext(MOS_GPU_CONTEXT currentGpuContext)
1239 {
1240 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1241 MOS_GPU_CONTEXT renderGpuContext;
1242 MOS_GPU_NODE renderGpuNode;
1243 MOS_GPUCTX_CREATOPTIONS_ENHANCED createOption = {};
1244 PVPHAL_VEBOX_STATE pVeboxState = nullptr;
1245 int i = 0;
1246
1247 if ((MEDIA_IS_SKU(m_pSkuTable, FtrRAMode) || MEDIA_IS_SKU(m_pSkuTable, FtrProtectedEnableBitRequired)) &&
1248 m_pOsInterface->osCpInterface->IsCpEnabled() &&
1249 (m_pOsInterface->osCpInterface->IsHMEnabled() || m_pOsInterface->osCpInterface->IsSMEnabled()))
1250 {
1251 if (currentGpuContext == MOS_GPU_CONTEXT_COMPUTE ||
1252 currentGpuContext == MOS_GPU_CONTEXT_COMPUTE_RA) // CCS
1253 {
1254 renderGpuContext = MOS_GPU_CONTEXT_COMPUTE_RA;
1255 renderGpuNode = MOS_GPU_NODE_COMPUTE;
1256 }
1257 else // RCS
1258 {
1259 renderGpuContext = MOS_GPU_CONTEXT_RENDER_RA;
1260 renderGpuNode = MOS_GPU_NODE_3D;
1261 }
1262 createOption.RAMode = MEDIA_IS_SKU(m_pSkuTable, FtrRAMode);
1263 createOption.ProtectMode = MEDIA_IS_SKU(m_pSkuTable, FtrProtectedEnableBitRequired);
1264 }
1265 else
1266 {
1267 if (currentGpuContext == MOS_GPU_CONTEXT_COMPUTE ||
1268 currentGpuContext == MOS_GPU_CONTEXT_COMPUTE_RA) // CCS
1269 {
1270 renderGpuContext = MOS_GPU_CONTEXT_COMPUTE;
1271 renderGpuNode = MOS_GPU_NODE_COMPUTE;
1272 }
1273 else // RCS
1274 {
1275 renderGpuContext = MOS_GPU_CONTEXT_RENDER;
1276 renderGpuNode = MOS_GPU_NODE_3D;
1277 }
1278 createOption.RAMode = 0;
1279 createOption.ProtectMode = 0;
1280 }
1281
1282 // no gpucontext will be created if the gpu context has been created before.
1283 VPHAL_PUBLIC_CHK_STATUS(m_pOsInterface->pfnCreateGpuContext(
1284 m_pOsInterface,
1285 renderGpuContext,
1286 renderGpuNode,
1287 &createOption));
1288
1289 VPHAL_PUBLIC_CHK_STATUS(m_pOsInterface->pfnSetGpuContext(
1290 m_pOsInterface,
1291 renderGpuContext));
1292
1293 // Register Render GPU context with the event
1294 VPHAL_PUBLIC_CHK_STATUS(m_pOsInterface->pfnRegisterBBCompleteNotifyEvent(
1295 m_pOsInterface,
1296 renderGpuContext));
1297
1298 //update sub render status one by one
1299 for (i = 0; i < VPHAL_RENDER_ID_COUNT - 1; i++)
1300 { // VPHAL_RENDER_ID_COMPOSITE is not inherited from vphal_vebox_state, skip it.
1301 pVeboxState = (PVPHAL_VEBOX_STATE)(pRender[i]);
1302 if (pVeboxState != nullptr)
1303 {
1304 pVeboxState->UpdateRenderGpuContext(renderGpuContext);
1305 }
1306 }
1307 finish:
1308 VPHAL_RENDER_NORMALMESSAGE("gpucontext switch from %d to %d", currentGpuContext, renderGpuContext);
1309 return eStatus;
1310 }
1311
SetRenderGpuContext(VPHAL_RENDER_PARAMS & RenderParams)1312 MOS_STATUS VphalRenderer::SetRenderGpuContext(VPHAL_RENDER_PARAMS& RenderParams)
1313 {
1314 MOS_GPU_CONTEXT currentGpuContext = m_renderGpuContext;
1315
1316 if (currentGpuContext != MOS_GPU_CONTEXT_RENDER)
1317 {
1318 bool bLumaKeyEnabled = false;
1319 for (uint32_t uiSources = 0; uiSources < RenderParams.uSrcCount; uiSources++)
1320 {
1321 VPHAL_SURFACE* pSrc = (VPHAL_SURFACE*)RenderParams.pSrc[uiSources];
1322 bLumaKeyEnabled = (pSrc && pSrc->pLumaKeyParams) ? true : false;
1323 if (bLumaKeyEnabled)
1324 {
1325 break;
1326 }
1327 }
1328 if (bLumaKeyEnabled)
1329 {
1330 currentGpuContext = MOS_GPU_CONTEXT_RENDER;
1331 }
1332 }
1333
1334 UpdateRenderGpuContext(currentGpuContext);
1335
1336 return MOS_STATUS_SUCCESS;
1337 }
1338
1339 //!
1340 //! \brief Release intermediate surfaces
1341 //! \details Release intermediate surfaces created for main render function
1342 //! \return MOS_STATUS
1343 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1344 //!
FreeIntermediateSurfaces()1345 MOS_STATUS VphalRenderer::FreeIntermediateSurfaces()
1346 {
1347 // Free IntermediateSurface
1348 if (m_pOsInterface)
1349 {
1350 m_pOsInterface->pfnFreeResource(m_pOsInterface, &IntermediateSurface.OsResource);
1351 }
1352
1353 MOS_SafeFreeMemory(IntermediateSurface.pBlendingParams);
1354 MOS_SafeFreeMemory(IntermediateSurface.pIEFParams);
1355 MOS_SafeFreeMemory(IntermediateSurface.pHDRParams);
1356
1357 return MOS_STATUS_SUCCESS;
1358 }
1359
1360 //!
1361 //! \brief Initialize the VPHAL renderer
1362 //! \details Initialize all the renderers supported including VEBOX, Composite.
1363 //! \param [in] pSettings
1364 //! Const pointer to VPHAL settings
1365 //! \return MOS_STATUS
1366 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1367 //!
Initialize(const VphalSettings * pSettings,bool isApoEnabled)1368 MOS_STATUS VphalRenderer::Initialize(
1369 const VphalSettings *pSettings,
1370 bool isApoEnabled)
1371 {
1372 void* pKernelBin;
1373 void* pFcPatchBin;
1374 MOS_STATUS eStatus;
1375 PMOS_INTERFACE pOsInterface;
1376 PRENDERHAL_INTERFACE pRenderHal;
1377 int32_t iResult;
1378 MHW_KERNEL_PARAM MhwKernelParam;
1379 Kdll_KernelCache *pKernelCache;
1380 Kdll_CacheEntry *pCacheEntryTable;
1381
1382 pKernelBin = nullptr;
1383 pFcPatchBin = nullptr;
1384 eStatus = MOS_STATUS_UNKNOWN;
1385 pOsInterface = m_pOsInterface;
1386 pRenderHal = m_pRenderHal;
1387 iResult = 0;
1388 pKernelBin = nullptr;
1389 pFcPatchBin = nullptr;
1390
1391 MOS_ZeroMemory(&MhwKernelParam, sizeof(MHW_KERNEL_PARAM));
1392
1393 //---------------------------------------
1394 VPHAL_RENDER_CHK_NULL(pSettings);
1395 VPHAL_RENDER_CHK_NULL(m_pOsInterface);
1396 VPHAL_RENDER_CHK_NULL(m_pRenderHal);
1397 //---------------------------------------
1398 m_isApoEnabled = isApoEnabled;
1399 m_renderGpuContext = m_pOsInterface->pfnGetGpuContext(m_pOsInterface);
1400 m_clearVideoViewMode = pSettings->clearVideoViewMode;
1401
1402 Align16State.pPerfData = &PerfData;
1403 Fast1toNState.pPerfData = &PerfData;
1404 // Current KDLL expects a writable memory for kernel binary. For that reason,
1405 // we need to copy the memory to a new location so that KDLL can overwrite.
1406 // !!! WARNING !!!
1407 // We MUST NOT create a writable global memory since it can cause issues
1408 // in multi-device cases (multiple threads operating on the memory)
1409 // NOTE: KDLL will release the allocated memory.
1410 // NOTE: Need to check kernel binary pointer and bin size firstly,
1411 // Because calling malloc(0) will usually returns a valid pointer, and any usage of this pointer excluding free memory is undefined in C/C++.
1412 if(pcKernelBin == nullptr || dwKernelBinSize == 0)
1413 {
1414 eStatus = MOS_STATUS_NULL_POINTER;
1415 VPHAL_RENDER_ASSERTMESSAGE("Could not allocate KDLL state with no kernel binary");
1416 goto finish;
1417 }
1418 pKernelBin = MOS_AllocMemory(dwKernelBinSize);
1419 VPHAL_RENDER_CHK_NULL(pKernelBin);
1420 MOS_SecureMemcpy(pKernelBin,
1421 dwKernelBinSize,
1422 pcKernelBin,
1423 dwKernelBinSize);
1424
1425 if ((pcFcPatchBin != nullptr) && (dwFcPatchBinSize != 0))
1426 {
1427 pFcPatchBin = MOS_AllocMemory(dwFcPatchBinSize);
1428 VPHAL_RENDER_CHK_NULL(pFcPatchBin);
1429 MOS_SecureMemcpy(pFcPatchBin,
1430 dwFcPatchBinSize,
1431 pcFcPatchBin,
1432 dwFcPatchBinSize);
1433 }
1434
1435 // Allocate KDLL state (Kernel Dynamic Linking)
1436 pKernelDllState = KernelDll_AllocateStates(
1437 pKernelBin,
1438 dwKernelBinSize,
1439 pFcPatchBin,
1440 dwFcPatchBinSize,
1441 pKernelDllRules,
1442 m_modifyKdllFunctionPointers);
1443 if (!pKernelDllState)
1444 {
1445 eStatus = MOS_STATUS_NULL_POINTER;
1446 VPHAL_RENDER_ASSERTMESSAGE("Failed to allocate KDLL state.");
1447 goto finish;
1448 }
1449
1450 // Set up SIP debug kernel if enabled
1451 if (m_pRenderHal->bIsaAsmDebugEnable)
1452 {
1453 pKernelCache = &pKernelDllState->ComponentKernelCache;
1454 pCacheEntryTable = pKernelCache->pCacheEntries;
1455 VPHAL_RENDER_CHK_NULL(pCacheEntryTable);
1456
1457 MOS_ZeroMemory(&MhwKernelParam, sizeof(MhwKernelParam));
1458 MhwKernelParam.pBinary = pCacheEntryTable[IDR_VP_SIP_Debug].pBinary;
1459 MhwKernelParam.iSize = pCacheEntryTable[IDR_VP_SIP_Debug].iSize;
1460 iResult = m_pRenderHal->pfnLoadDebugKernel(
1461 m_pRenderHal,
1462 &MhwKernelParam);
1463
1464 if (iResult != 0)
1465 {
1466 m_pRenderHal->bIsaAsmDebugEnable = false;
1467 }
1468 }
1469
1470 // Initialize Compositing renderer
1471 VPHAL_RENDER_CHK_STATUS(pRender[VPHAL_RENDER_ID_COMPOSITE]->Initialize(
1472 pSettings,
1473 pKernelDllState));
1474
1475 if (!m_clearVideoViewMode)
1476 {
1477 VeboxExecState[0].Mode = VEBOX_EXEC_MODE_0;
1478 VeboxExecState[0].bDIOutputPair01 = true;
1479 VeboxExecState[0].bSpeculativeCopy = false;
1480 VeboxExecState[0].bEnable = (pSettings->veboxParallelExecution == VEBOX_EXECUTION_OVERRIDE_ENABLE);
1481 VeboxExecState[1] = VeboxExecState[0];
1482
1483 // Initialize VEBOX renderer
1484 VPHAL_RENDER_CHK_STATUS(pRender[VPHAL_RENDER_ID_VEBOX]->Initialize(
1485 pSettings,
1486 pKernelDllState));
1487
1488 VPHAL_RENDER_CHK_STATUS(pRender[VPHAL_RENDER_ID_VEBOX2]->Initialize(
1489 pSettings,
1490 pKernelDllState));
1491
1492 // Initialize 16 Alignment Interface and renderer
1493 VpHal_16AlignInitInterface(&Align16State, m_pRenderHal);
1494 VPHAL_RENDER_CHK_STATUS(Align16State.pfnInitialize(
1495 &Align16State,
1496 pSettings,
1497 pKernelDllState))
1498
1499 // Initialize fast 1to N Interface and render
1500 VpHal_Fast1toNInitInterface(&Fast1toNState, m_pRenderHal);
1501 VPHAL_RENDER_CHK_STATUS(Fast1toNState.pfnInitialize(
1502 &Fast1toNState,
1503 pSettings,
1504 pKernelDllState))
1505 }
1506
1507 eStatus = AllocateDebugDumper();
1508 if (eStatus != MOS_STATUS_SUCCESS)
1509 {
1510 VPHAL_RENDER_ASSERTMESSAGE("Debug dumper allocate failed!");
1511 goto finish;
1512 }
1513
1514 if (MEDIA_IS_SKU(m_pSkuTable, FtrVpDisableFor4K))
1515 {
1516 bSkuDisableVpFor4K = true;
1517 }
1518 else
1519 {
1520 bSkuDisableVpFor4K = false;
1521 }
1522
1523 // Initialize Hdr renderer
1524 if (MEDIA_IS_SKU(m_pSkuTable, FtrHDR) && pHdrState && !m_clearVideoViewMode)
1525 {
1526 VPHAL_RENDER_CHK_STATUS(pHdrState->pfnInitialize(
1527 pHdrState,
1528 pSettings,
1529 pKernelDllState));
1530 }
1531
1532 eStatus = MOS_STATUS_SUCCESS;
1533 finish:
1534 if (eStatus != MOS_STATUS_SUCCESS)
1535 {
1536 if (pKernelBin)
1537 {
1538 MOS_SafeFreeMemory(pKernelBin);
1539 if (pKernelDllState && pKernelDllState->ComponentKernelCache.pCache == pKernelBin)
1540 {
1541 pKernelDllState->ComponentKernelCache.pCache = nullptr;
1542 }
1543 pKernelBin = nullptr;
1544 }
1545
1546 if (pFcPatchBin)
1547 {
1548 MOS_SafeFreeMemory(pFcPatchBin);
1549 if (pKernelDllState && pKernelDllState->CmFcPatchCache.pCache == pFcPatchBin)
1550 {
1551 pKernelDllState->CmFcPatchCache.pCache = nullptr;
1552 }
1553 pFcPatchBin = nullptr;
1554 }
1555 }
1556 return eStatus;
1557 }
1558
1559 //!
1560 //! \brief VPHAL renderer destructor
1561 //! \details Destory the resources allocated for the renderers
1562 //! including VEBOX and Composite.
1563 //!
~VphalRenderer()1564 VphalRenderer::~VphalRenderer()
1565 {
1566 VPHAL_RENDER_CHK_NULL_NO_STATUS(m_pOsInterface);
1567
1568 FreeIntermediateSurfaces();
1569
1570 MOS_Delete(m_reporting);
1571
1572 for (int32_t i = 0; i < VPHAL_RENDER_ID_COUNT; i++)
1573 {
1574 if (pRender[i])
1575 {
1576 pRender[i]->Destroy();
1577 MOS_Delete(pRender[i]);
1578 pRender[i] = nullptr;
1579 }
1580 }
1581
1582 // Destroy Kernel DLL objects (cache, hash table, states)
1583 if (pKernelDllState)
1584 {
1585 KernelDll_ReleaseStates(pKernelDllState);
1586 }
1587
1588 // Destroy resources allocated for 16 Alignment
1589 if (Align16State.pfnDestroy)
1590 {
1591 Align16State.pfnDestroy(&Align16State);
1592 }
1593
1594 // Destory resources allocated for fast1toN
1595 if (Fast1toNState.pfnDestroy)
1596 {
1597 Fast1toNState.pfnDestroy(&Fast1toNState);
1598 }
1599
1600 // Destroy resources allocated for Hdr
1601 if (MEDIA_IS_SKU(m_pSkuTable, FtrHDR) && pHdrState && pHdrState->pfnDestroy)
1602 {
1603 pHdrState->pfnDestroy(pHdrState);
1604 MOS_Delete(pHdrState);
1605 }
1606
1607 // Destroy surface dumper
1608 VPHAL_DBG_SURF_DUMP_DESTORY(m_surfaceDumper);
1609
1610 // Destroy state dumper
1611 VPHAL_DBG_STATE_DUMPPER_DESTORY(m_pRenderHal->pStateDumper);
1612
1613 // Destroy vphal parameter dump
1614 VPHAL_DBG_PARAMETERS_DUMPPER_DESTORY(m_parameterDumper);
1615
1616 VPHAL_DBG_OCA_DUMPER_DESTORY(m_pRenderHal);
1617
1618 finish:
1619 return;
1620 }
1621
1622 //!
1623 //! \brief Get the aligned the surface height and width unit
1624 //! \details Accoring to the format of the surface, get the aligned unit for the surface
1625 //! width and height
1626 //! \param [in,out] pwWidthAlignUnit
1627 //! Pointer to the surface width alignment unit
1628 //! \param [in,out] pwHeightAlignUnit
1629 //! Pointer to the surface height alignment unit
1630 //! \param [in] format
1631 //! The format of the surface
1632 //! \return void
1633 //!
VpHal_RndrGetAlignUnit(uint16_t * pwWidthAlignUnit,uint16_t * pwHeightAlignUnit,MOS_FORMAT format)1634 void VpHal_RndrGetAlignUnit(
1635 uint16_t* pwWidthAlignUnit,
1636 uint16_t* pwHeightAlignUnit,
1637 MOS_FORMAT format)
1638 {
1639 switch (format)
1640 {
1641 case Format_YV12:
1642 case Format_I420:
1643 case Format_IYUV:
1644 case Format_IMC1:
1645 case Format_IMC2:
1646 case Format_IMC3:
1647 case Format_IMC4:
1648 case Format_NV12:
1649 case Format_P010:
1650 case Format_P016:
1651 *pwWidthAlignUnit = 2;
1652 *pwHeightAlignUnit = 2;
1653 break;
1654
1655 case Format_YVU9:
1656 *pwWidthAlignUnit = 4;
1657 *pwHeightAlignUnit = 4;
1658 break;
1659
1660 case Format_YUY2:
1661 case Format_UYVY:
1662 case Format_YUYV:
1663 case Format_YVYU:
1664 case Format_VYUY:
1665 case Format_P208:
1666 case Format_Y210:
1667 case Format_Y216:
1668 *pwWidthAlignUnit = 2;
1669 *pwHeightAlignUnit = 1;
1670 break;
1671
1672 case Format_NV11:
1673 *pwWidthAlignUnit = 4;
1674 *pwHeightAlignUnit = 1;
1675 break;
1676
1677 default:
1678 *pwWidthAlignUnit = 1;
1679 *pwHeightAlignUnit = 1;
1680 break;
1681 }
1682 }
1683
1684 //!
1685 //! \brief Set packed YUV component offsets
1686 //! \details Accoring to the format of the surface, set packed YUV component offsets
1687 //! \param [in] format
1688 //! The format of the surface
1689 //! \param [in,out] pOffsetY
1690 //! The offset of Y
1691 //! \param [in,out] pOffsetU
1692 //! The offset of U
1693 //! \param [in,out] pOffsetV
1694 //! The offset of V
1695 //! \return MOS_STATUS
1696 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1697 //!
VpHal_RndrSetYUVComponents(MOS_FORMAT format,uint8_t * pOffsetY,uint8_t * pOffsetU,uint8_t * pOffsetV)1698 MOS_STATUS VpHal_RndrSetYUVComponents(
1699 MOS_FORMAT format,
1700 uint8_t* pOffsetY,
1701 uint8_t* pOffsetU,
1702 uint8_t* pOffsetV)
1703 {
1704 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1705
1706 switch (format)
1707 {
1708 case Format_PA:
1709 case Format_YUY2:
1710 case Format_YUYV:
1711 *pOffsetY = 0;
1712 *pOffsetU = 1;
1713 *pOffsetV = 3;
1714 break;
1715
1716 case Format_UYVY:
1717 *pOffsetY = 1;
1718 *pOffsetU = 0;
1719 *pOffsetV = 2;
1720 break;
1721
1722 case Format_YVYU:
1723 *pOffsetY = 0;
1724 *pOffsetU = 3;
1725 *pOffsetV = 1;
1726 break;
1727
1728 case Format_VYUY:
1729 *pOffsetY = 1;
1730 *pOffsetU = 2;
1731 *pOffsetV = 0;
1732 break;
1733
1734 case Format_Y210:
1735 *pOffsetY = 0;
1736 *pOffsetU = 2;
1737 *pOffsetV = 6;
1738 break;
1739
1740 default:
1741 VPHAL_RENDER_ASSERTMESSAGE("Unknown Packed YUV Format.");
1742 eStatus = MOS_STATUS_UNKNOWN;
1743 }
1744
1745 return eStatus;
1746 }
1747
1748 //!
1749 //! \brief VphalRenderer constructor
1750 //! \details Based on the HW and OS info, initialize the renderer interfaces
1751 //! \param [in] pRenderHal
1752 //! Pointer to RenderHal Interface Structure
1753 //! \param [in,out] pStatus
1754 //! Pointer to the MOS_STATUS flag.
1755 //! Will assign this flag to MOS_STATUS_SUCCESS if successful, otherwise failed
1756 //!
VphalRenderer(PRENDERHAL_INTERFACE pRenderHal,MOS_STATUS * pStatus)1757 VphalRenderer::VphalRenderer(
1758 PRENDERHAL_INTERFACE pRenderHal,
1759 MOS_STATUS *pStatus) :
1760 Align16State(),
1761 Fast1toNState(),
1762 VeboxExecState(),
1763 pRender(),
1764 pPrimaryFwdRef(),
1765 bVeboxUsedForCapPipe(false),
1766 uiCurrentChannel(0),
1767 pKernelDllRules(nullptr),
1768 pKernelDllState(nullptr),
1769 pcKernelBin(nullptr),
1770 dwKernelBinSize(0),
1771 pcFcPatchBin(nullptr),
1772 dwFcPatchBinSize(0),
1773 uiFrameCounter(0),
1774 #if (_DEBUG || _RELEASE_INTERNAL)
1775 m_surfaceDumper(nullptr),
1776 m_parameterDumper(nullptr),
1777 #endif
1778 m_statusTable(nullptr),
1779 maxSrcRect(),
1780 pHdrState(nullptr),
1781 m_pRenderHal((PRENDERHAL_INTERFACE_LEGACY)pRenderHal),
1782 m_pOsInterface(pRenderHal ? pRenderHal->pOsInterface : nullptr),
1783 m_pSkuTable(nullptr),
1784 m_pWaTable(nullptr),
1785 m_modifyKdllFunctionPointers(nullptr),
1786 uiSsdControl(0),
1787 bDpRotationUsed(false),
1788 bSkuDisableVpFor4K(false),
1789 bSkuDisableLaceFor4K(false),
1790 bSkuDisableDNFor4K(false),
1791 PerfData(),
1792 m_reporting(nullptr),
1793 m_renderGpuContext(MOS_GPU_CONTEXT_INVALID_HANDLE)
1794 {
1795 MOS_STATUS eStatus;
1796 uint32_t ssdControl = 0;
1797
1798 VPHAL_RENDER_CHK_NULL(m_pRenderHal);
1799 VPHAL_RENDER_CHK_NULL(m_pOsInterface);
1800 m_userSettingPtr = m_pOsInterface->pfnGetUserSettingInstance(m_pOsInterface);
1801
1802 MOS_ZeroMemory(&pRender, sizeof(pRender));
1803
1804 // Read Slice Shutdown (SSD Control) User Feature Key once during initialization
1805 eStatus = ReadUserSetting(
1806 m_userSettingPtr,
1807 ssdControl,
1808 __VPHAL_RNDR_SSD_CONTROL,
1809 MediaUserSetting::Group::Sequence);
1810 if (eStatus == MOS_STATUS_SUCCESS)
1811 {
1812 uiSsdControl = ssdControl;
1813 }
1814
1815 // Do not fail if User feature keys is not present
1816 eStatus = MOS_STATUS_SUCCESS;
1817
1818 // Get SKU table
1819 m_pSkuTable = m_pOsInterface->pfnGetSkuTable(m_pOsInterface);
1820 m_pWaTable = m_pOsInterface->pfnGetWaTable(m_pOsInterface);
1821
1822 finish:
1823 if (pStatus)
1824 {
1825 *pStatus = eStatus;
1826 }
1827 }
1828
1829 //!
1830 //! \brief Search for the best match BB according to the render BB arguments
1831 //! \details Based on the params of the BB, search the BB table and try to get
1832 //! the best match
1833 //! \param [in] pBatchBufferTable
1834 //! Point to the BB table to be searched
1835 //! \param [in] pInputBbParams
1836 //! Point to the BB params required for the BB needed
1837 //! \param [in] iBbSize
1838 //! The BB size required for the BB needed
1839 //! \param [out] ppBatchBuffer
1840 //! Point to the addr of the best matched BB. Point to nullptr if there's no.
1841 //! \return MOS_STATUS
1842 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1843 //!
VpHal_RenderGetBestMatchBB(PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,int32_t iBbSize,PMHW_BATCH_BUFFER * ppBatchBuffer)1844 MOS_STATUS VpHal_RenderGetBestMatchBB(
1845 PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,
1846 PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,
1847 int32_t iBbSize,
1848 PMHW_BATCH_BUFFER *ppBatchBuffer)
1849 {
1850 PMHW_BATCH_BUFFER pBbEntry;
1851 PMHW_BATCH_BUFFER pBestMatch;
1852 PVPHAL_BATCH_BUFFER_PARAMS pSearchBbParams;
1853 void* pInputBbArgs;
1854 void* pSearchBbArgs;
1855 VPHAL_BB_TYPE BbType;
1856 int32_t i;
1857 int32_t iBbCount;
1858 int32_t iBbArgSize;
1859 MOS_STATUS eStatus;
1860
1861 pBestMatch = nullptr;
1862 pBbEntry = pBatchBufferTable->pBatchBufferHeader;
1863 iBbCount = *pBatchBufferTable->piBatchBufferCount;
1864 BbType = pInputBbParams->iType;
1865 pInputBbArgs = &pInputBbParams->BbArgs;
1866 iBbArgSize = pInputBbParams->iSize;
1867 eStatus = MOS_STATUS_UNKNOWN;
1868
1869 for (i = iBbCount; i > 0; i--, pBbEntry++)
1870 {
1871 pSearchBbParams = (PVPHAL_BATCH_BUFFER_PARAMS)pBbEntry->pPrivateData;
1872
1873 // Must have adequate size and the batch buffer type must be the same
1874 if (!pSearchBbParams ||
1875 pBbEntry->iSize < iBbSize ||
1876 pSearchBbParams->iType != BbType)
1877 {
1878 continue;
1879 }
1880
1881 // Point to the start address of the union
1882 pSearchBbArgs = &(pSearchBbParams->BbArgs);
1883
1884 // BB args must be the same to find the best match(DnDi, Frc and Istab)
1885 if (memcmp(pInputBbArgs, pSearchBbArgs, iBbArgSize))
1886 {
1887 continue;
1888 }
1889
1890 // Match -> reuse the BB regardless of the running state
1891 pBestMatch = pBbEntry;
1892 ((PVPHAL_BATCH_BUFFER_PARAMS)pBestMatch->pPrivateData)->bMatch = true;
1893
1894 break;
1895 }
1896
1897 *ppBatchBuffer = pBestMatch;
1898 eStatus = MOS_STATUS_SUCCESS;
1899 return eStatus;
1900 }
1901
1902 //!
1903 //! \brief Search from existing BBs for a match. If none, allocate new BB
1904 //! \details Based on the params of the BB, search the BB table and try to get
1905 //! the best match. If none, try to get an old unused BB to reuse. If
1906 //! still none, allocate one new BB
1907 //! \param [in] pBatchBufferTable
1908 //! Pointer to the BB table to be searched
1909 //! \param [in] pInputBbParams
1910 //! Pointer to the BB params required for the BB needed
1911 //! \param [in] iBbSize
1912 //! The BB size required for the BB needed
1913 //! \param [in] pRenderHal
1914 //! Pointer to RenderHal Interface Structure
1915 //! \param [out] ppBatchBuffer
1916 //! Pointer to the addr of the available BB. Point to nullptr if there's no
1917 //! \return MOS_STATUS
1918 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1919 //!
VpHal_RenderAllocateBB(PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,int32_t iBbSize,PRENDERHAL_INTERFACE pRenderHal,PMHW_BATCH_BUFFER * ppBatchBuffer)1920 MOS_STATUS VpHal_RenderAllocateBB(
1921 PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,
1922 PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,
1923 int32_t iBbSize,
1924 PRENDERHAL_INTERFACE pRenderHal,
1925 PMHW_BATCH_BUFFER *ppBatchBuffer)
1926 {
1927 PMHW_BATCH_BUFFER pOldest; // Oldest BB entry
1928 PMHW_BATCH_BUFFER pBatchBuffer; // Available BB allocation
1929 PMHW_BATCH_BUFFER pBbEntry; // 2nd level BBs array entry
1930 PVPHAL_BATCH_BUFFER_PARAMS pSearchBbParams; // Search BB parameters
1931 PVPHAL_BATCH_BUFFER_PARAMS pBbParams;
1932 int32_t i;
1933 int32_t iBbCount;
1934 VPHAL_BB_TYPE BbType;
1935 int32_t iBbArgSize;
1936 MOS_STATUS eStatus;
1937
1938 pOldest = nullptr;
1939 pBatchBuffer = nullptr;
1940 pBbEntry = pBatchBufferTable->pBatchBufferHeader;
1941 iBbCount = *pBatchBufferTable->piBatchBufferCount;
1942 BbType = pInputBbParams->iType;
1943 iBbArgSize = pInputBbParams->iSize;
1944 eStatus = MOS_STATUS_UNKNOWN;
1945
1946 switch (BbType)
1947 {
1948 case VPHAL_BB_TYPE_COMPOSITING:
1949 VPHAL_RENDER_CHK_STATUS(CompositeState::GetBestMatchBB(
1950 pBatchBufferTable,
1951 pInputBbParams,
1952 iBbSize,
1953 &pBatchBuffer));
1954 break;
1955
1956 case VPHAL_BB_TYPE_ADVANCED:
1957 VPHAL_RENDER_CHK_STATUS(VpHal_RenderGetBestMatchBB(
1958 pBatchBufferTable,
1959 pInputBbParams,
1960 iBbSize,
1961 &pBatchBuffer));
1962 break;
1963
1964 case VPHAL_BB_TYPE_GENERIC:
1965 break;
1966
1967 default:
1968 VPHAL_RENDER_ASSERTMESSAGE("Unsupported batch buffer type.");
1969 eStatus = MOS_STATUS_UNKNOWN;
1970 goto finish;
1971 }
1972
1973 if (pBatchBuffer)
1974 {
1975 // Best available batch buffer found
1976 eStatus = MOS_STATUS_SUCCESS;
1977 goto finish;
1978 }
1979
1980 // Search for an old unused BB to reuse
1981 for (i = iBbCount; i > 0; i--, pBbEntry++)
1982 {
1983 pSearchBbParams = (PVPHAL_BATCH_BUFFER_PARAMS)pBbEntry->pPrivateData;
1984
1985 if (pSearchBbParams == nullptr ||
1986 pSearchBbParams->iType != BbType)
1987 {
1988 continue;
1989 }
1990
1991 // Save oldest entry, regardless of size/in-use
1992 if (pOldest == nullptr ||
1993 (int32_t)(pBbEntry->dwSyncTag - pOldest->dwSyncTag) < 0)
1994 {
1995 pOldest = pBbEntry;
1996 }
1997
1998 // Skip busy or small batch buffers
1999 if (pBbEntry->bBusy || pBbEntry->iSize < iBbSize)
2000 {
2001 continue;
2002 }
2003
2004 // Use the oldest BB with suitable size and not in use
2005 if (pBatchBuffer == nullptr ||
2006 (int32_t)(pBbEntry->dwSyncTag - pBatchBuffer->dwSyncTag) < 0)
2007 {
2008 pBatchBuffer = pBbEntry;
2009 pBatchBuffer->iCurrent = 0;
2010 pBatchBuffer->iRemaining = pBatchBuffer->iSize;
2011 }
2012 }
2013
2014 // No available BB to use - allocate new
2015 if (!pBatchBuffer)
2016 {
2017 iBbSize = MOS_ALIGN_CEIL(iBbSize, VPHAL_BB_ALIGN_SIZE);
2018
2019 if (pOldest == nullptr ||
2020 (pOldest->bBusy &&
2021 iBbCount < pBatchBufferTable->iBbCountMax))
2022 {
2023 pOldest = nullptr;
2024 i = iBbCount++;
2025
2026 pBatchBuffer = pBatchBufferTable->pBatchBufferHeader + i;
2027 pBatchBuffer->pPrivateData = pBatchBufferTable->pBbParamsHeader + i;
2028
2029 *pBatchBufferTable->piBatchBufferCount = iBbCount;
2030 }
2031
2032 // Release old buffer - may be even in use (delayed release)
2033 if (pOldest)
2034 {
2035 if (pRenderHal->pfnFreeBB(pRenderHal, pOldest) != MOS_STATUS_SUCCESS)
2036 {
2037 VPHAL_RENDER_ASSERTMESSAGE("Failed to release batch buffer.");
2038 eStatus = MOS_STATUS_UNKNOWN;
2039 goto finish;
2040 }
2041
2042 pBatchBuffer = pOldest;
2043 }
2044
2045 // Allocate new buffer
2046 if (pRenderHal->pfnAllocateBB(pRenderHal, pBatchBuffer, iBbSize) != MOS_STATUS_SUCCESS)
2047 {
2048 VPHAL_RENDER_ASSERTMESSAGE("Failed to allocate batch buffer.");
2049 pBatchBuffer = nullptr;
2050 eStatus = MOS_STATUS_UNKNOWN;
2051 goto finish;
2052 }
2053 }
2054
2055 // Set batch buffer args
2056 pBbParams = (PVPHAL_BATCH_BUFFER_PARAMS)pBatchBuffer->pPrivateData;
2057 pBbParams->bMatch = false;
2058 pBbParams->iType = BbType;
2059 pBbParams->iSize = iBbArgSize;
2060 pBbParams->BbArgs = pInputBbParams->BbArgs;
2061
2062 eStatus = MOS_STATUS_SUCCESS;
2063
2064 finish:
2065 *ppBatchBuffer = pBatchBuffer;
2066 return eStatus;
2067 }
2068
2069 //!
2070 //! \brief Update max src rect in VphalRenderer and primary surface based
2071 //! on src rectangle info from primary video
2072 //! \details Add max src rect for consistent statistics surface layout. Update
2073 //! the max src rect of the surface and its reference surfaces
2074 //! \param [in,out] pRenderer
2075 //! VPHAL renderer pointer
2076 //! \param [in,out] pSurface
2077 //! Pointer to the surface
2078 //! \return void
2079 //!
VpHal_RenderInitMaxRect(VphalRenderer * pRenderer,PVPHAL_SURFACE pSurface)2080 void VpHal_RenderInitMaxRect(
2081 VphalRenderer *pRenderer,
2082 PVPHAL_SURFACE pSurface)
2083 {
2084 PVPHAL_SURFACE pRef;
2085 uint32_t i;
2086
2087 pSurface->bMaxRectChanged =
2088 (pSurface->rcSrc.right > pRenderer->maxSrcRect.right ||
2089 pSurface->rcSrc.bottom > pRenderer->maxSrcRect.bottom) ?
2090 true : false;
2091
2092 // calcualte max srcRect in pRenderParams
2093 pRenderer->maxSrcRect.right = MOS_MAX(
2094 pRenderer->maxSrcRect.right, pSurface->rcSrc.right);
2095 pRenderer->maxSrcRect.bottom = MOS_MAX(
2096 pRenderer->maxSrcRect.bottom, pSurface->rcSrc.bottom);
2097
2098 // copy max src rect to primary video
2099 pSurface->rcMaxSrc = pRenderer->maxSrcRect;
2100
2101 // copy max src rect to forward reference video
2102 pRef = pSurface->pFwdRef;
2103 for (i = 0; i < pSurface->uFwdRefCount; i++)
2104 {
2105 // check surface validity
2106 VPHAL_RENDER_CHK_NULL_NO_STATUS(pRef);
2107
2108 pRef->rcMaxSrc = pRenderer->maxSrcRect;
2109
2110 // get next forward reference
2111 pRef = pRef->pFwdRef;
2112 }
2113
2114 // copy max src rect to backward reference video
2115 pRef = pSurface->pBwdRef;
2116 for (i = 0; i < pSurface->uBwdRefCount; i++)
2117 {
2118 // check surface validity
2119 VPHAL_RENDER_CHK_NULL_NO_STATUS(pRef);
2120
2121 pRef->rcMaxSrc = pRenderer->maxSrcRect;
2122
2123 // get next backward reference
2124 pRef = pRef->pBwdRef;
2125 }
2126
2127 finish:
2128 return;
2129 }
2130
2131 //!
2132 //! \brief Allocate surface dumper
2133 //! \return MOS_STATUS
2134 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
2135 //!
CreateSurfaceDumper()2136 MOS_STATUS VphalRenderer::CreateSurfaceDumper()
2137 {
2138 #if (_DEBUG || _RELEASE_INTERNAL)
2139 VPHAL_DBG_SURF_DUMP_CREATE()
2140 VPHAL_RENDER_CHK_NULL_RETURN(m_surfaceDumper);
2141 #endif
2142 return MOS_STATUS_SUCCESS;
2143 }
2144
AllocateDebugDumper()2145 MOS_STATUS VphalRenderer::AllocateDebugDumper()
2146 {
2147 PRENDERHAL_INTERFACE pRenderHal = m_pRenderHal;
2148 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2149 // Allocate feature report
2150 m_reporting = MOS_New(VphalFeatureReport);
2151 if (m_reporting == nullptr)
2152 {
2153 VPHAL_RENDER_ASSERTMESSAGE("Invalid null pointer!");
2154 eStatus = MOS_STATUS_NULL_POINTER;
2155 goto finish;
2156 }
2157
2158 #if (_DEBUG || _RELEASE_INTERNAL)
2159
2160 // Initialize Surface Dumper
2161 VPHAL_RENDER_CHK_STATUS(CreateSurfaceDumper());
2162
2163 // Initialize State Dumper
2164 VPHAL_DBG_STATE_DUMPPER_CREATE()
2165 if (pRenderHal->pStateDumper == nullptr)
2166 {
2167 VPHAL_RENDER_ASSERTMESSAGE("Invalid null pointer!");
2168 eStatus = MOS_STATUS_NULL_POINTER;
2169 goto finish;
2170 }
2171
2172 VPHAL_DBG_PARAMETERS_DUMPPER_CREATE()
2173
2174 if (m_parameterDumper == nullptr)
2175 {
2176 VPHAL_RENDER_ASSERTMESSAGE("Invalid null pointer!");
2177 eStatus = MOS_STATUS_NULL_POINTER;
2178 goto finish;
2179 }
2180
2181 // if m_isApoEnabled is false dump in legacy path, otherwise in APO path
2182 if (!m_isApoEnabled)
2183 {
2184 SkuWaTable_DUMPPER_DUMP_XML(m_pSkuTable, m_pWaTable);
2185 }
2186
2187 #endif
2188
2189 // vphal oca dumper object should also be created for release driver.
2190 VPHAL_DBG_OCA_DUMPER_CREATE(pRenderHal)
2191 if (nullptr == pRenderHal->pVphalOcaDumper)
2192 {
2193 VPHAL_RENDER_ASSERTMESSAGE("Invalid null pointer!");
2194 eStatus = MOS_STATUS_NULL_POINTER;
2195 goto finish;
2196 }
2197
2198 finish:
2199 if (eStatus != MOS_STATUS_SUCCESS)
2200 {
2201 if (m_reporting)
2202 {
2203 MOS_Delete(m_reporting);
2204 m_reporting = nullptr;
2205 }
2206
2207 #if (_DEBUG || _RELEASE_INTERNAL)
2208
2209 if (m_surfaceDumper)
2210 {
2211 VPHAL_DBG_SURF_DUMP_DESTORY(m_surfaceDumper)
2212 }
2213
2214 if (pRenderHal->pStateDumper)
2215 {
2216 VPHAL_DBG_STATE_DUMPPER_DESTORY(pRenderHal->pStateDumper)
2217 }
2218 #endif
2219 VPHAL_DBG_OCA_DUMPER_DESTORY(pRenderHal)
2220
2221 }
2222
2223 return eStatus;
2224 }
2225
2226 //!
2227 //! \brief Get Hdr path needed flag
2228 //! \details Get Hdr path needed flag
2229 //! \param pRenderParams
2230 //! [in] Pointer to VPHAL render parameter
2231 //! \param pRenderPassData
2232 //! [in,out] Pointer to the VPHAL render pass data
2233 //! \return MOS_STATUS
2234 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
2235 //!
GetHdrPathNeededFlag(PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)2236 MOS_STATUS VphalRenderer::GetHdrPathNeededFlag(
2237 PVPHAL_RENDER_PARAMS pRenderParams,
2238 RenderpassData *pRenderPassData)
2239 {
2240 MOS_STATUS eStatus;
2241 uint32_t uiIndex;
2242 PVPHAL_SURFACE pSrcSurface;
2243 PVPHAL_SURFACE pTargetSurface;
2244 bool bToneMapping;
2245 bool bBt2020Output;
2246 bool bMultiLayerBt2020;
2247
2248 //--------------------------------------------
2249 VPHAL_RENDER_CHK_NULL(pRenderParams);
2250 VPHAL_RENDER_CHK_NULL(pRenderPassData);
2251 VPHAL_RENDER_CHK_NULL(pRenderParams->pTarget[0]);
2252 //--------------------------------------------
2253
2254 eStatus = MOS_STATUS_SUCCESS;
2255 uiIndex = 0;
2256 pSrcSurface = nullptr;
2257 pTargetSurface = nullptr;
2258 bToneMapping = false;
2259 bBt2020Output = false;
2260 bMultiLayerBt2020 = false;
2261
2262 // Loop through the sources
2263 for (uiIndex = 0;
2264 uiIndex < VPHAL_MAX_SOURCES && uiIndex < pRenderParams->uSrcCount;
2265 uiIndex++)
2266 {
2267 pSrcSurface = pRenderParams->pSrc[uiIndex];
2268 if (pSrcSurface == nullptr)
2269 {
2270 continue;
2271 }
2272 pTargetSurface = pRenderParams->pTarget[0];
2273
2274 // Need to use HDR to process BT601/BT709->BT2020
2275 if (IS_COLOR_SPACE_BT2020(pRenderParams->pTarget[0]->ColorSpace) &&
2276 !IS_COLOR_SPACE_BT2020(pSrcSurface->ColorSpace))
2277 {
2278 bBt2020Output = true;
2279 }
2280
2281 if ((pSrcSurface->pHDRParams && (pSrcSurface->pHDRParams->EOTF != VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_SDR)) ||
2282 (pTargetSurface->pHDRParams && (pTargetSurface->pHDRParams->EOTF != VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_SDR)))
2283 {
2284 bToneMapping = true;
2285 }
2286
2287 if (IS_COLOR_SPACE_BT2020(pSrcSurface->ColorSpace) && pRenderParams->uSrcCount > 1)
2288 {
2289 bMultiLayerBt2020 = true;
2290 }
2291 }
2292
2293 pRenderPassData->bHdrNeeded = bBt2020Output || bToneMapping || bMultiLayerBt2020;
2294
2295 // Error handling for illegal Hdr cases on unsupported m_Platform
2296 if ((pRenderPassData->bHdrNeeded) && (!MEDIA_IS_SKU(m_pSkuTable, FtrHDR)))
2297 {
2298 eStatus = MOS_STATUS_SUCCESS;
2299 VPHAL_RENDER_ASSERTMESSAGE("Illegal Hdr cases on unsupported m_Platform, turn off HDR.");
2300 pRenderPassData->bHdrNeeded = false;
2301 }
2302
2303 if (pRenderPassData->bHdrNeeded)
2304 {
2305 pRenderPassData->bCompNeeded = false;
2306 }
2307
2308 if (!pRenderPassData->bHdrNeeded &&
2309 pRenderParams->pSrc[0] &&
2310 pRenderParams->pTarget[0] &&
2311 IS_COLOR_SPACE_BT2020(pRenderParams->pSrc[0]->ColorSpace) &&
2312 !IS_COLOR_SPACE_BT2020(pRenderParams->pTarget[0]->ColorSpace) &&
2313 MEDIA_IS_SKU(m_pSkuTable, FtrDisableVEBoxFeatures))
2314 {
2315 eStatus = MOS_STATUS_INVALID_PARAMETER;
2316 VPHAL_RENDER_ASSERTMESSAGE("Invalid Params for This Platform.");
2317 }
2318
2319 finish:
2320 return eStatus;
2321 }
2322