xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/vp/hal/vphal_renderer.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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