1 /*
2 * Copyright (c) 2011-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     vphal_render_vebox_base.cpp
24 //! \brief    Common interface used in Vebox
25 //! \details  Common interface used in Vebox which are platform independent
26 //!
27 
28 #include "vphal.h"
29 #include "vphal_render_vebox_base.h"
30 #include "vphal_debug.h"
31 #include "vphal_renderer.h"
32 #include "vphal_render_vebox_util_base.h"
33 
34 #include "vphal_render_common.h"
35 #include "renderhal_platform_interface.h"
36 #include "hal_oca_interface.h"
37 #include <string>
38 
39 extern const Kdll_Layer g_cSurfaceType_Layer[];
40 
41 extern const VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATION g_cInit_VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATION =
42 {
43     // DWORD 0
44     {
45         {NOISE_BLF_RANGE_THRESHOLD_S0_DEFAULT},           // RangeThrStart0
46     },
47 
48     // DWORD 1
49     {
50         {NOISE_BLF_RANGE_THRESHOLD_S1_DEFAULT},           // RangeThrStart1
51     },
52 
53     // DWORD 2
54     {
55         {NOISE_BLF_RANGE_THRESHOLD_S2_DEFAULT},           // RangeThrStart2
56     },
57 
58     // DWORD 3
59     {
60         {NOISE_BLF_RANGE_THRESHOLD_S3_DEFAULT},           // RangeThrStart3
61     },
62 
63     // DWORD 4
64     {
65         {NOISE_BLF_RANGE_THRESHOLD_S4_DEFAULT},           // RangeThrStart4
66     },
67 
68     // DWORD 5
69     {
70         {NOISE_BLF_RANGE_THRESHOLD_S5_DEFAULT},           // RangeThrStart5
71     },
72 
73     // DWORD 6
74     {
75         {0},                                              // Reserved
76     },
77 
78     // DWORD 7
79     {
80         {0},                                              // Reserved
81     },
82 
83     // DWORD 8
84     {
85         {NOISE_BLF_RANGE_WGTS0_DEFAULT},                  // RangeWgt0
86     },
87 
88     // DWORD 9
89     {
90         {NOISE_BLF_RANGE_WGTS1_DEFAULT},                  // RangeWgt1
91     },
92 
93     // DWORD 10
94     {
95         {NOISE_BLF_RANGE_WGTS2_DEFAULT},                  // RangeWgt2
96     },
97 
98     // DWORD 11
99     {
100         {NOISE_BLF_RANGE_WGTS3_DEFAULT},                  // RangeWgt3
101     },
102 
103     // DWORD 12
104     {
105         {NOISE_BLF_RANGE_WGTS4_DEFAULT},                  // RangeWgt4
106     },
107 
108     // DWORD 13
109     {
110         {NOISE_BLF_RANGE_WGTS5_DEFAULT},                  // RangeWgt5
111     },
112 
113     // DWORD 14
114     {
115         {0},                                              // Reserved
116     },
117 
118     // DWORD 15
119     {
120         {0},                                              // Reserved
121     },
122 
123     // DWORD 16 - 41: DistWgt[5][5]
124     {
125         {NOISE_BLF_DISTANCE_WGTS00_DEFAULT, NOISE_BLF_DISTANCE_WGTS01_DEFAULT, NOISE_BLF_DISTANCE_WGTS02_DEFAULT, NOISE_BLF_DISTANCE_WGTS01_DEFAULT, NOISE_BLF_DISTANCE_WGTS00_DEFAULT},
126         {NOISE_BLF_DISTANCE_WGTS10_DEFAULT, NOISE_BLF_DISTANCE_WGTS11_DEFAULT, NOISE_BLF_DISTANCE_WGTS12_DEFAULT, NOISE_BLF_DISTANCE_WGTS11_DEFAULT, NOISE_BLF_DISTANCE_WGTS10_DEFAULT},
127         {NOISE_BLF_DISTANCE_WGTS20_DEFAULT, NOISE_BLF_DISTANCE_WGTS21_DEFAULT, NOISE_BLF_DISTANCE_WGTS22_DEFAULT, NOISE_BLF_DISTANCE_WGTS21_DEFAULT, NOISE_BLF_DISTANCE_WGTS20_DEFAULT},
128         {NOISE_BLF_DISTANCE_WGTS10_DEFAULT, NOISE_BLF_DISTANCE_WGTS11_DEFAULT, NOISE_BLF_DISTANCE_WGTS12_DEFAULT, NOISE_BLF_DISTANCE_WGTS11_DEFAULT, NOISE_BLF_DISTANCE_WGTS10_DEFAULT},
129         {NOISE_BLF_DISTANCE_WGTS00_DEFAULT, NOISE_BLF_DISTANCE_WGTS01_DEFAULT, NOISE_BLF_DISTANCE_WGTS02_DEFAULT, NOISE_BLF_DISTANCE_WGTS01_DEFAULT, NOISE_BLF_DISTANCE_WGTS00_DEFAULT},
130     },
131 
132     // Padding
133     {
134         0,                                      // Padding
135         0,                                      // Padding
136         0,                                      // Padding
137         0,                                      // Padding
138         0,                                      // Padding
139         0,                                      // Padding
140         0,                                      // Padding
141     }
142 };
143 
144 //!
145 //! \brief    Send Vecs Status Tag
146 //! \details  Add MI Flush with write back into command buffer for GPU to write
147 //!           back GPU Tag. This should be the last command in 1st level batch.
148 //!           This ensures sync tag will be written after rendering is complete.
149 //! \param    [in] pMhwMiInterface
150 //!           MHW MI interface
151 //! \param    [in] pOsInterface
152 //!           Pointer to OS Interface
153 //! \param    [out] pCmdBuffer
154 //!           Pointer to Command Buffer
155 //! \return   MOS_STATUS
156 //!
VeboxSendVecsStatusTag(PMHW_MI_INTERFACE pMhwMiInterface,PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer)157 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSendVecsStatusTag(
158     PMHW_MI_INTERFACE                   pMhwMiInterface,
159     PMOS_INTERFACE                      pOsInterface,
160     PMOS_COMMAND_BUFFER                 pCmdBuffer)
161 {
162     PMOS_RESOURCE                       gpuStatusBuffer = nullptr;
163     MHW_MI_FLUSH_DW_PARAMS              FlushDwParams;
164     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
165 
166     //------------------------------------
167     VPHAL_RENDER_CHK_NULL(pMhwMiInterface);
168     VPHAL_RENDER_CHK_NULL(pOsInterface);
169     VPHAL_RENDER_CHK_NULL(pCmdBuffer);
170     //------------------------------------
171 
172 #if !EMUL
173     // Get GPU Status buffer
174     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetGpuStatusBufferResource(
175         pOsInterface,
176         gpuStatusBuffer));
177     VPHAL_RENDER_CHK_NULL(gpuStatusBuffer);
178     // Register the buffer
179     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(
180         pOsInterface,
181         gpuStatusBuffer,
182         true,
183         true));
184 
185     MOS_ZeroMemory(&FlushDwParams, sizeof(FlushDwParams));
186     FlushDwParams.pOsResource       = gpuStatusBuffer;
187     FlushDwParams.dwResourceOffset  = pOsInterface->pfnGetGpuStatusTagOffset(pOsInterface, MOS_GPU_CONTEXT_VEBOX);
188     FlushDwParams.dwDataDW1         = pOsInterface->pfnGetGpuStatusTag(pOsInterface, MOS_GPU_CONTEXT_VEBOX);
189     VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiFlushDwCmd(
190         pCmdBuffer,
191         &FlushDwParams));
192 
193     // Increase buffer tag for next usage
194     pOsInterface->pfnIncrementGpuStatusTag(pOsInterface, MOS_GPU_CONTEXT_VEBOX);
195 #endif
196 
197 finish:
198     return eStatus;
199 }
200 
201 //!
202 //! \brief    Initialize VEBOX state
203 //! \param    [in] pSettings
204 //!           Pointer to VPHAL settings
205 //! \param    [in] pKernelDllState
206 //!           Pointer to KDLL state
207 //! \return   MOS_STATUS
208 //!           MOS_STATUS_SUCCESS if successful, otherwise failed
209 //!
Initialize(const VphalSettings * pSettings,Kdll_State * pKernelDllState)210 MOS_STATUS VPHAL_VEBOX_STATE::Initialize(
211     const VphalSettings         *pSettings,
212     Kdll_State                  *pKernelDllState)
213 {
214     MOS_STATUS                          eStatus;
215     PRENDERHAL_INTERFACE                pRenderHal;
216     MOS_NULL_RENDERING_FLAGS            NullRenderingFlags;
217     PVPHAL_VEBOX_STATE                  pVeboxState = this;
218     uint32_t                            customValue = VPHAL_COMP_BYPASS_ENABLED;
219 
220     eStatus      = MOS_STATUS_SUCCESS;
221     pRenderHal   = pVeboxState->m_pRenderHal;
222 
223     if (m_reporting == nullptr)
224     {
225         m_reporting = MOS_New(VphalFeatureReport);
226     }
227 
228     if (pRenderHal == nullptr)
229     {
230         eStatus = MOS_STATUS_UNKNOWN;
231         goto finish;
232     }
233 
234     if (!m_currentSurface)
235     {
236         m_currentSurface = (VPHAL_SURFACE*)MOS_AllocAndZeroMemory(sizeof(VPHAL_SURFACE));
237         if (!m_currentSurface)
238         {
239             return MOS_STATUS_NO_SPACE;
240         }
241     }
242 
243     if (!m_previousSurface)
244     {
245         m_previousSurface = (VPHAL_SURFACE*)MOS_AllocAndZeroMemory(sizeof(VPHAL_SURFACE));
246         if (!m_previousSurface)
247         {
248             return MOS_STATUS_NO_SPACE;
249         }
250     }
251 
252     for (uint32_t i = 0; i < VPHAL_NUM_FFDN_SURFACES; i++)
253     {
254         if (!FFDNSurfaces[i])
255         {
256             FFDNSurfaces[i] = (VPHAL_SURFACE*)MOS_AllocAndZeroMemory(sizeof(VPHAL_SURFACE));
257             if (!FFDNSurfaces[i])
258             {
259                 return MOS_STATUS_NO_SPACE;
260             }
261         }
262     }
263 
264     for (uint32_t i = 0; i < VPHAL_MAX_NUM_FFDI_SURFACES; i++)
265     {
266         if (!FFDISurfaces[i])
267         {
268             FFDISurfaces[i] = (VPHAL_SURFACE*)MOS_AllocAndZeroMemory(sizeof(VPHAL_SURFACE));
269             if (!FFDISurfaces[i])
270             {
271                 return MOS_STATUS_NO_SPACE;
272             }
273         }
274     }
275 
276     // Initial IECP modules
277     if (!m_IECP)
278     {
279         m_IECP = MOS_New(VPHAL_VEBOX_IECP_RENDERER);
280         if (!m_IECP)
281         {
282             return MOS_STATUS_NO_SPACE;
283         }
284     }
285     m_IECP->m_veboxState = this;
286     m_IECP->m_renderData = pVeboxState->GetLastExecRenderData();
287 
288     if (MEDIA_IS_SKU(m_pSkuTable, FtrSFCPipe) && !m_sfcPipeState)
289     {
290 #if __VPHAL_SFC_SUPPORTED
291         m_sfcPipeState = CreateSfcState();
292 #else
293         m_sfcPipeState = MOS_New(VphalSfcState, m_pOsInterface, m_pRenderHal, m_pSfcInterface);
294 #endif
295         if (!m_sfcPipeState)
296         {
297             return MOS_STATUS_NO_SPACE;
298         }
299     }
300 
301     //Initial SFC temp surface
302     if (!m_sfcTempSurface)
303     {
304         m_sfcTempSurface = MOS_New(VPHAL_SURFACE);
305         VPHAL_RENDER_CHK_NULL(m_sfcTempSurface);
306     }
307 
308     if (!m_sfc2ndTempSurface)
309     {
310         m_sfc2ndTempSurface = MOS_New(VPHAL_SURFACE);
311         VPHAL_RENDER_CHK_NULL(m_sfc2ndTempSurface);
312     }
313 
314     // Vebox Comp Bypass is on by default
315     pVeboxState->dwCompBypassMode = VPHAL_COMP_BYPASS_ENABLED;
316 
317     // Read user feature key to get the Composition Bypass mode
318     // Vebox Comp Bypass is on by default
319     ReadUserSetting(
320         m_userSettingPtr,
321         pVeboxState->dwCompBypassMode,
322         __VPHAL_BYPASS_COMPOSITION,
323         MediaUserSetting::Group::Sequence,
324         customValue,
325         true);
326 
327     if (MEDIA_IS_SKU(pVeboxState->m_pSkuTable, FtrSFCPipe) &&
328         m_sfcPipeState)
329     {
330         // Read user feature key to Disable SFC
331         bool disableSfc = 0;
332         ReadUserSetting(
333             m_userSettingPtr,
334             disableSfc,
335             __VPHAL_VEBOX_DISABLE_SFC,
336             MediaUserSetting::Group::Sequence);
337         m_sfcPipeState->SetDisable(disableSfc ? true : false);
338     }
339 
340     pVeboxState->bEnableMMC = 0;
341     pVeboxState->bDisableTemporalDenoiseFilter = 0;
342     pVeboxState->bDisableTemporalDenoiseFilterUserKey = 0;
343 
344     NullRenderingFlags  = pVeboxState->m_pOsInterface->pfnGetNullHWRenderFlags(
345                         pVeboxState->m_pOsInterface);
346 
347     pVeboxState->bNullHwRenderDnDi    =
348                     NullRenderingFlags.VPDnDi ||
349                     NullRenderingFlags.VPGobal;
350 
351     // Setup disable render flag controlled by a user feature key for validation purpose
352     pVeboxState->SetRenderDisableFlag( pSettings->disableDnDi == false ? false : true );
353 
354     // Enable/Disable kernel Copy/Update for VEBox
355     pVeboxState->dwKernelUpdate = pSettings->kernelUpdate;
356 
357     // Setup Same Sample Threshold for VEBOX
358     pVeboxState->iSameSampleThreshold = pSettings->sameSampleThreshold;
359 
360     // Setup interface to KDLL
361     pVeboxState->m_pKernelDllState      = pKernelDllState;
362 
363     // Initialize State variables
364     pVeboxState->iCurFrameID          = FIRST_FRAME;
365     pVeboxState->iPrvFrameID          = FIRST_FRAME;
366     pVeboxState->bFirstFrame          = true;
367 
368     // Initialize Front End CSC
369     pVeboxState->fFeCscCoeff          = (float*)MOS_AllocAndZeroMemory(sizeof(float)*9);
370     pVeboxState->fFeCscInOffset       = (float*)MOS_AllocAndZeroMemory(sizeof(float)*3);
371     pVeboxState->fFeCscOutOffset      = (float*)MOS_AllocAndZeroMemory(sizeof(float)*3);
372 
373 finish:
374     return eStatus;
375 }
376 
377 //!
378 //! \brief    Destroy function
379 //! \details  Release all VEBOX related resources
380 //!           that needs virtual function and thus cannot be done in destructors
381 //! \return   void
382 //!
Destroy()383 void VPHAL_VEBOX_STATE::Destroy()
384 {
385     PVPHAL_VEBOX_STATE                  pVeboxState = this;
386 
387     if (pVeboxState)
388     {
389         MOS_SafeFreeMemory(pVeboxState->fFeCscCoeff);
390         MOS_SafeFreeMemory(pVeboxState->fFeCscInOffset);
391         MOS_SafeFreeMemory(pVeboxState->fFeCscOutOffset);
392 
393         // Free VEBOX allocations
394         if (MEDIA_IS_SKU(pVeboxState->m_pSkuTable, FtrVERing))
395         {
396             pVeboxState->FreeResources();
397         }
398     }
399 }
400 
401 //!
402 //! \brief    Copy Dndi Surface Params
403 //! \details  Copies surface params to output surface
404 //!           based on src and temp surfaces
405 //! \param    [in] pSrcSurface
406 //!           Pointer to Source Surface
407 //! \param    [in] pTempSurface
408 //!           Pointer to Temporary Surface
409 //! \param    [in,out] pOutSurface
410 //!           Pointer to Out Surface
411 //! \return   void
412 //!
VeboxCopySurfaceParams(const PVPHAL_SURFACE pSrcSurface,const PVPHAL_SURFACE pTempSurface,PVPHAL_SURFACE pOutSurface)413 void VPHAL_VEBOX_STATE::VeboxCopySurfaceParams(
414     const PVPHAL_SURFACE            pSrcSurface,
415     const PVPHAL_SURFACE            pTempSurface,
416     PVPHAL_SURFACE                  pOutSurface)
417 {
418     PMOS_INTERFACE                  pOsInterface        = nullptr;
419     const PVPHAL_VEBOX_STATE        pVeboxState         = this;
420     const PVPHAL_VEBOX_RENDER_DATA  pRenderData         = GetLastExecRenderData();
421 
422     pOsInterface = pVeboxState->m_pOsInterface;
423 
424     VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderData);
425     VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrcSurface);
426     VPHAL_RENDER_CHK_NULL_NO_STATUS(pTempSurface);
427     VPHAL_RENDER_CHK_NULL_NO_STATUS(pOutSurface);
428     VPHAL_RENDER_CHK_NULL_NO_STATUS(pOsInterface);
429 
430     // Copy all parameters from SrcSurface to Output Surface
431     CopySurfaceValue(pOutSurface, pSrcSurface);
432 
433     // Disable variance query if applicable
434     if (pVeboxState->IsQueryVarianceEnabled())
435     {
436         pOutSurface->bQueryVariance = false;
437     }
438 
439     // Use original input as AdvProc's output (may occur in Variance)
440     if (pSrcSurface == pTempSurface)
441     {
442         goto finish;
443     }
444 
445     // Copy relevant surf params from Temp Surface to Output surface
446     pOutSurface->OsResource         = pTempSurface->OsResource;
447     pOutSurface->Format             = pTempSurface->Format;
448     pOutSurface->dwHeight           = pTempSurface->dwHeight;
449     pOutSurface->dwWidth            = pTempSurface->dwWidth;
450     pOutSurface->dwPitch            = pTempSurface->dwPitch;
451     pOutSurface->TileType           = pTempSurface->TileType;
452     pOutSurface->TileModeGMM        = pTempSurface->TileModeGMM;
453     pOutSurface->bGMMTileEnabled    = pTempSurface->bGMMTileEnabled;
454     pOutSurface->SampleType         = pTempSurface->SampleType;
455     pOutSurface->ColorSpace         = pTempSurface->ColorSpace;
456     pOutSurface->dwOffset           = pTempSurface->dwOffset;
457     pOutSurface->YPlaneOffset       = pTempSurface->YPlaneOffset;
458     pOutSurface->UPlaneOffset       = pTempSurface->UPlaneOffset;
459     pOutSurface->VPlaneOffset       = pTempSurface->VPlaneOffset;
460     pOutSurface->bCompressible      = pTempSurface->bCompressible;
461     pOutSurface->bIsCompressed      = pTempSurface->bIsCompressed;
462     pOutSurface->CompressionMode    = pTempSurface->CompressionMode;
463 
464     // Reset deinterlace params if applicable
465     if (pRenderData->bDeinterlace)
466     {
467         pOutSurface->pDeinterlaceParams = nullptr;
468     }
469 
470     // Reset Allocations
471     pOsInterface->pfnResetResourceAllocationIndex(
472         pOsInterface,
473         &pOutSurface->OsResource);
474 
475 finish:
476     return;
477 }
478 
479 //!
480 //! \brief    Setup reference surfaces
481 //! \details  Setup reference surfaces for app feeds reference case and
482 //!           no reference frame case
483 //! \param    [in] pSrcSurface
484 //!           Pointer to Source Surface
485 //! \return   PVPHAL_SURFACE
486 //!           Pointer to Reference surface or nullptr if no reference
487 //!
VeboxSetReference(PVPHAL_SURFACE pSrcSurface)488 PVPHAL_SURFACE VPHAL_VEBOX_STATE::VeboxSetReference(
489     PVPHAL_SURFACE              pSrcSurface)
490 {
491     PVPHAL_SURFACE pRefSurface = nullptr;
492     PVPHAL_VEBOX_STATE          pVeboxState = this;
493     PVPHAL_VEBOX_RENDER_DATA    pRenderData = GetLastExecRenderData();
494 
495     VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderData);
496     if (pRenderData->bRefValid)
497     {
498         // Set the Reference surface
499         if (IS_VEBOX_EXECUTION_MODE_2(pVeboxState->m_pVeboxExecState))
500         {
501             // Vebox defines reference as previous input frame.
502             // In this mode, treat current as the previous
503             pRefSurface = pSrcSurface;
504         }
505         else
506         {
507             pRefSurface = pSrcSurface->pBwdRef;
508             VPHAL_RENDER_ASSERT( pRefSurface && pSrcSurface->uBwdRefCount > 0);
509         }
510 
511         // Discontinuity - hence can't reuse previous surfaces
512         if (!pRenderData->bSameSamples && pRenderData->bOutOfBound)
513         {
514             if (pRenderData->bDenoise &&
515                 !Mos_ResourceIsNull(&pVeboxState->m_currentSurface->OsResource))
516             {
517                 // Save prev call's current sample as prev sample for current call
518                 CopySurfaceValue(pVeboxState->m_previousSurface, pVeboxState->m_currentSurface);
519                 pVeboxState->m_previousSurface->FrameID = pRefSurface->FrameID;
520             }
521             else if ((pRenderData->bEnableMMC || IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData)) &&
522                      pRenderData->bDenoise &&
523                      pRenderData->bDeinterlace &&
524                      Mos_ResourceIsNull(&pVeboxState->m_currentSurface->OsResource))
525             {
526                 // In WHCK test, there is a special test.Test app will set future / post reference frame for frame 0.
527                 // Then, frame 0 will do deinterlace using uncompressed reference frame instead of denoised compressed frames if MMC on.
528                 // If using reference frame to do ADI deinterlace, there is corruption with previous DI frame of the VEBOX output which output by SFC.
529                 pRenderData->bRefValid = false;
530             }
531             else
532             {
533                 // Save cur sample as prev for next call
534                 CopySurfaceValue(pVeboxState->m_previousSurface, pRefSurface);
535             }
536             pVeboxState->VeboxClearFmdStates();
537             VPHAL_RENDER_NORMALMESSAGE("Discontinuity.");
538         }
539         else
540         {
541             if (Mos_ResourceIsNull(&pVeboxState->m_currentSurface->OsResource))
542             {
543                 // If Current Resource is not valid, always set the
544                 // previous surface as Reference surface
545                 CopySurfaceValue(pVeboxState->m_previousSurface, pRefSurface);
546             }
547             else
548             {
549                 if (pRenderData->bDenoise)
550                 {
551                     // Save prev call's current sample as prev sample for current call
552                     CopySurfaceValue(pVeboxState->m_previousSurface, pVeboxState->m_currentSurface);
553                     pVeboxState->m_previousSurface->FrameID = pRefSurface->FrameID;
554                 }
555                 else
556                 {
557                     // Use application supplied reference frame
558                     CopySurfaceValue(pVeboxState->m_previousSurface, pRefSurface);
559                 }
560             }
561         }
562     }
563 
564     if (!pRenderData->bRefValid)    // No Reference frame provided.
565     {
566         // Disable FMD.
567         if (!IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData))
568         {
569             pVeboxState->VeboxClearFmdStates();
570         }
571 
572         if (pRenderData->bDenoise &&
573             (pSrcSurface->SampleType == SAMPLE_PROGRESSIVE))
574         {
575 
576             //  The first "current" frame may not have a resource (i.e. no
577             //  memory has been allocated for this image surface.
578             //  All subsequent frames should have a resource.
579             if (!Mos_ResourceIsNull(&pVeboxState->m_currentSurface->OsResource))
580             {
581                 // At this stage, the CurrentSurface contains the Denoise output
582                 // from the previous iteration.
583                 CopySurfaceValue(pVeboxState->m_previousSurface, pVeboxState->m_currentSurface);
584 
585                 pRefSurface = pVeboxState->m_previousSurface;
586                 pRenderData->bRefValid = true;
587             }
588         }
589         else if (pRenderData->bDeinterlace)
590         {
591             // Force DI when there is no ref sample
592             // Update Surfaces DI params
593             pSrcSurface->pDeinterlaceParams->bSingleField = true;
594             pRenderData->bSingleField = true;
595 
596             VPHAL_RENDER_NORMALMESSAGE("BOB using VEBOX h/w (no ref sample).");
597         }
598     }
599 
600 finish:
601     return pRefSurface;
602 }
603 
604 //!
605 //! \brief    Set DI output sample
606 //! \details  Set DI sample to be used for compositing stage followed by VEBOX
607 //!           feature reporting
608 //! \param    [in] pSrcSurface
609 //!           Pointer to Source Surface
610 //! \param    [in,out] pOutputSurface
611 //!           Pointer to Output Surface
612 //! \return   MOS_STATUS
613 //!           MOS_STATUS_SUCCESS if no error else MOS_STATUS_UNKNOWN
614 //!
VeboxSetDiOutput(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutputSurface)615 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSetDiOutput(
616     PVPHAL_SURFACE              pSrcSurface,
617     PVPHAL_SURFACE              pOutputSurface)
618 {
619     PVPHAL_SURFACE  pDstSurface;
620     int32_t         iFrame0;
621     int32_t         iFrame1;
622     PVPHAL_VEBOX_STATE          pVeboxState = this;
623     PVPHAL_VEBOX_RENDER_DATA    pRenderData = GetLastExecRenderData();
624 
625     VPHAL_RENDER_CHK_NULL_RETURN(pRenderData);
626     if (pRenderData->bDeinterlace)
627     {
628         if (pVeboxState->m_pVeboxExecState->bDIOutputPair01)
629         {
630             iFrame0 = 0;
631             iFrame1 = 1;
632         }
633         else
634         {
635             iFrame0 = 2;
636             iFrame1 = 3;
637         }
638 
639         // for 30i->60fps + Comp
640         if (pRenderData->b60fpsDi)
641         {
642             // Output 1st field of current frame according to DDI flag
643             if (pRenderData->bSingleField                                               ||
644                 (pSrcSurface->SampleType == SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD)     ||
645                 (pSrcSurface->SampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD) ||
646                 (pSrcSurface->SampleType == SAMPLE_SINGLE_BOTTOM_FIELD)                 ||
647                 (pSrcSurface->SampleType == SAMPLE_PROGRESSIVE))
648             {
649                 pDstSurface = pVeboxState->FFDISurfaces[iFrame1];
650             }
651             else
652             {
653                 // First sample output - 2nd field of the previous frame
654                 pDstSurface = pVeboxState->FFDISurfaces[iFrame0];
655             }
656         }
657         // for 30i->30fps + Comp, which differentiates from 30i->60fps for the correct
658         // output according to SampleType input
659         // eg. TF/BF matches with {0,2,4,6...}/{0,1,3,5...} output
660         else
661         {
662             // Output 1st field of current frame according to DDI flag
663             if (pRenderData->bSingleField                                              ||
664                 (pSrcSurface->SampleType == SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD) ||
665                 (pSrcSurface->SampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD)   ||
666                 (pSrcSurface->SampleType == SAMPLE_SINGLE_TOP_FIELD)                   ||
667                 (pSrcSurface->SampleType == SAMPLE_PROGRESSIVE))
668             {
669                 pDstSurface = pVeboxState->FFDISurfaces[iFrame1];
670             }
671             else
672             {
673                 // First sample output - 2nd field of the previous frame
674                 pDstSurface = pVeboxState->FFDISurfaces[iFrame0];
675             }
676         }
677      }
678      else if (pRenderData->bIECP)
679      {
680          // IECP output
681          pDstSurface = pVeboxState->FFDISurfaces[pRenderData->iCurDNOut];
682      }
683      else if (pRenderData->bDenoise)
684      {
685          // Denoise output
686          pDstSurface = pVeboxState->FFDNSurfaces[pRenderData->iCurDNOut];
687      }
688      else
689      {
690          VPHAL_RENDER_ASSERTMESSAGE("incorrect dndi output.");
691          return MOS_STATUS_UNKNOWN;
692      }
693 
694     //----------------------------
695     // VEBOX feature reporting
696     //----------------------------
697      m_reporting->GetFeatures().iecp    = IsIECPEnabled();
698      m_reporting->GetFeatures().denoise = pRenderData->bDenoise;
699     if (pRenderData->bDeinterlace)
700     {
701         m_reporting->GetFeatures().deinterlaceMode =
702             (pRenderData->bSingleField && !pRenderData->bRefValid ) ?
703             VPHAL_DI_REPORT_ADI_BOB :    // VEBOX BOB
704             VPHAL_DI_REPORT_ADI;         // ADI
705     }
706 
707     // Copy relevant surf params from pDst to pOutput
708     VeboxCopySurfaceParams(
709         pSrcSurface,
710         pDstSurface,
711         pOutputSurface);
712 
713     return MOS_STATUS_SUCCESS;
714 }
715 
716 //!
717 //! \brief    Vebox Set PerfTag
718 //! \details  Set Vebox PerfTag: DN, DI and IECP
719 //! \param    [in] srcFmt
720 //!           Source surface format of Vebox
721 //! \return   MOS_STATUS
722 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
723 //!
VeboxSetPerfTag(MOS_FORMAT srcFmt)724 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSetPerfTag(
725     MOS_FORMAT               srcFmt)
726 {
727     MOS_STATUS     eStatus;
728     PVPHAL_PERFTAG pPerfTag;
729     PVPHAL_VEBOX_RENDER_DATA pRenderData = GetLastExecRenderData();
730 
731     eStatus  = MOS_STATUS_INVALID_PARAMETER;
732     pPerfTag = &pRenderData->PerfTag;
733 
734     switch (srcFmt)
735     {
736         case Format_NV12:
737             if (pRenderData->bDeinterlace ||
738                 IsQueryVarianceEnabled())
739             {
740                 if (pRenderData->bDenoise ||
741                     pRenderData->bChromaDenoise)
742                 {
743                     if (IsIECPEnabled())
744                     {
745                         *pPerfTag = VPHAL_NV12_DNDI_422CP;
746                     }
747                     else
748                     {
749                         *pPerfTag = VPHAL_NV12_DNDI_PA;
750                     }
751                 }
752                 else
753                 {
754                     if (IsIECPEnabled())
755                     {
756                         *pPerfTag = VPHAL_PL_DI_422CP;
757                     }
758                     else
759                     {
760                         *pPerfTag = VPHAL_PL_DI_PA;
761                     }
762                 }
763             }
764             else
765             {
766                 if (pRenderData->bDenoise ||
767                     pRenderData->bChromaDenoise)
768                 {
769                     if (IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
770                     {
771                         switch (pRenderData->pRenderTarget->Format)
772                         {
773                             case Format_NV12:
774                                 *pPerfTag = VPHAL_NV12_DN_420CP;
775                                 break;
776                             CASE_PA_FORMAT:
777                                 *pPerfTag = VPHAL_NV12_DN_422CP;
778                                 break;
779                             case Format_RGB32:
780                             case Format_A8R8G8B8:
781                             case Format_A8B8G8R8:
782                                 *pPerfTag = VPHAL_NV12_DN_RGB32CP;
783                                 break;
784                             case Format_P010:
785                             case Format_P016:
786                             case Format_Y410:
787                             case Format_Y416:
788                             case Format_Y210:
789                             case Format_Y216:
790                             case Format_AYUV:
791                             case Format_Y8:
792                             case Format_Y16S:
793                             case Format_Y16U:
794                             case Format_A16B16G16R16F:
795                             case Format_A16R16G16B16F:
796                                 *pPerfTag = VPHAL_NONE;
797                                 break;
798                             default:
799                                 VPHAL_RENDER_ASSERTMESSAGE("Output Format Not found.");
800                                 goto finish;
801                         }
802                     }
803                     else if (IsIECPEnabled())
804                     {
805                         *pPerfTag = VPHAL_NV12_DN_420CP;
806                     }
807                     else
808                     {
809                         *pPerfTag = VPHAL_NV12_DN_NV12;
810                     }
811                 }
812                 else
813                 {
814                     if (IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
815                     {
816                         switch (pRenderData->pRenderTarget->Format)
817                         {
818                             case Format_NV12:
819                                 *pPerfTag = VPHAL_NV12_420CP;
820                                 break;
821                             CASE_PA_FORMAT:
822                                 *pPerfTag = VPHAL_NV12_422CP;
823                                 break;
824                             case Format_RGB32:
825                                 *pPerfTag = VPHAL_NV12_RGB32CP;
826                                 break;
827                             case Format_A8R8G8B8:
828                             case Format_A8B8G8R8:
829                             case Format_R10G10B10A2:
830                             case Format_B10G10R10A2:
831                                 *pPerfTag = VPHAL_NV12_RGB32CP;
832                                 break;
833                             case Format_P010:
834                             case Format_P016:
835                             case Format_Y410:
836                             case Format_Y416:
837                             case Format_Y210:
838                             case Format_Y216:
839                             case Format_AYUV:
840                             case Format_Y8:
841                             case Format_Y16S:
842                             case Format_Y16U:
843                             case Format_A16B16G16R16F:
844                             case Format_A16R16G16B16F:
845                                 *pPerfTag = VPHAL_NONE;
846                                 break;
847                             default:
848                                 VPHAL_RENDER_ASSERTMESSAGE("Output Format Not found.");
849                                 goto finish;
850                         }
851                     }
852                     else
853                     {
854                         *pPerfTag = VPHAL_NV12_420CP;
855                     }
856                 }
857             }
858             break;
859 
860         CASE_PA_FORMAT:
861             if (pRenderData->bDeinterlace ||
862                 IsQueryVarianceEnabled())
863             {
864                 if (pRenderData->bDenoise ||
865                     pRenderData->bChromaDenoise)
866                 {
867                     if (IsIECPEnabled())
868                     {
869                         *pPerfTag = VPHAL_PA_DNDI_422CP;
870                     }
871                     else
872                     {
873                         *pPerfTag = VPHAL_PA_DNDI_PA;
874                     }
875                 }
876                 else
877                 {
878                     if (IsIECPEnabled())
879                     {
880                         *pPerfTag = VPHAL_PA_DI_422CP;
881                     }
882                     else
883                     {
884                         *pPerfTag = VPHAL_PA_DI_PA;
885                     }
886                 }
887             }
888             else
889             {
890                 if (pRenderData->bDenoise ||
891                     pRenderData->bChromaDenoise)
892                 {
893                     if (IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
894                     {
895                         switch (pRenderData->pRenderTarget->Format)
896                         {
897                             case Format_NV12:
898                                 *pPerfTag = VPHAL_PA_DN_420CP;
899                                 break;
900                             CASE_PA_FORMAT:
901                                 *pPerfTag = VPHAL_PA_DN_422CP;
902                                 break;
903                             case Format_RGB32:
904                                 *pPerfTag = VPHAL_PA_DN_RGB32CP;
905                                 break;
906                             case Format_P010:
907                             case Format_P016:
908                             case Format_Y410:
909                             case Format_Y416:
910                             case Format_Y210:
911                             case Format_Y216:
912                             case Format_AYUV:
913                             case Format_Y8:
914                             case Format_Y16S:
915                             case Format_Y16U:
916                             case Format_A16B16G16R16F:
917                             case Format_A16R16G16B16F:
918                                 *pPerfTag = VPHAL_NONE;
919                                 break;
920                             default:
921                                 VPHAL_RENDER_ASSERTMESSAGE("Output Format Not found.");
922                                 goto finish;
923                         }
924                     }
925                     else if (IsIECPEnabled())
926                     {
927                         *pPerfTag = VPHAL_PA_DN_422CP;
928                     }
929                     else
930                     {
931                         *pPerfTag = VPHAL_PA_DN_PA;
932                     }
933                 }
934                 else
935                 {
936                     if (IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
937                     {
938                         switch (pRenderData->pRenderTarget->Format)
939                         {
940                             case Format_NV12:
941                                 *pPerfTag = VPHAL_PA_420CP;
942                                 break;
943                             CASE_PA_FORMAT:
944                                 *pPerfTag = VPHAL_PA_422CP;
945                                 break;
946                             case Format_RGB32:
947                                 *pPerfTag = VPHAL_PA_RGB32CP;
948                                 break;
949                             case Format_A8R8G8B8:
950                             case Format_A8B8G8R8:
951                             case Format_R10G10B10A2:
952                             case Format_B10G10R10A2:
953                                 *pPerfTag = VPHAL_PA_RGB32CP;
954                                 break;
955                             case Format_P010:
956                             case Format_P016:
957                             case Format_Y410:
958                             case Format_Y416:
959                             case Format_Y210:
960                             case Format_Y216:
961                             case Format_AYUV:
962                             case Format_Y8:
963                             case Format_Y16S:
964                             case Format_Y16U:
965                             case Format_A16B16G16R16F:
966                             case Format_A16R16G16B16F:
967                                 *pPerfTag = VPHAL_NONE;
968                                 break;
969                             default:
970                                 VPHAL_RENDER_ASSERTMESSAGE("Output Format Not found.");
971                                 goto finish;
972                         }
973                     }
974                     else
975                     {
976                         *pPerfTag = VPHAL_PA_422CP;
977                     }
978                 }
979             }
980             break;
981 
982         case Format_AYUV:
983             break;
984 
985         CASE_RGB32_FORMAT:
986             // RGB Input Support for SFC
987             *pPerfTag = VPHAL_NONE;
988             break;
989 
990         case Format_P010:
991             // P010 Input Support for VEBOX, SFC
992             *pPerfTag = VPHAL_VEBOX_P010;
993             break;
994 
995         case Format_P016:
996             // P016 Input Support for VEBOX, SFC
997             *pPerfTag = VPHAL_VEBOX_P016;
998             break;
999 
1000         case Format_P210:
1001             // P210 Input Support for VEBOX, SFC
1002             *pPerfTag = VPHAL_VEBOX_P210;
1003             break;
1004 
1005         case Format_P216:
1006             // P216 Input Support for VEBOX, SFC
1007             *pPerfTag = VPHAL_VEBOX_P216;
1008             break;
1009 
1010         case Format_Y210:
1011             // Y210 Input Support for VEBOX, SFC
1012             *pPerfTag = VPHAL_VEBOX_Y210;
1013             break;
1014 
1015         case Format_Y216:
1016             // Y216 Input Support for VEBOX, SFC
1017             *pPerfTag = VPHAL_VEBOX_Y216;
1018             break;
1019 
1020         case Format_Y410:
1021             // Y410 Input Support for VEBOX, SFC
1022             *pPerfTag = VPHAL_VEBOX_Y410;
1023             break;
1024 
1025         case Format_Y416:
1026             // Y416 Input Support for VEBOX, SFC
1027             *pPerfTag = VPHAL_VEBOX_Y416;
1028             break;
1029 
1030         case Format_A16B16G16R16:
1031         case Format_A16R16G16B16:
1032         case Format_A16B16G16R16F:
1033         case Format_A16R16G16B16F:
1034             *pPerfTag = VPHAL_NONE;
1035             break;
1036 
1037         default:
1038             VPHAL_RENDER_ASSERTMESSAGE("Format Not found.");
1039             goto finish;
1040     } // switch (srcFmt)
1041 
1042     eStatus = MOS_STATUS_SUCCESS;
1043 
1044 finish:
1045     return eStatus;
1046 }
1047 
1048 //!
1049 //! \brief    Vebox Populate VEBOX parameters
1050 //! \details  Populate the Vebox VEBOX state parameters to VEBOX RenderData
1051 //! \param    [in] pLumaParams
1052 //!           Pointer to Luma DN and DI parameter
1053 //! \param    [in] pChromaParams
1054 //!           Pointer to Chroma DN parameter
1055 //! \return   MOS_STATUS
1056 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1057 //!
VeboxPopulateDNDIParams(PVPHAL_SAMPLER_STATE_DNDI_PARAM pLumaParams,PVPHAL_DNUV_PARAMS pChromaParams)1058 MOS_STATUS VPHAL_VEBOX_STATE::VeboxPopulateDNDIParams(
1059     PVPHAL_SAMPLER_STATE_DNDI_PARAM pLumaParams,
1060     PVPHAL_DNUV_PARAMS              pChromaParams)
1061 {
1062     PMHW_VEBOX_DNDI_PARAMS          pVeboxDNDIParams;
1063     PVPHAL_VEBOX_RENDER_DATA        pRenderData = GetLastExecRenderData();
1064 
1065     // Populate the VEBOX VEBOX parameters
1066     pVeboxDNDIParams = &pRenderData->VeboxDNDIParams;
1067 
1068     // DI and Luma Denoise Params
1069     if (pLumaParams != nullptr)
1070     {
1071         VPHAL_RENDER_NORMALMESSAGE("bProgressiveDN %d, bDNDITopFirst %d", pLumaParams->bProgressiveDN, pLumaParams->bDNDITopFirst);
1072         if (pRenderData->bDenoise)
1073         {
1074             pVeboxDNDIParams->dwDenoiseASDThreshold     = pLumaParams->dwDenoiseASDThreshold;
1075             pVeboxDNDIParams->dwDenoiseHistoryDelta     = pLumaParams->dwDenoiseHistoryDelta;
1076             pVeboxDNDIParams->dwDenoiseMaximumHistory   = pLumaParams->dwDenoiseMaximumHistory;
1077             pVeboxDNDIParams->dwDenoiseSTADThreshold    = pLumaParams->dwDenoiseSTADThreshold;
1078             pVeboxDNDIParams->dwDenoiseSCMThreshold     = pLumaParams->dwDenoiseSCMThreshold;
1079             pVeboxDNDIParams->dwDenoiseMPThreshold      = pLumaParams->dwDenoiseMPThreshold;
1080             pVeboxDNDIParams->dwLTDThreshold            = pLumaParams->dwLTDThreshold;
1081             pVeboxDNDIParams->dwTDThreshold             = pLumaParams->dwTDThreshold;
1082             pVeboxDNDIParams->dwGoodNeighborThreshold   = pLumaParams->dwGoodNeighborThreshold;
1083             pVeboxDNDIParams->bProgressiveDN            = pLumaParams->bProgressiveDN;
1084         }
1085         pVeboxDNDIParams->dwFMDFirstFieldCurrFrame      = pLumaParams->dwFMDFirstFieldCurrFrame;
1086         pVeboxDNDIParams->dwFMDSecondFieldPrevFrame     = pLumaParams->dwFMDSecondFieldPrevFrame;
1087         pVeboxDNDIParams->bDNDITopFirst                 = pLumaParams->bDNDITopFirst;
1088     }
1089 
1090     // Only need to reverse bDNDITopFirst for no reference case, no need to reverse it for having refrenece case
1091     if (!pRenderData->bRefValid)
1092     {
1093         pVeboxDNDIParams->bDNDITopFirst                 = pRenderData->bTopField;
1094     }
1095 
1096     // Chroma Denoise Params
1097     if (pRenderData->bChromaDenoise && pChromaParams != nullptr)
1098     {
1099         VPHAL_RENDER_NORMALMESSAGE("bChromaDNEnable %d", pRenderData->bChromaDenoise);
1100         pVeboxDNDIParams->dwChromaSTADThreshold     = pChromaParams->dwSTADThresholdU; // Use U threshold for now
1101         pVeboxDNDIParams->dwChromaLTDThreshold      = pChromaParams->dwLTDThresholdU;  // Use U threshold for now
1102         pVeboxDNDIParams->dwChromaTDThreshold       = pChromaParams->dwTDThresholdU;   // Use U threshold for now
1103         pVeboxDNDIParams->bChromaDNEnable           = pRenderData->bChromaDenoise;
1104     }
1105 
1106     pRenderData->GetVeboxStateParams()->pVphalVeboxDndiParams = pVeboxDNDIParams;
1107 
1108     return MOS_STATUS_SUCCESS;
1109 }
1110 
1111 //!
1112 //! \brief    Vebox Set FMD parameter
1113 //! \details  Set up the FMD parameters for DNDI State
1114 //! \param    [out] pLumaParams
1115 //!           Pointer to DNDI Param for set FMD parameters
1116 //! \return   MOS_STATUS
1117 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1118 //!
VeboxSetFMDParams(PVPHAL_SAMPLER_STATE_DNDI_PARAM pLumaParams)1119 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSetFMDParams(
1120     PVPHAL_SAMPLER_STATE_DNDI_PARAM     pLumaParams)
1121 {
1122     PVPHAL_VEBOX_RENDER_DATA         pRenderData = GetLastExecRenderData();
1123     MOS_STATUS                       eStatus = MOS_STATUS_SUCCESS;
1124 
1125     VPHAL_RENDER_CHK_NULL(pRenderData);
1126     VPHAL_RENDER_CHK_NULL(pLumaParams);
1127 
1128 #if VEBOX_AUTO_DENOISE_SUPPORTED
1129     if (pRenderData->bProgressive && pRenderData->bAutoDenoise)
1130     {
1131         // out1 = Cur1st + Cur2nd
1132         pLumaParams->dwFMDFirstFieldCurrFrame =
1133             MEDIASTATE_DNDI_FIELDCOPY_NEXT;
1134         // out2 = Prv1st + Prv2nd
1135         pLumaParams->dwFMDSecondFieldPrevFrame =
1136             MEDIASTATE_DNDI_FIELDCOPY_PREV;
1137     }
1138     else
1139 #endif
1140     {
1141         pLumaParams->dwFMDFirstFieldCurrFrame =
1142             MEDIASTATE_DNDI_DEINTERLACE;
1143         pLumaParams->dwFMDSecondFieldPrevFrame =
1144             MEDIASTATE_DNDI_DEINTERLACE;
1145     }
1146 
1147 finish:
1148     return eStatus;
1149 }
1150 
1151 //!
1152 //! \brief    Vebox Set VEBOX parameter
1153 //! \details  Set up the VEBOX parameter value
1154 //! \param    [in] pSrcSurface
1155 //!           Pointer to input surface of Vebox
1156 //! \return   MOS_STATUS
1157 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1158 //!
VeboxSetDNDIParams(PVPHAL_SURFACE pSrcSurface)1159 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSetDNDIParams(
1160     PVPHAL_SURFACE              pSrcSurface)
1161 {
1162     MOS_STATUS                       eStatus;
1163     VPHAL_SAMPLER_STATE_DNDI_PARAM   lumaParams;
1164     VPHAL_DNUV_PARAMS                chromaParams;
1165     PVPHAL_SAMPLER_STATE_DNDI_PARAM  pLumaParams;
1166     PVPHAL_DNUV_PARAMS               pChromaParams;
1167     PVPHAL_VEBOX_STATE               pVeboxState = this;
1168     PVPHAL_VEBOX_RENDER_DATA         pRenderData = GetLastExecRenderData();
1169     VPHAL_RENDER_CHK_NULL(pRenderData);
1170 
1171     eStatus             = MOS_STATUS_SUCCESS;
1172     pLumaParams         = &lumaParams;     // Params for DI and LumaDN
1173     pChromaParams       = &chromaParams;   // Params for ChromaDN
1174 
1175     MOS_ZeroMemory(pLumaParams, sizeof(VPHAL_SAMPLER_STATE_DNDI_PARAM));
1176     MOS_ZeroMemory(pChromaParams, sizeof(VPHAL_DNUV_PARAMS));
1177 
1178     // Set Luma and Chroma DNDI params
1179     VPHAL_RENDER_CHK_STATUS(pVeboxState->SetDNDIParams(
1180         pSrcSurface,
1181         pLumaParams,
1182         pChromaParams));
1183 
1184     if (!pRenderData->bRefValid)
1185     {
1186         // setting LTDThreshold = TDThreshold = 0 forces SpatialDenoiseOnly
1187         pLumaParams->dwLTDThreshold   = 0;
1188         pLumaParams->dwTDThreshold    = 0;
1189     }
1190 
1191     if (pRenderData->bDenoise)
1192     {
1193         pLumaParams->bDNEnable = true;
1194 
1195         if (pRenderData->bProgressive)
1196         {
1197             pLumaParams->bProgressiveDN = true;
1198         }
1199     }
1200 
1201     if (pRenderData->bDeinterlace || IsQueryVarianceEnabled())
1202     {
1203         pLumaParams->bDIEnable = true;
1204         pLumaParams->bDNDITopFirst = pRenderData->bTFF;
1205     }
1206 
1207     VeboxSetFMDParams(pLumaParams);
1208 
1209     VeboxPopulateDNDIParams(
1210         pLumaParams,
1211         pChromaParams);
1212 
1213 finish:
1214     return eStatus;
1215 }
1216 
1217 //!
1218 //! \brief    Flush command buffer for update kernels
1219 //! \details  Flush the command buffer for Update kernels
1220 //! \return   MOS_STATUS
1221 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1222 //!
VeboxFlushUpdateStateCmdBuffer()1223 MOS_STATUS VPHAL_VEBOX_STATE::VeboxFlushUpdateStateCmdBuffer()
1224 {
1225     PRENDERHAL_INTERFACE_LEGACY         pRenderHal = nullptr;
1226     PRENDERHAL_STATE_HEAP               pStateHeap = nullptr;
1227     MhwRenderInterface                  *pMhwRender = nullptr;
1228     PMOS_INTERFACE                      pOsInterface = nullptr;
1229     MOS_COMMAND_BUFFER                  CmdBuffer = {};
1230     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1231     int32_t                             i = 0, iRemaining = 0;
1232     PMHW_MI_INTERFACE                   pMhwMiInterface = nullptr;
1233     MHW_MEDIA_OBJECT_PARAMS             MediaObjectParams = {};
1234     MEDIA_OBJECT_KA2_INLINE_DATA        InlineData = {};
1235     int32_t                             iInlineSize = 0;
1236     MHW_PIPE_CONTROL_PARAMS             PipeCtlParams = {};
1237     MHW_ID_LOAD_PARAMS                  IdLoadParams = {};
1238     PVPHAL_VEBOX_STATE                  pVeboxState = this;
1239     PVPHAL_VEBOX_RENDER_DATA            pRenderData = GetLastExecRenderData();
1240     MOS_CONTEXT                         *pOsContext = nullptr;
1241     PMHW_MI_MMIOREGISTERS               pMmioRegisters = nullptr;
1242 
1243     VPHAL_RENDER_CHK_NULL(pVeboxState);
1244     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal);
1245     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pMhwMiInterface);
1246     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pMhwRenderInterface);
1247     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pMhwRenderInterface->GetMmioRegisters());
1248     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pOsInterface);
1249     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pOsInterface->pOsContext);
1250     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pRenderHalPltInterface);
1251 
1252     pRenderHal              = pVeboxState->m_pRenderHal;
1253     pStateHeap              = pRenderHal->pStateHeap;
1254     pMhwRender              = pRenderHal->pMhwRenderInterface;
1255     pMhwMiInterface         = pRenderHal->pMhwMiInterface;
1256     pOsInterface            = pRenderHal->pOsInterface;
1257     pOsContext              = pOsInterface->pOsContext;
1258     pMmioRegisters          = pMhwRender->GetMmioRegisters();
1259 
1260     iRemaining = 0;
1261     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetCommandBuffer(pOsInterface, &CmdBuffer, 0));
1262 
1263     // Set initial state
1264     iRemaining = CmdBuffer.iRemaining;
1265 
1266     HalOcaInterface::On1stLevelBBStart(CmdBuffer, *pOsContext, pOsInterface->CurrentGpuContextHandle,
1267         *pMhwMiInterface, *pMmioRegisters);
1268 
1269     // Add kernel info to log.
1270     HalOcaInterface::DumpVpKernelInfo(CmdBuffer, (MOS_CONTEXT_HANDLE)pOsContext, kernelVeboxUpdateDnState, 0, nullptr);
1271     // Add vphal param to log.
1272     HalOcaInterface::DumpVphalParam(CmdBuffer, (MOS_CONTEXT_HANDLE)pOsContext, pRenderHal->pVphalOcaDumper);
1273 
1274     // Initialize command buffer and insert prolog
1275     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnInitCommandBuffer(pRenderHal, &CmdBuffer, nullptr));
1276 
1277     VPHAL_RENDER_CHK_STATUS(pRenderHal->pRenderHalPltInterface->AddPerfCollectStartCmd(pRenderHal, pOsInterface, &CmdBuffer));
1278 
1279     VPHAL_RENDER_CHK_STATUS(NullHW::StartPredicate(pOsInterface, pRenderHal->pMhwMiInterface, &CmdBuffer));
1280 
1281     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendSyncTag(pRenderHal, &CmdBuffer));
1282 
1283     VPHAL_RENDER_CHK_STATUS(pMhwRender->EnablePreemption(&CmdBuffer));
1284 
1285     // Send Media Pipeline Select command
1286     VPHAL_RENDER_CHK_STATUS(pMhwRender->AddPipelineSelectCmd(
1287         &CmdBuffer,
1288         false));
1289 
1290     VPHAL_RENDER_CHK_STATUS(pMhwRender->AddStateBaseAddrCmd(
1291         &CmdBuffer,
1292         &pRenderHal->StateBaseAddressParams));
1293 
1294     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendSurfaces(pRenderHal, &CmdBuffer));
1295 
1296     VPHAL_RENDER_CHK_NULL(pRenderHal->pRenderHalPltInterface);
1297     if(!pRenderHal->bComputeContextInUse)
1298     {// Set VFE
1299         VPHAL_RENDER_CHK_STATUS(pMhwRender->AddMediaVfeCmd(
1300             &CmdBuffer,
1301             pRenderHal->pRenderHalPltInterface->GetVfeStateParameters()));
1302     }
1303     else
1304     {// Set CFE
1305         VPHAL_RENDER_CHK_STATUS(pMhwRender->AddCfeStateCmd(
1306             &CmdBuffer,
1307             pRenderHal->pRenderHalPltInterface->GetVfeStateParameters()));
1308     }
1309 
1310     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendCurbeLoad(pRenderHal, &CmdBuffer));
1311 
1312     // Send Interface Descriptor Load
1313     MOS_ZeroMemory(&IdLoadParams, sizeof(IdLoadParams));
1314     IdLoadParams.pKernelState                     = nullptr;
1315     IdLoadParams.dwInterfaceDescriptorStartOffset = pStateHeap->pCurMediaState->dwOffset +  pStateHeap->dwOffsetMediaID;
1316     IdLoadParams.dwInterfaceDescriptorLength      = pRenderHal->StateHeapSettings.iMediaIDs * pStateHeap->dwSizeMediaID;
1317     VPHAL_RENDER_CHK_STATUS(pMhwRender->AddMediaIDLoadCmd(&CmdBuffer, &IdLoadParams));
1318 
1319     // Each media obj include header (no inline data is needed,
1320     // however add 1 DW dummy inline to avoid HW Hang)
1321     iInlineSize = 1 * sizeof(uint32_t);
1322     InlineData  = g_cInit_MEDIA_OBJECT_KA2_INLINE_DATA;
1323 
1324     MOS_ZeroMemory(&MediaObjectParams, sizeof(MediaObjectParams));
1325     MediaObjectParams.dwInlineDataSize              = iInlineSize;
1326     MediaObjectParams.pInlineData                   = &InlineData;
1327 
1328     HalOcaInterface::OnDispatch(CmdBuffer, *pOsInterface, *pMhwMiInterface, *pMmioRegisters);
1329 
1330 #if VEBOX_AUTO_DENOISE_SUPPORTED
1331     // Launch Interface Descriptor for DN Update kernel
1332     if (pRenderData->bAutoDenoise)
1333     {
1334         MediaObjectParams.dwInterfaceDescriptorOffset   = pRenderData->iMediaID0;
1335         VPHAL_RENDER_CHK_STATUS(pMhwRender->AddMediaObject(
1336             &CmdBuffer,
1337             nullptr,
1338             &MediaObjectParams));
1339         pVeboxState->m_currKernelId =  kernelVeboxUpdateDnState;
1340     }
1341 #endif
1342 
1343     VPHAL_RENDER_CHK_STATUS(VeboxFlushUpdateStateAddExtraKernels(
1344             CmdBuffer,
1345             MediaObjectParams));
1346 
1347     if (GFX_IS_GEN_9_OR_LATER(pRenderHal->Platform))
1348     {
1349         // Add a pipe_control and vfe to clear the media state to fix PF issue.
1350         MHW_PIPE_CONTROL_PARAMS PipeControlParams;
1351 
1352         MOS_ZeroMemory(&PipeControlParams, sizeof(PipeControlParams));
1353         PipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
1354         PipeControlParams.bGenericMediaStateClear = true;
1355         PipeControlParams.bIndirectStatePointersDisable = true;
1356         PipeControlParams.bDisableCSStall = false;
1357         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddPipeControl(&CmdBuffer, nullptr, &PipeControlParams));
1358 
1359         if (MEDIA_IS_WA(pRenderHal->pWaTable, WaSendDummyVFEafterPipelineSelect))
1360         {
1361             MHW_VFE_PARAMS VfeStateParams = {};
1362             VfeStateParams.dwNumberofURBEntries = 1;
1363             VPHAL_RENDER_CHK_STATUS(pMhwRender->AddMediaVfeCmd(&CmdBuffer, &VfeStateParams));
1364         }
1365     }
1366 
1367     if (GFX_IS_GEN_8_OR_LATER(pRenderHal->Platform))
1368     {
1369         // Add media flush command in case HW not cleaning the media state
1370         // On CHV A Stepping, use MSFlush with Watermark or FlushToGo
1371         MHW_MEDIA_STATE_FLUSH_PARAM         FlushParam = g_cRenderHal_InitMediaStateFlushParams;
1372 
1373         if (MEDIA_IS_WA(pRenderHal->pWaTable, WaMSFWithNoWatermarkTSGHang))
1374         {
1375             FlushParam.bFlushToGo = true;
1376             VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMediaStateFlush(&CmdBuffer, nullptr, &FlushParam));
1377         }
1378         else if (MEDIA_IS_WA(pRenderHal->pWaTable, WaAddMediaStateFlushCmd))
1379         {
1380             VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMediaStateFlush(&CmdBuffer, nullptr, &FlushParam));
1381         }
1382     }
1383 
1384     VPHAL_RENDER_CHK_STATUS(NullHW::StopPredicate(pOsInterface, pRenderHal->pMhwMiInterface, &CmdBuffer));
1385 
1386     VPHAL_RENDER_CHK_STATUS(pRenderHal->pRenderHalPltInterface->AddPerfCollectEndCmd(pRenderHal, pOsInterface, &CmdBuffer));
1387 
1388     HalOcaInterface::On1stLevelBBEnd(CmdBuffer, *pOsInterface);
1389 
1390     if (VpHal_RndrCommonIsMiBBEndNeeded(pOsInterface))
1391     {
1392         // Add Batch Buffer end command (HW/OS dependent)
1393         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(&CmdBuffer, nullptr));
1394     }
1395 
1396 finish:
1397     if (nullptr == CmdBuffer.pCmdBase || nullptr == pOsInterface)
1398     {
1399         return eStatus;
1400     }
1401 
1402     // Failed -> discard all changes in Command Buffer
1403     if (eStatus != MOS_STATUS_SUCCESS)
1404     {
1405         // Buffer overflow - display overflow size
1406         if (CmdBuffer.iRemaining < 0)
1407         {
1408             VPHAL_RENDER_ASSERTMESSAGE("Command Buffer overflow by %d bytes", -CmdBuffer.iRemaining);
1409         }
1410 
1411         // Move command buffer back to beginning
1412         i = iRemaining - CmdBuffer.iRemaining;
1413         CmdBuffer.iRemaining  = iRemaining;
1414         CmdBuffer.iOffset    -= i;
1415         CmdBuffer.pCmdPtr     = CmdBuffer.pCmdBase + CmdBuffer.iOffset/sizeof(uint32_t);
1416     }
1417 
1418     // Return unused command buffer space to OS
1419     pOsInterface->pfnReturnCommandBuffer(
1420         pOsInterface,
1421         &CmdBuffer,
1422         0);
1423 
1424     // Flush the command buffer
1425     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnSubmitCommandBuffer(
1426         pOsInterface,
1427         &CmdBuffer,
1428         pVeboxState->bNullHwRenderDnDi));
1429 
1430     return eStatus;
1431 }
1432 
1433 //!
1434 //! \brief    Vebox Copy Vebox state heap, intended for HM or IDM
1435 //! \details  Copy Vebox state heap between different memory
1436 //! \return   MOS_STATUS
1437 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1438 //!
VeboxCopyVeboxStates()1439 MOS_STATUS VPHAL_VEBOX_STATE::VeboxCopyVeboxStates()
1440 {
1441     return MOS_STATUS_SUCCESS;  // no need to copy, always use driver resource in clear memory
1442 }
1443 
1444 //!
1445 //! \brief    Calculate offsets of statistics surface address based on the
1446 //!           functions which were enabled in the previous call,
1447 //!           and store the width and height of the per-block statistics into DNDI_STATE
1448 //! \details
1449 //! Layout of Statistics surface when Temporal DI enabled
1450 //!     --------------------------------------------------------------\n
1451 //!     | 16 bytes for x=0, Y=0       | 16 bytes for x=16, Y=0       | ...\n
1452 //!     |-------------------------------------------------------------\n
1453 //!     | 16 bytes for x=0, Y=4       | ...\n
1454 //!     |------------------------------\n
1455 //!     | ...\n
1456 //!     |------------------------------\n
1457 //!     | 16 bytes for x=0, Y=height-4| ...\n
1458 //!     |-----------------------------------------------Pitch----------------------------------------------------------\n
1459 //!     | 256 DW of ACE histogram Slice 0 (Previous)| 17 DW Reserved         | 2 DW STD0 | 2 DW GCC0 | 11 DW Reserved |\n
1460 //!     |--------------------------------------------------------------------------------------------------------------\n
1461 //!     | 256 DW of ACE histogram Slice 0 (Current) | 11 DW FMD0 | 6 DW GNE0 | 2 DW STD0 | 2 DW GCC0 | 11 DW Reserved |\n
1462 //!     |--------------------------------------------------------------------------------------------------------------\n
1463 //!     | 256 DW of ACE histogram Slice 1 (Previous)| 17 DW Reserved         | 2 DW STD1 | 2 DW GCC1 | 11 DW Reserved |\n
1464 //!     |--------------------------------------------------------------------------------------------------------------\n
1465 //!     | 256 DW of ACE histogram Slice 1 (Current) | 11 DW FMD1 | 6 DW GNE1 | 2 DW STD1 | 2 DW GCC1 | 11 DW Reserved |\n
1466 //!     ---------------------------------------------------------------------------------------------------------------\n
1467 //!
1468 //! Layout of Statistics surface when DN or Spatial DI enabled (and Temporal DI disabled)
1469 //!     --------------------------------------------------------------\n
1470 //!     | 16 bytes for x=0, Y=0       | 16 bytes for x=16, Y=0       | ...\n
1471 //!     |-------------------------------------------------------------\n
1472 //!     | 16 bytes for x=0, Y=4       | ...\n
1473 //!     |------------------------------\n
1474 //!     | ...\n
1475 //!     |------------------------------\n
1476 //!     | 16 bytes for x=0, Y=height-4| ...\n
1477 //!     |-----------------------------------------------Pitch----------------------------------------------------------\n
1478 //!     | 256 DW of ACE histogram Slice 0 (Input)   | 11 DW FMD0 | 6 DW GNE0 | 2 DW STD0 | 2 DW GCC0 | 11 DW Reserved |\n
1479 //!     |--------------------------------------------------------------------------------------------------------------\n
1480 //!     | 256 DW of ACE histogram Slice 1 (Input)   | 11 DW FMD1 | 6 DW GNE1 | 2 DW STD1 | 2 DW GCC1 | 11 DW Reserved |\n
1481 //!     ---------------------------------------------------------------------------------------------------------------\n
1482 //!
1483 //! Layout of Statistics surface when both DN and DI are disabled
1484 //!     ------------------------------------------------Pitch----------------------------------------------------------\n
1485 //!     | 256 DW of ACE histogram Slice 0 (Input)   | 17 DW Reserved         | 2 DW STD0 | 2 DW GCC0 | 11 DW Reserved |\n
1486 //!     |--------------------------------------------------------------------------------------------------------------\n
1487 //!     | 256 DW of ACE histogram Slice 1 (Input)   | 17 DW Reserved         | 2 DW STD1 | 2 DW GCC1 | 11 DW Reserved |\n
1488 //!     ---------------------------------------------------------------------------------------------------------------\n
1489 //! \param    [out] pStatSlice0Offset
1490 //!           Statistics surface Slice 0 base pointer
1491 //! \param    [out] pStatSlice1Offset
1492 //!           Statistics surface Slice 1 base pointer
1493 //! \return   MOS_STATUS
1494 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1495 //!
VeboxGetStatisticsSurfaceOffsets(int32_t * pStatSlice0Offset,int32_t * pStatSlice1Offset)1496 MOS_STATUS VPHAL_VEBOX_STATE::VeboxGetStatisticsSurfaceOffsets(
1497     int32_t*                    pStatSlice0Offset,
1498     int32_t*                    pStatSlice1Offset)
1499 {
1500     PVPHAL_VEBOX_STATE          pVeboxState = this;
1501     uint32_t    uiPitch;
1502     int32_t     iOffset;
1503     MOS_STATUS  eStatus;
1504 
1505     eStatus     = MOS_STATUS_UNKNOWN;
1506     uiPitch     = 0;
1507 
1508     // Query platform dependent size of per frame information
1509     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxQueryStatLayout(
1510         VEBOX_STAT_QUERY_PER_FRAME_SIZE, &uiPitch));
1511 
1512     // Get the base address of Frame based statistics for each slice
1513     if (pVeboxState->bDIEnabled) // VEBOX, VEBOX+IECP
1514     {
1515         // Frame based statistics begins after Encoder statistics
1516         iOffset = pVeboxState->dwVeboxPerBlockStatisticsWidth *
1517                   pVeboxState->dwVeboxPerBlockStatisticsHeight;
1518 
1519         *pStatSlice0Offset = iOffset + uiPitch;                                     // Slice 0 current frame
1520         *pStatSlice1Offset = iOffset + uiPitch * 3;                                 // Slice 1 current frame
1521     }
1522     else if (pVeboxState->bDNEnabled) // DN, DN_IECP, SpatialDI
1523     {
1524         // Frame based statistics begins after Encoder statistics
1525         iOffset = pVeboxState->dwVeboxPerBlockStatisticsWidth *
1526                   pVeboxState->dwVeboxPerBlockStatisticsHeight;
1527 
1528         *pStatSlice0Offset = iOffset;                                               // Slice 0 input frame
1529         *pStatSlice1Offset = iOffset + uiPitch;                                     // Slice 1 input frame
1530     }
1531     else // IECP only
1532     {
1533         *pStatSlice0Offset = 0;                                                     // Slice 0 input frame
1534         *pStatSlice1Offset = uiPitch;                                               // Slice 1 input frame
1535     }
1536 
1537 finish:
1538     return eStatus;
1539 }
1540 
1541 //! \brief    Vebox get statistics surface base
1542 //! \details  Calculate address of statistics surface address based on the
1543 //!           functions which were enabled in the previous call.
1544 //! \param    uint8_t* pStat
1545 //!           [in] Pointer to Statistics surface
1546 //! \param    uint8_t* * pStatSlice0Base
1547 //!           [out] Statistics surface Slice 0 base pointer
1548 //! \param    uint8_t* * pStatSlice1Base
1549 //!           [out] Statistics surface Slice 1 base pointer
1550 //! \return   MOS_STATUS
1551 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1552 //!
VeboxGetStatisticsSurfaceBase(uint8_t * pStat,uint8_t ** pStatSlice0Base,uint8_t ** pStatSlice1Base)1553 MOS_STATUS VPHAL_VEBOX_STATE::VeboxGetStatisticsSurfaceBase(
1554     uint8_t * pStat,
1555     uint8_t **pStatSlice0Base,
1556     uint8_t **pStatSlice1Base)
1557 {
1558     int32_t    iOffsetSlice0, iOffsetSlice1;
1559     MOS_STATUS eStatus;
1560 
1561     eStatus = MOS_STATUS_UNKNOWN;
1562 
1563     // Calculate the offsets of Slice0 and Slice1
1564     VPHAL_RENDER_CHK_STATUS(VeboxGetStatisticsSurfaceOffsets(
1565         &iOffsetSlice0,
1566         &iOffsetSlice1));
1567 
1568     *pStatSlice0Base = pStat + iOffsetSlice0;  // Slice 0 current frame
1569     *pStatSlice1Base = pStat + iOffsetSlice1;  // Slice 1 current frame
1570 
1571 finish:
1572     return eStatus;
1573 }
1574 
1575 //!
1576 //! \brief    Vebox state heap update for auto mode features
1577 //! \details  Update Vebox indirect states for auto mode features
1578 //! \param    [in] pSrcSurface
1579 //!           Pointer to input surface of Vebox
1580 //! \return   MOS_STATUS
1581 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1582 //!
VeboxUpdateVeboxStates(PVPHAL_SURFACE pSrcSurface)1583 MOS_STATUS VPHAL_VEBOX_STATE::VeboxUpdateVeboxStates(
1584     PVPHAL_SURFACE              pSrcSurface)
1585 {
1586 #if VEBOX_AUTO_DENOISE_SUPPORTED
1587     PRENDERHAL_INTERFACE        pRenderHal;
1588     PMOS_INTERFACE              pOsInterface;
1589     MOS_STATUS                  eStatus;
1590     int32_t                     iCurbeOffsetDN;
1591     int32_t                     iKrnAllocation;
1592     MHW_KERNEL_PARAM            MhwKernelParam;
1593 
1594     PVPHAL_VEBOX_STATE          pVeboxState = this;
1595     PVPHAL_VEBOX_RENDER_DATA    pRenderData = GetLastExecRenderData();
1596 
1597     VPHAL_RENDER_CHK_NULL(pRenderData);
1598     eStatus             = MOS_STATUS_SUCCESS;
1599     pRenderHal          = pVeboxState->m_pRenderHal;
1600     pOsInterface        = pVeboxState->m_pOsInterface;
1601 
1602     if (!pRenderData->bAutoDenoise)
1603     {
1604         // only when auto denoise is on do we need to update VEBOX states
1605         return MOS_STATUS_SUCCESS;
1606     }
1607     // Switch GPU Context to Render Engine
1608     pOsInterface->pfnSetGpuContext(pOsInterface, RenderGpuContext);
1609 
1610     // Reset allocation list and house keeping
1611     pOsInterface->pfnResetOsStates(pOsInterface);
1612 
1613     // Register the resource of GSH
1614     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnReset(pRenderHal));
1615 
1616     // Set up UpdateDNState kernel
1617     if (pRenderData->bAutoDenoise)
1618     {
1619         pVeboxState->SetupVeboxKernel(KERNEL_UPDATEDNSTATE);
1620     }
1621 
1622     //----------------------------------
1623     // Allocate and reset media state
1624     //----------------------------------
1625     pRenderData->pMediaState = pRenderHal->pfnAssignMediaState(pRenderHal, RENDERHAL_COMPONENT_VEBOX);
1626     VPHAL_RENDER_CHK_NULL(pRenderData->pMediaState);
1627 
1628     //----------------------------------
1629     //Allocate and reset SSH instance
1630     //----------------------------------
1631     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnAssignSshInstance(pRenderHal));
1632 
1633     //----------------------------------
1634     // Assign and Reset Binding Table
1635     //----------------------------------
1636     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnAssignBindingTable(
1637         pRenderHal,
1638         &pRenderData->iBindingTable));
1639 
1640     //------------------------------------------
1641     // Setup Surface states for DN Update kernel
1642     //------------------------------------------
1643     if (pRenderData->bAutoDenoise)
1644     {
1645         VPHAL_RENDER_CHK_STATUS(SetupSurfaceStatesForDenoise());
1646     }
1647 
1648     //----------------------------------
1649     // Load static data (platform specific)
1650     //----------------------------------
1651     VPHAL_RENDER_CHK_STATUS(pVeboxState->LoadUpdateDenoiseKernelStaticData(
1652         &iCurbeOffsetDN));
1653 
1654     //----------------------------------
1655     // Setup VFE State params. Each Renderer MUST call pfnSetVfeStateParams().
1656     //----------------------------------
1657     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetVfeStateParams(
1658         pRenderHal,
1659         MEDIASTATE_DEBUG_COUNTER_FREE_RUNNING,
1660         pVeboxState->pKernelParamTable[KERNEL_UPDATEDNSTATE].Thread_Count,
1661         pRenderData->iCurbeLength,
1662         pRenderData->iInlineLength,
1663         nullptr));
1664 
1665     //----------------------------------
1666     // Load DN update kernel to GSH
1667     //----------------------------------
1668     if (pRenderData->bAutoDenoise)
1669     {
1670         INIT_MHW_KERNEL_PARAM(MhwKernelParam, &pRenderData->KernelEntry[KERNEL_UPDATEDNSTATE]);
1671         iKrnAllocation = pRenderHal->pfnLoadKernel(
1672             pRenderHal,
1673             pRenderData->pKernelParam[KERNEL_UPDATEDNSTATE],
1674             &MhwKernelParam,
1675             nullptr);
1676 
1677         if (iKrnAllocation < 0)
1678         {
1679             eStatus = MOS_STATUS_UNKNOWN;
1680             goto finish;
1681         }
1682 
1683         //----------------------------------
1684         // Allocate Media ID, link to kernel
1685         //----------------------------------
1686         pRenderData->iMediaID0 = pRenderHal->pfnAllocateMediaID(
1687             pRenderHal,
1688             iKrnAllocation,
1689             pRenderData->iBindingTable,
1690             iCurbeOffsetDN,
1691             pRenderData->pKernelParam[KERNEL_UPDATEDNSTATE]->CURBE_Length << 5,
1692             0,
1693             nullptr);
1694 
1695         if (pRenderData->iMediaID0 < 0)
1696         {
1697             eStatus = MOS_STATUS_UNKNOWN;
1698             goto finish;
1699         }
1700     }
1701 
1702     //---------------------------
1703     // Render Batch Buffer (Submit commands to HW)
1704     //---------------------------
1705     VPHAL_RENDER_CHK_STATUS(VeboxFlushUpdateStateCmdBuffer());
1706 
1707 finish:
1708     return eStatus;
1709 #else
1710     return MOS_STATUS_SUCCESS;
1711 #endif
1712 }
1713 
VeboxSetupIndirectStates(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutSurface)1714 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSetupIndirectStates(
1715     PVPHAL_SURFACE              pSrcSurface,
1716     PVPHAL_SURFACE              pOutSurface)
1717 {
1718     PMOS_INTERFACE                  pOsInterface       = nullptr;
1719     PMHW_VEBOX_INTERFACE            pVeboxInterface    = nullptr;
1720     MOS_STATUS                      eStatus;
1721     MHW_VEBOX_IECP_PARAMS           VeboxIecpParams    = {};
1722     MHW_VEBOX_GAMUT_PARAMS          VeboxGamutParams   = {};
1723     PVPHAL_VEBOX_STATE              pVeboxState        = this;
1724     PVPHAL_VEBOX_RENDER_DATA        pRenderData        = GetLastExecRenderData();
1725 
1726     VPHAL_RENDER_CHK_NULL(pRenderData);
1727     VPHAL_RENDER_CHK_NULL(pVeboxState);
1728     VPHAL_RENDER_CHK_NULL(pSrcSurface);
1729 
1730     pOsInterface = pVeboxState->m_pOsInterface;
1731     pVeboxInterface = pVeboxState->m_pVeboxInterface;
1732 
1733     VPHAL_RENDER_CHK_NULL(pOsInterface);
1734 
1735     // Initialize structure before using
1736     MOS_ZeroMemory(&VeboxIecpParams, sizeof(MHW_VEBOX_IECP_PARAMS));
1737     MOS_ZeroMemory(&VeboxGamutParams, sizeof(MHW_VEBOX_GAMUT_PARAMS));
1738     // Gamma is default to 2.2 since SDR uses 2.2
1739     VeboxGamutParams.InputGammaValue    = MHW_GAMMA_2P2;
1740     VeboxGamutParams.OutputGammaValue   = MHW_GAMMA_2P2;
1741 
1742     //----------------------------------
1743     // Allocate and reset VEBOX state
1744     //----------------------------------
1745     VPHAL_RENDER_CHK_STATUS(pVeboxInterface->AssignVeboxState());
1746 
1747     // Set VEBOX State Params
1748     if (pRenderData->bDeinterlace       ||
1749         pRenderData->bDenoise           ||
1750         pRenderData->bChromaDenoise)
1751     {
1752         VPHAL_RENDER_CHK_STATUS(VeboxSetDNDIParams(pSrcSurface));
1753     }
1754 
1755     if (pRenderData->GetVeboxStateParams()->pVphalVeboxDndiParams)
1756     {
1757         VPHAL_RENDER_CHK_STATUS(pVeboxInterface->AddVeboxDndiState(
1758             pRenderData->GetVeboxStateParams()->pVphalVeboxDndiParams));
1759     }
1760 
1761     // Set IECP State Params
1762     if (pRenderData->bIECP ||
1763         IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData) ||
1764         IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
1765     {
1766         m_IECP->SetParams(pSrcSurface, pOutSurface);
1767     }
1768 
1769     // Set IECP State Params
1770     if (pRenderData->GetVeboxStateParams()->pVphalVeboxIecpParams)
1771     {
1772         VPHAL_RENDER_CHK_STATUS(m_IECP->InitParams(
1773             pSrcSurface->ColorSpace,
1774             &VeboxIecpParams));
1775         VPHAL_RENDER_CHK_STATUS(pVeboxInterface->AddVeboxIecpState(
1776             &VeboxIecpParams));
1777     }
1778 
1779     // Set Gamma Parameters
1780     if (pRenderData->bHdr3DLut)
1781     {
1782         VeboxGamutParams.bGammaCorr         = true;
1783         VeboxGamutParams.ColorSpace         = VPHal_VpHalCspace2MhwCspace(pSrcSurface->ColorSpace);
1784         VeboxGamutParams.InputGammaValue    = MHW_GAMMA_1P0;
1785         VeboxGamutParams.OutputGammaValue   = MHW_GAMMA_1P0;
1786 
1787         VPHAL_RENDER_CHK_STATUS(pVeboxInterface->AddVeboxGamutState(
1788             &VeboxIecpParams,
1789             &VeboxGamutParams));
1790     }
1791 
1792     if (pRenderData->bBT2020TosRGB)
1793     {
1794         VeboxGamutParams.ColorSpace    = VPHal_VpHalCspace2MhwCspace(pSrcSurface->ColorSpace);
1795         VeboxGamutParams.dstColorSpace = VPHal_VpHalCspace2MhwCspace(pRenderData->BT2020DstColorSpace);
1796         VeboxGamutParams.srcFormat     = pSrcSurface->Format;
1797         VeboxGamutParams.dstFormat     = pOutSurface->Format;
1798         VeboxGamutParams.GCompMode     = MHW_GAMUT_MODE_NONE;
1799         VeboxGamutParams.GExpMode      = MHW_GAMUT_MODE_NONE;
1800         VeboxGamutParams.bGammaCorr    = false;
1801 
1802         VPHAL_RENDER_CHK_STATUS(pVeboxInterface->AddVeboxGamutState(
1803             &VeboxIecpParams,
1804             &VeboxGamutParams));
1805     }
1806 
1807 finish:
1808     return eStatus;
1809 }
1810 
1811 //!
1812 //! \brief    Doing prepare stage tasks for VeboxSendVeboxCmd
1813 //!           Parameters might remain unchanged in case
1814 //! \param    [out] CmdBuffer
1815 //!           reference to Cmd buffer control struct
1816 //! \param    [out] GenericPrologParams
1817 //!           Generic prolog params struct to be set
1818 //! \param    [out] iRemaining
1819 //!           integer showing initial cmd buffer usage
1820 //! \return   MOS_STATUS
1821 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1822 //!
VeboxSendVeboxCmd_Prepare(MOS_COMMAND_BUFFER & CmdBuffer,RENDERHAL_GENERIC_PROLOG_PARAMS & GenericPrologParams,int32_t & iRemaining)1823 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSendVeboxCmd_Prepare(
1824     MOS_COMMAND_BUFFER&                      CmdBuffer,
1825     RENDERHAL_GENERIC_PROLOG_PARAMS&         GenericPrologParams,
1826     int32_t&                                 iRemaining)
1827 {
1828     MOS_STATUS                              eStatus      = MOS_STATUS_SUCCESS;
1829     PMOS_INTERFACE                          pOsInterface = m_pOsInterface;
1830     PVPHAL_VEBOX_STATE                      pVeboxState  = this;
1831     PVPHAL_VEBOX_RENDER_DATA                pRenderData  = GetLastExecRenderData();
1832 
1833     VPHAL_RENDER_CHK_NULL(pRenderData);
1834     // Switch GPU context to VEBOX
1835     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnSetGpuContext(pOsInterface, MOS_GPU_CONTEXT_VEBOX));
1836 
1837     // Reset allocation list and house keeping
1838     pOsInterface->pfnResetOsStates(pOsInterface);
1839 
1840     // initialize the command buffer struct
1841     MOS_ZeroMemory(&CmdBuffer, sizeof(MOS_COMMAND_BUFFER));
1842     GenericPrologParams = {};
1843 
1844     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetCommandBuffer(pOsInterface, &CmdBuffer, 0));
1845 
1846     // Set initial state
1847     iRemaining = CmdBuffer.iRemaining;
1848 
1849     //---------------------------
1850     // Set Performance Tags
1851     //---------------------------
1852     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxSetPerfTag(pVeboxState->m_currentSurface->Format));
1853     pOsInterface->pfnResetPerfBufferID(pOsInterface);
1854     pOsInterface->pfnSetPerfTag(pOsInterface, pRenderData->PerfTag);
1855 
1856     // Linux will do nothing here since currently no frame tracking support
1857 
1858 #ifndef EMUL
1859     // Don't enable MediaFrame Track on Vebox if one VPBlit Still need to do compostion. It can avoid the kmd notify
1860     // the frame be handling finished twice for one VPBLIT.
1861     // For VE+Render colorfill case, don't enable MediaFrame Track on vebox to avoid twice notification for one VP Blt.
1862     // We need to refactor decision code of bCompNeeded by setting bCompNeeded flag before Vebox/SFC processing in the future.
1863     if ((pRenderData->OutputPipe != VPHAL_OUTPUT_PIPE_MODE_COMP &&
1864         !pRenderData->pRenderTarget->bFastColorFill) &&
1865         (pVeboxState->m_sfcPipeState != nullptr && !pVeboxState->m_sfcPipeState->m_bSFC2Pass) &&
1866         pOsInterface->bEnableKmdMediaFrameTracking)
1867     {
1868         PMOS_RESOURCE gpuStatusBuffer = nullptr;
1869         // Get GPU Status buffer
1870         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetGpuStatusBufferResource(pOsInterface, gpuStatusBuffer));
1871         VPHAL_RENDER_CHK_NULL(gpuStatusBuffer);
1872         // Register the buffer
1873         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(pOsInterface, gpuStatusBuffer, true, true));
1874 
1875         GenericPrologParams.bEnableMediaFrameTracking       = true;
1876         GenericPrologParams.presMediaFrameTrackingSurface   = gpuStatusBuffer;
1877         GenericPrologParams.dwMediaFrameTrackingTag         = pOsInterface->pfnGetGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
1878         GenericPrologParams.dwMediaFrameTrackingAddrOffset  = pOsInterface->pfnGetGpuStatusTagOffset(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
1879 
1880         // Increment GPU Status Tag
1881         pOsInterface->pfnIncrementGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
1882     }
1883 #endif
1884 
1885 finish:
1886     return eStatus;
1887 }
1888 
1889 //!
1890 //! \brief    Check whether the Vebox command parameters are correct
1891 //! \param    [in] VeboxStateCmdParams
1892 //!           MHW vebox state cmd params
1893 //! \param    [in] VeboxDiIecpCmdParams
1894 //!           DiIecpCmd params struct
1895 //! \return   MOS_STATUS
1896 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1897 //!
VeboxIsCmdParamsValid(const MHW_VEBOX_STATE_CMD_PARAMS & VeboxStateCmdParams,const MHW_VEBOX_DI_IECP_CMD_PARAMS & VeboxDiIecpCmdParams,const VPHAL_VEBOX_SURFACE_STATE_CMD_PARAMS & VeboxSurfaceStateCmdParams)1898 MOS_STATUS VPHAL_VEBOX_STATE::VeboxIsCmdParamsValid(
1899     const MHW_VEBOX_STATE_CMD_PARAMS            &VeboxStateCmdParams,
1900     const MHW_VEBOX_DI_IECP_CMD_PARAMS          &VeboxDiIecpCmdParams,
1901     const VPHAL_VEBOX_SURFACE_STATE_CMD_PARAMS  &VeboxSurfaceStateCmdParams)
1902 {
1903     const MHW_VEBOX_MODE    &veboxMode          = VeboxStateCmdParams.VeboxMode;
1904 
1905     if (veboxMode.DIEnable)
1906     {
1907         if (nullptr == VeboxDiIecpCmdParams.pOsResPrevOutput &&
1908             (MEDIA_VEBOX_DI_OUTPUT_PREVIOUS == veboxMode.DIOutputFrames || MEDIA_VEBOX_DI_OUTPUT_BOTH == veboxMode.DIOutputFrames))
1909         {
1910             return MOS_STATUS_INVALID_PARAMETER;
1911         }
1912         if (nullptr == VeboxDiIecpCmdParams.pOsResCurrOutput &&
1913             (MEDIA_VEBOX_DI_OUTPUT_CURRENT == veboxMode.DIOutputFrames || MEDIA_VEBOX_DI_OUTPUT_BOTH == veboxMode.DIOutputFrames))
1914         {
1915             return MOS_STATUS_INVALID_PARAMETER;
1916         }
1917     }
1918 
1919     if (IsDNOnly())
1920     {
1921         VPHAL_RENDER_CHK_NULL_RETURN(VeboxSurfaceStateCmdParams.pSurfInput);
1922         VPHAL_RENDER_CHK_NULL_RETURN(VeboxSurfaceStateCmdParams.pSurfDNOutput);
1923 
1924         if ((VeboxSurfaceStateCmdParams.pSurfInput->TileModeGMM == VeboxSurfaceStateCmdParams.pSurfDNOutput->TileModeGMM) &&
1925             (VeboxSurfaceStateCmdParams.pSurfInput->dwPitch != VeboxSurfaceStateCmdParams.pSurfDNOutput->dwPitch))
1926         {
1927             return MOS_STATUS_INVALID_PARAMETER;
1928         }
1929     }
1930 
1931     return MOS_STATUS_SUCCESS;
1932 }
1933 
1934 //!
1935 //! \brief    Render the Vebox Cmd buffer for VeboxSendVeboxCmd
1936 //!           Parameters might remain unchanged in case
1937 //! \param    [in,out] CmdBuffer
1938 //!           reference to Cmd buffer control struct
1939 //! \param    [out] VeboxDiIecpCmdParams
1940 //!           DiIecpCmd params struct to be set
1941 //! \param    [out] VeboxSurfaceStateCmdParams
1942 //!           VPHAL surface state cmd to be set
1943 //! \param    [out] MhwVeboxSurfaceStateCmdParams
1944 //!           MHW surface state cmd to be set
1945 //! \param    [out] VeboxStateCmdParams
1946 //!           MHW vebox state cmd to be set
1947 //! \param    [out] FlushDwParams
1948 //!           MHW MI_FLUSH_DW cmd to be set
1949 //! \param    [in] pGenericPrologParams
1950 //!           pointer to Generic prolog params struct to send to cmd buffer header
1951 //! \return   MOS_STATUS
1952 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1953 //!
VeboxRenderVeboxCmd(MOS_COMMAND_BUFFER & CmdBuffer,MHW_VEBOX_DI_IECP_CMD_PARAMS & VeboxDiIecpCmdParams,VPHAL_VEBOX_SURFACE_STATE_CMD_PARAMS & VeboxSurfaceStateCmdParams,MHW_VEBOX_SURFACE_STATE_CMD_PARAMS & MhwVeboxSurfaceStateCmdParams,MHW_VEBOX_STATE_CMD_PARAMS & VeboxStateCmdParams,MHW_MI_FLUSH_DW_PARAMS & FlushDwParams,PRENDERHAL_GENERIC_PROLOG_PARAMS pGenericPrologParams)1954 MOS_STATUS VPHAL_VEBOX_STATE::VeboxRenderVeboxCmd(
1955     MOS_COMMAND_BUFFER&                      CmdBuffer,
1956     MHW_VEBOX_DI_IECP_CMD_PARAMS&            VeboxDiIecpCmdParams,
1957     VPHAL_VEBOX_SURFACE_STATE_CMD_PARAMS&    VeboxSurfaceStateCmdParams,
1958     MHW_VEBOX_SURFACE_STATE_CMD_PARAMS&      MhwVeboxSurfaceStateCmdParams,
1959     MHW_VEBOX_STATE_CMD_PARAMS&              VeboxStateCmdParams,
1960     MHW_MI_FLUSH_DW_PARAMS&                  FlushDwParams,
1961     PRENDERHAL_GENERIC_PROLOG_PARAMS         pGenericPrologParams)
1962 {
1963     MOS_STATUS                              eStatus = MOS_STATUS_SUCCESS;
1964     PRENDERHAL_INTERFACE                    pRenderHal = nullptr;
1965     PMOS_INTERFACE                          pOsInterface = nullptr;
1966     PMHW_MI_INTERFACE                       pMhwMiInterface = nullptr;
1967     PMHW_VEBOX_INTERFACE                    pVeboxInterface = nullptr;
1968     bool                                    bDiVarianceEnable = false;
1969     const MHW_VEBOX_HEAP                    *pVeboxHeap = nullptr;
1970     PVPHAL_VEBOX_STATE                      pVeboxState = this;
1971     PVPHAL_VEBOX_RENDER_DATA                pRenderData = GetLastExecRenderData();
1972     MOS_CONTEXT                             *pOsContext = nullptr;
1973     PMHW_MI_MMIOREGISTERS                   pMmioRegisters = nullptr;
1974 
1975     VPHAL_RENDER_CHK_NULL(pRenderData);
1976     VPHAL_RENDER_CHK_NULL(pVeboxState);
1977     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal);
1978     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pMhwMiInterface);
1979     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pMhwMiInterface->GetMmioRegisters());
1980     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pOsInterface);
1981     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pOsInterface->pOsContext);
1982     VPHAL_RENDER_CHK_NULL(pVeboxState->m_pRenderHal->pRenderHalPltInterface);
1983 
1984     eStatus                 = MOS_STATUS_SUCCESS;
1985     pRenderHal              = pVeboxState->m_pRenderHal;
1986     pMhwMiInterface         = pRenderHal->pMhwMiInterface;
1987     pOsInterface            = pVeboxState->m_pOsInterface;
1988     pVeboxInterface         = pVeboxState->m_pVeboxInterface;
1989     pOsContext              = pOsInterface->pOsContext;
1990     pMmioRegisters          = pMhwMiInterface->GetMmioRegisters();
1991 
1992     VPHAL_RENDER_CHK_STATUS(pVeboxInterface->GetVeboxHeapInfo(
1993                                 &pVeboxHeap));
1994     VPHAL_RENDER_CHK_NULL(pVeboxHeap);
1995 
1996     HalOcaInterface::On1stLevelBBStart(CmdBuffer, *pOsContext, pOsInterface->CurrentGpuContextHandle,
1997         *pRenderHal->pMhwMiInterface, *pMmioRegisters);
1998 
1999     HalOcaInterface::TraceOcaSkuValue(CmdBuffer, *pOsInterface);
2000 
2001     // Add vphal param to log.
2002     HalOcaInterface::DumpVphalParam(CmdBuffer, (MOS_CONTEXT_HANDLE)pOsContext, pRenderHal->pVphalOcaDumper);
2003 
2004     // Initialize command buffer and insert prolog
2005     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnInitCommandBuffer(pRenderHal, &CmdBuffer, pGenericPrologParams));
2006 
2007     VPHAL_RENDER_CHK_STATUS(pRenderHal->pRenderHalPltInterface->AddPerfCollectStartCmd(pRenderHal, pOsInterface, &CmdBuffer));
2008 
2009     VPHAL_RENDER_CHK_STATUS(NullHW::StartPredicate(pOsInterface, pRenderHal->pMhwMiInterface, &CmdBuffer));
2010 
2011     bDiVarianceEnable = pRenderData->bDeinterlace || IsQueryVarianceEnabled();
2012 
2013     pVeboxState->SetupSurfaceStates(
2014         bDiVarianceEnable,
2015         &VeboxSurfaceStateCmdParams);
2016 
2017     // Add compressible info of input/output surface to log
2018     if( this->m_currentSurface && VeboxSurfaceStateCmdParams.pSurfOutput)
2019     {
2020         std::string info = "in_comps = " + std::to_string(int(this->m_currentSurface->bCompressible)) + ", out_comps = " + std::to_string(int(VeboxSurfaceStateCmdParams.pSurfOutput->bCompressible));
2021         const char* ocaLog = info.c_str();
2022         HalOcaInterface::TraceMessage(CmdBuffer, (MOS_CONTEXT_HANDLE)pOsContext, ocaLog, info.size());
2023     }
2024 
2025     VPHAL_RENDER_CHK_STATUS(pVeboxState->SetupVeboxState(
2026         bDiVarianceEnable,
2027         &VeboxStateCmdParams));
2028 
2029     // Ensure LACE LUT table is ready to be written
2030     if (VeboxStateCmdParams.pLaceLookUpTables)
2031     {
2032         pOsInterface->pfnSyncOnResource(
2033             pOsInterface,
2034             VeboxStateCmdParams.pLaceLookUpTables,
2035             MOS_GPU_CONTEXT_VEBOX,
2036             false);
2037     }
2038 
2039     VPHAL_RENDER_CHK_STATUS(pVeboxState->SetupDiIecpState(
2040         bDiVarianceEnable,
2041         &VeboxDiIecpCmdParams));
2042 
2043     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxIsCmdParamsValid(
2044         VeboxStateCmdParams,
2045         VeboxDiIecpCmdParams,
2046         VeboxSurfaceStateCmdParams));
2047 
2048     // Ensure output is ready to be written
2049     if (VeboxDiIecpCmdParams.pOsResCurrOutput)
2050     {
2051         pOsInterface->pfnSyncOnResource(
2052             pOsInterface,
2053             VeboxDiIecpCmdParams.pOsResCurrOutput,
2054             MOS_GPU_CONTEXT_VEBOX,
2055             true);
2056 
2057         // Synchronize overlay if overlay is used because output could be Render Target
2058         if (VeboxSurfaceStateCmdParams.pSurfOutput &&
2059             VeboxSurfaceStateCmdParams.pSurfOutput->bOverlay)
2060         {
2061             pOsInterface->pfnSyncOnOverlayResource(
2062                 pOsInterface,
2063                 VeboxDiIecpCmdParams.pOsResCurrOutput,
2064                 MOS_GPU_CONTEXT_VEBOX);
2065         }
2066     }
2067 
2068     if (VeboxDiIecpCmdParams.pOsResPrevOutput)
2069     {
2070         pOsInterface->pfnSyncOnResource(
2071             pOsInterface,
2072             VeboxDiIecpCmdParams.pOsResPrevOutput,
2073             MOS_GPU_CONTEXT_VEBOX,
2074             true);
2075     }
2076 
2077     if (VeboxDiIecpCmdParams.pOsResDenoisedCurrOutput)
2078     {
2079         pOsInterface->pfnSyncOnResource(
2080             pOsInterface,
2081             VeboxDiIecpCmdParams.pOsResDenoisedCurrOutput,
2082             MOS_GPU_CONTEXT_VEBOX,
2083             true);
2084     }
2085 
2086     if (VeboxDiIecpCmdParams.pOsResStatisticsOutput)
2087     {
2088         pOsInterface->pfnSyncOnResource(
2089             pOsInterface,
2090             VeboxDiIecpCmdParams.pOsResStatisticsOutput,
2091             MOS_GPU_CONTEXT_VEBOX,
2092             true);
2093     }
2094 
2095     //---------------------------------
2096     // Initialize Vebox Surface State Params
2097     //---------------------------------
2098     VPHAL_RENDER_CHK_STATUS(VpHal_InitVeboxSurfaceStateCmdParams(
2099         &VeboxSurfaceStateCmdParams, &MhwVeboxSurfaceStateCmdParams));
2100 
2101     //---------------------------------
2102     // Send MMC CMD
2103     //---------------------------------
2104     VPHAL_RENDER_CHK_STATUS_RETURN(VeboxRenderMMCPipeCmd(
2105         pVeboxInterface,
2106         pMhwMiInterface,
2107         &(MhwVeboxSurfaceStateCmdParams),
2108         &VeboxDiIecpCmdParams,
2109         &CmdBuffer));
2110 
2111     //---------------------------------
2112     // Send CMD: Vebox_State
2113     //---------------------------------
2114     VPHAL_RENDER_CHK_STATUS(pVeboxInterface->AddVeboxState(
2115         &CmdBuffer,
2116         &VeboxStateCmdParams,
2117         0));
2118 
2119     //---------------------------------
2120     // Send CMD: Vebox_Surface_State
2121     //---------------------------------
2122     VPHAL_RENDER_CHK_STATUS(pVeboxInterface->AddVeboxSurfaces(
2123         &CmdBuffer,
2124         &MhwVeboxSurfaceStateCmdParams));
2125 
2126     //---------------------------------
2127     // Send CMD: SFC pipe commands
2128     //---------------------------------
2129     if (IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData))
2130     {
2131         VPHAL_RENDER_CHK_STATUS(m_sfcPipeState->SendSfcCmd(
2132             pRenderData,
2133             &CmdBuffer));
2134     }
2135 
2136     HalOcaInterface::OnDispatch(CmdBuffer, *pOsInterface, *pRenderHal->pMhwMiInterface, *pMmioRegisters);
2137 
2138     //---------------------------------
2139     // Send CMD: Vebox_DI_IECP
2140     //---------------------------------
2141     VPHAL_RENDER_CHK_STATUS(pVeboxInterface->AddVeboxDiIecp(
2142         &CmdBuffer,
2143         &VeboxDiIecpCmdParams));
2144 
2145     //---------------------------------
2146     // Write GPU Status Tag for Tag based synchronization
2147     //---------------------------------
2148     if (!pOsInterface->bEnableKmdMediaFrameTracking)
2149     {
2150         VPHAL_RENDER_CHK_STATUS(VeboxSendVecsStatusTag(
2151             pMhwMiInterface,
2152             pOsInterface,
2153             &CmdBuffer));
2154     }
2155 
2156     //---------------------------------
2157     // Write Sync tag for Vebox Heap Synchronization
2158     // If KMD frame tracking is on, the synchronization of Vebox Heap will use Status tag which
2159     // is updated using KMD frame tracking.
2160     //---------------------------------
2161     if (!pOsInterface->bEnableKmdMediaFrameTracking)
2162     {
2163         MOS_ZeroMemory(&FlushDwParams, sizeof(FlushDwParams));
2164         FlushDwParams.pOsResource                   = (PMOS_RESOURCE)&pVeboxHeap->DriverResource;
2165         FlushDwParams.dwResourceOffset              = pVeboxHeap->uiOffsetSync;
2166         FlushDwParams.dwDataDW1                     = pVeboxHeap->dwNextTag;
2167         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiFlushDwCmd(
2168             &CmdBuffer,
2169             &FlushDwParams));
2170     }
2171 
2172     VPHAL_RENDER_CHK_STATUS(NullHW::StopPredicate(pOsInterface, pRenderHal->pMhwMiInterface, &CmdBuffer));
2173 
2174     VPHAL_RENDER_CHK_STATUS(pRenderHal->pRenderHalPltInterface->AddPerfCollectEndCmd(pRenderHal, pOsInterface, &CmdBuffer));
2175 
2176     HalOcaInterface::On1stLevelBBEnd(CmdBuffer, *pOsInterface);
2177 
2178     if (pOsInterface->bNoParsingAssistanceInKmd)
2179     {
2180         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(
2181             &CmdBuffer,
2182             nullptr));
2183     }
2184     else if (VpHal_RndrCommonIsMiBBEndNeeded(pOsInterface))
2185     {
2186         // Add Batch Buffer end command (HW/OS dependent)
2187         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(
2188             &CmdBuffer,
2189             nullptr));
2190     }
2191 
2192     VPHAL_DBG_STATE_DUMPPER_DUMP_COMMAND_BUFFER(pRenderHal, &CmdBuffer);
2193 
2194 finish:
2195     return eStatus;
2196 
2197 }
2198 
2199 //!
2200 //! \brief    Vebox send Vebox ring HW commands
2201 //! \details  Send Vebox ring Commands.
2202 //! \return   MOS_STATUS
2203 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2204 //!
VeboxSendVeboxCmd()2205 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSendVeboxCmd()
2206 {
2207     PRENDERHAL_INTERFACE                    pRenderHal                      = nullptr;
2208     PMOS_INTERFACE                          pOsInterface                    = {};
2209     MOS_COMMAND_BUFFER                      CmdBuffer                       = {};
2210     MOS_STATUS                              eStatus                         = MOS_STATUS_SUCCESS;
2211     int32_t                                 iRemaining                      = 0;
2212     int32_t                                 i                               = 0;
2213     MHW_VEBOX_DI_IECP_CMD_PARAMS            VeboxDiIecpCmdParams            = {};
2214     VPHAL_VEBOX_SURFACE_STATE_CMD_PARAMS    VeboxSurfaceStateCmdParams      = {};
2215     MHW_VEBOX_SURFACE_STATE_CMD_PARAMS      MhwVeboxSurfaceStateCmdParams   = {};
2216     MHW_VEBOX_STATE_CMD_PARAMS              VeboxStateCmdParams             = {};
2217     MHW_MI_FLUSH_DW_PARAMS                  FlushDwParams                   = {};
2218     PMHW_VEBOX_INTERFACE                    pVeboxInterface                 = {};
2219     RENDERHAL_GENERIC_PROLOG_PARAMS         GenericPrologParams             = {};
2220     PVPHAL_VEBOX_STATE                      pVeboxState                     = this;
2221     PVPHAL_VEBOX_RENDER_DATA                pRenderData                     = GetLastExecRenderData();
2222 
2223     pRenderHal              = pVeboxState->m_pRenderHal;
2224     pOsInterface            = pVeboxState->m_pOsInterface;
2225     iRemaining              = 0;
2226     pVeboxInterface         = pVeboxState->m_pVeboxInterface;
2227 
2228     if (!pRenderData) {
2229         VPHAL_RENDER_ASSERTMESSAGE("pRenderData is NULL");
2230         return MOS_STATUS_NULL_POINTER;
2231     }
2232 
2233     VPHAL_RENDER_CHK_STATUS(VeboxSendVeboxCmd_Prepare(
2234         CmdBuffer,
2235         GenericPrologParams,
2236         iRemaining));
2237 
2238     VPHAL_RENDER_CHK_STATUS(VeboxRenderVeboxCmd(
2239         CmdBuffer,
2240         VeboxDiIecpCmdParams,
2241         VeboxSurfaceStateCmdParams,
2242         MhwVeboxSurfaceStateCmdParams,
2243         VeboxStateCmdParams,
2244         FlushDwParams,
2245         &GenericPrologParams));
2246 
2247     // Return unused command buffer space to OS
2248     pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
2249 
2250     VPHAL_RENDER_CHK_STATUS(VeboxSyncIndirectStateCmd());
2251     VPHAL_RENDER_CHK_STATUS(VeboxSendVeboxCmdSetParamBeforeSubmit());
2252 
2253     // Flush the command buffer
2254     if (!bPhasedSubmission)
2255     {
2256         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnSubmitCommandBuffer(
2257             pOsInterface,
2258             &CmdBuffer,
2259             pVeboxState->bNullHwRenderDnDi));
2260     }
2261 
2262     if (pVeboxState->bNullHwRenderDnDi == false)
2263     {
2264         pVeboxInterface->UpdateVeboxSync();
2265     }
2266 
2267 finish:
2268     // Failed -> discard all changes in Command Buffer
2269     if (eStatus != MOS_STATUS_SUCCESS)
2270     {
2271         // Buffer overflow - display overflow size
2272         if (CmdBuffer.iRemaining < 0)
2273         {
2274             VPHAL_RENDER_ASSERTMESSAGE("Command Buffer overflow by %d bytes", -CmdBuffer.iRemaining);
2275         }
2276 
2277         // Move command buffer back to beginning
2278         i = iRemaining - CmdBuffer.iRemaining;
2279         CmdBuffer.iRemaining  = iRemaining;
2280         CmdBuffer.iOffset    -= i;
2281         CmdBuffer.pCmdPtr     = CmdBuffer.pCmdBase + CmdBuffer.iOffset/sizeof(uint32_t);
2282 
2283         pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
2284     }
2285 
2286     VpHal_RndrUpdateStatusTableAfterSubmit(pOsInterface, &m_StatusTableUpdateParams, MOS_GPU_CONTEXT_VEBOX, eStatus);
2287 
2288     return eStatus;
2289 }
2290 
2291 //!
2292 //! \brief    Sync for Indirect state Copy and Update Kernels
2293 //! \details  Sync for Indirect state Copy and Update Kernels before Send Vebox ring Commands.
2294 //! \return   MOS_STATUS
2295 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2296 //!
VeboxSyncIndirectStateCmd()2297 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSyncIndirectStateCmd()
2298 {
2299 #if VEBOX_AUTO_DENOISE_SUPPORTED
2300     PVPHAL_VEBOX_RENDER_DATA pRenderData = GetLastExecRenderData();
2301     if (pRenderData && pRenderData->bAutoDenoise)
2302     {
2303         // Make sure copy kernel and update kernels are finished before submitting
2304         // VEBOX commands
2305 
2306         m_pOsInterface->pfnSyncGpuContext(
2307             m_pOsInterface,
2308             RenderGpuContext,
2309             MOS_GPU_CONTEXT_VEBOX);
2310     }
2311 #endif
2312 
2313     return MOS_STATUS_SUCCESS;
2314 }
2315 
2316 //!
2317 //! \brief    Vebox set common rendering flag
2318 //! \details  Common flags should be set before other flags,
2319 //!           and it should be independent with other flags
2320 //! \param    [in] pSrc
2321 //!           Pointer to input surface of Vebox
2322 //! \param    [in] pRenderTarget
2323 //!           Pointer to Render targe surface of VPP BLT
2324 //! \return   void
2325 //!
VeboxSetCommonRenderingFlags(PVPHAL_SURFACE pSrc,PVPHAL_SURFACE pRenderTarget)2326 void VPHAL_VEBOX_STATE::VeboxSetCommonRenderingFlags(
2327     PVPHAL_SURFACE              pSrc,
2328     PVPHAL_SURFACE              pRenderTarget)
2329 {
2330     PVPHAL_SURFACE              pRef;
2331     PVPHAL_SURFACE              pCurSurf;
2332     PVPHAL_SURFACE              pPrvSurf;
2333     int32_t                     iSameSampleThreshold;
2334     PVPHAL_VEBOX_STATE          pVeboxState = this;
2335     PVPHAL_VEBOX_RENDER_DATA    pRenderData = GetLastExecRenderData();
2336     VPHAL_RENDER_CHK_NULL_NO_STATUS_RETURN(pRenderData);
2337 
2338     if (IS_VEBOX_EXECUTION_MODE_2(pVeboxState->m_pVeboxExecState))
2339     {
2340         // Treat forward frame as current frame input to vebox
2341         // and current frame as previous frame input to vebox
2342         pRef     = pSrc->pFwdRef;
2343         pCurSurf = pRef;
2344         pPrvSurf = pSrc;
2345         VPHAL_RENDER_ASSERT(pRef && pSrc->uFwdRefCount > 0);
2346     }
2347     else
2348     {
2349         // In serial mode (mode0) or transition mode (mode0to2),
2350         // treat current frame as current frame input to vebox
2351         // and previous frame as previous frame input to vebox
2352         // if a previous exists.
2353         // It is valid case to have no previous frame reference
2354         pRef     = (pSrc->uBwdRefCount > 0) ? pSrc->pBwdRef : nullptr;
2355         pCurSurf = pSrc;
2356         pPrvSurf = pRef;
2357     }
2358 
2359     iSameSampleThreshold        = pVeboxState->iSameSampleThreshold;
2360 
2361     VpHal_GetScalingRatio(pSrc, pRenderTarget, &pRenderData->fScaleX, &pRenderData->fScaleY);
2362 
2363     pRenderData->bProgressive   = (pSrc->SampleType == SAMPLE_PROGRESSIVE);
2364 
2365     if (IsDnDisabled())
2366     {
2367         pRenderData->bDenoise = false;
2368         pRenderData->bChromaDenoise = false;
2369 #if VEBOX_AUTO_DENOISE_SUPPORTED
2370         pRenderData->bAutoDenoise   = false;
2371 #endif
2372     }
2373     else
2374     {
2375         pRenderData->bDenoise = (pSrc->pDenoiseParams &&
2376                                  (pSrc->pDenoiseParams->bEnableLuma ||
2377                                      pSrc->pDenoiseParams->bEnableSlimIPUDenoise ||
2378                                      pSrc->pDenoiseParams->bEnableHVSDenoise) &&
2379                                  pVeboxState->IsDnFormatSupported(pSrc));
2380 
2381         pRenderData->bChromaDenoise = (pSrc->pDenoiseParams &&
2382                                        pSrc->pDenoiseParams->bEnableChroma &&
2383                                        pSrc->pDenoiseParams->bEnableLuma &&
2384                                        pVeboxState->IsDnFormatSupported(pSrc));
2385 
2386 #if VEBOX_AUTO_DENOISE_SUPPORTED
2387         pRenderData->bAutoDenoise = (pRenderData->bDenoise &&
2388                                      pSrc->pDenoiseParams &&
2389                                      pSrc->pDenoiseParams->bAutoDetect &&
2390                                      pVeboxState->IsDnFormatSupported(pSrc));
2391 #endif
2392     }
2393 
2394     // Free dDenoiseParams when DN don`t support source format
2395     // to avoid the possible using by mistake, 8 alignement for DN in renderhal
2396     if ((!pRenderData->bDenoise) && (pSrc->pDenoiseParams != nullptr))
2397     {
2398         MOS_FreeMemAndSetNull(pSrc->pDenoiseParams);
2399     }
2400 
2401     pRenderData->bDeinterlace   = (pVeboxState->IsDiFormatSupported(pSrc)            &&
2402                                    ((pSrc->pDeinterlaceParams                        &&
2403                                     pSrc->pDeinterlaceParams->DIMode == DI_MODE_ADI) ||
2404                                     (IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData)           &&
2405                                      pSrc->pDeinterlaceParams                        &&
2406                                      pSrc->pDeinterlaceParams->DIMode == DI_MODE_BOB)));
2407 
2408     pRenderData->bRefValid      = (pRef                                 &&
2409                                    (pSrc->Format   == pRef->Format)     &&
2410                                    (pSrc->dwWidth  == pRef->dwWidth)    &&
2411                                    (pSrc->dwHeight == pRef->dwHeight)   &&
2412                                    (pSrc->FrameID  != pRef->FrameID)    &&
2413                                    (pSrc->InterlacedScalingType == ISCALING_NONE));
2414 
2415     // Flags needs to be set if the reference sample is valid
2416     if (pRenderData->bRefValid)
2417     {
2418         pRenderData->bSameSamples   =
2419                WITHIN_BOUNDS(
2420                       pCurSurf->FrameID - pVeboxState->iCurFrameID,
2421                       -iSameSampleThreshold,
2422                       iSameSampleThreshold) &&
2423                WITHIN_BOUNDS(
2424                       pPrvSurf->FrameID - pVeboxState->iPrvFrameID,
2425                       -iSameSampleThreshold,
2426                       iSameSampleThreshold);
2427 
2428         pRenderData->bOutOfBound    =
2429                OUT_OF_BOUNDS(
2430                       pPrvSurf->FrameID - pVeboxState->iCurFrameID,
2431                       -iSameSampleThreshold,
2432                       iSameSampleThreshold);
2433     }
2434     // bSameSamples flag also needs to be set for no reference case
2435     else
2436     {
2437          pRenderData->bSameSamples  =
2438                WITHIN_BOUNDS(
2439                       pCurSurf->FrameID - pVeboxState->iCurFrameID,
2440                       -iSameSampleThreshold,
2441                       iSameSampleThreshold);
2442     }
2443 
2444     pVeboxState->bSameSamples = pRenderData->bSameSamples;
2445 
2446     // Cache Render Target pointer
2447     pRenderData->pRenderTarget = pRenderTarget;
2448 }
2449 
2450 //!
2451 //! \brief    Vebox set Field related rendering flag
2452 //! \details  Set Field related flags for interlaced or related features
2453 //! \param    [in] pSrc
2454 //!           Pointer to input surface of Vebox
2455 //! \return   void
2456 //!
VeboxSetFieldRenderingFlags(PVPHAL_SURFACE pSrc)2457 void VPHAL_VEBOX_STATE::VeboxSetFieldRenderingFlags(
2458     PVPHAL_SURFACE              pSrc)
2459 {
2460     PVPHAL_VEBOX_RENDER_DATA    pRenderData = GetLastExecRenderData();
2461 
2462     VPHAL_RENDER_CHK_NULL_NO_STATUS_RETURN(pRenderData);
2463     // No need to check future surface for Mode2 here
2464     // Because only current frame will change the field setting.
2465     // And whether current blt are top or bottom field doesn't matter here
2466     pRenderData->bTFF =
2467         (pSrc->SampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD) ||
2468         (pSrc->SampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD);
2469 
2470     // Seting bTopField flag
2471     pRenderData->bTopField =
2472         (pSrc->SampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD) ||
2473         (pSrc->SampleType == SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD);
2474 }
2475 
2476 //!
2477 //! \brief    Vebox set rendering flag
2478 //! \details  Setup Rendering Flags due to different usage case
2479 //! \param    [in] pSrc
2480 //!           Pointer to input surface of Vebox
2481 //! \param    [in] pRenderTarget
2482 //!           Pointer to Render targe surface of VPP BLT
2483 //! \return   void
2484 //!
VeboxSetRenderingFlags(PVPHAL_SURFACE pSrc,PVPHAL_SURFACE pRenderTarget)2485 void VPHAL_VEBOX_STATE::VeboxSetRenderingFlags(
2486     PVPHAL_SURFACE              pSrc,
2487     PVPHAL_SURFACE              pRenderTarget)
2488 {
2489     PRENDERHAL_INTERFACE         pRenderHal         = nullptr;
2490     PVPHAL_VEBOX_STATE           pVeboxState        = this;
2491     PVPHAL_VEBOX_RENDER_DATA     pRenderData        = GetLastExecRenderData();
2492 
2493     VPHAL_RENDER_CHK_NULL_NO_STATUS(pSrc);
2494     VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderTarget);
2495     VPHAL_RENDER_CHK_NULL_NO_STATUS(pRenderData);
2496 
2497     pRenderHal                  = pVeboxState->m_pRenderHal;
2498 
2499     // VEBOX needed to be bypass for VE+COMP/SFC cases when no vebox feature.
2500     if (MEDIA_IS_SKU(pVeboxState->GetSkuTable(), FtrDisableVEBoxFeatures) &&
2501         !IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
2502     {
2503         pRenderData->bVeboxBypass = true;
2504         return;
2505     }
2506 
2507     VeboxSetCommonRenderingFlags(pSrc, pRenderTarget);
2508 
2509     // surface height should be a multiple of 4 when DN/DI is enabled and input format is Planar 420
2510     if ((IS_VEBOX_SURFACE_HEIGHT_UNALIGNED(pSrc, 4)) &&
2511         (pSrc->Format == Format_P010                 ||
2512          pSrc->Format == Format_P016                 ||
2513          pSrc->Format == Format_NV12))
2514     {
2515         pRenderData->bDenoise     = false;
2516         pRenderData->bDeinterlace = false;
2517     }
2518 
2519     // surface height should be a multiple of 2 for all format
2520     // when Denoise is enabled and progressiveDN is disabled
2521     if (IS_VEBOX_SURFACE_HEIGHT_UNALIGNED(pSrc, 2) &&
2522         pRenderData->bDenoise                      &&
2523         (!pRenderData->bProgressive))
2524     {
2525         pRenderData->bDenoise     = false;
2526     }
2527 
2528     // Flags only needs to be set if deinterlacing is needed
2529     if (pRenderData->bDeinterlace)
2530     {
2531         VeboxSetFieldRenderingFlags(pSrc);
2532 
2533         pRenderData->bSingleField   = (pRenderData->bRefValid                           &&
2534                                         pSrc->pDeinterlaceParams->DIMode != DI_MODE_BOB) ?
2535                                         pSrc->pDeinterlaceParams->bSingleField            :
2536                                         true;
2537 
2538         // Detect ADI mode (30i->30fps or 30i->60fps) according to DDI
2539         pRenderData->b60fpsDi       = !pSrc->pDeinterlaceParams->bSingleField;
2540     }
2541 
2542     pRenderData->b2PassesCSC = VeboxIs2PassesCSCNeeded(pSrc, pRenderTarget);
2543 
2544     pRenderData->bBT2020TosRGB = (pVeboxState->IsFormatSupported(pSrc) &&
2545                                   (GFX_IS_GEN_9_OR_LATER(pVeboxState->m_pRenderHal->Platform)) &&
2546                                   (IS_COLOR_SPACE_BT2020_YUV(pSrc->ColorSpace)) &&
2547                                   (pRenderTarget->ColorSpace != pSrc->ColorSpace) &&
2548                                   (!IS_COLOR_SPACE_BT2020_RGB(pRenderTarget->ColorSpace)) &&
2549                                   (!IS_COLOR_SPACE_BT2020_YUV(pRenderTarget->ColorSpace)));
2550 
2551     pRenderData->BT2020DstColorSpace = pRenderTarget->ColorSpace;
2552 
2553     // Need to refine later
2554     // Actually, behind CSC can do nothing which is related to degamma/gamma
2555     pRenderData->bBeCsc             = (IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData) &&
2556                                        pSrc->ColorSpace != pRenderTarget->ColorSpace &&
2557                                        !pSrc->p3DLutParams);
2558 
2559     pRenderData->bProcamp           = ((IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData) ||
2560                                         IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData)   ||
2561                                         pRenderData->b2PassesCSC)               && // 2pass CSC goes into VEBOX + render. In this case, need to anable procamp.
2562                                         pSrc->pProcampParams                    &&
2563                                         pSrc->pProcampParams->bEnabled);
2564 
2565     pRenderData->bColorPipe         = (pSrc->pColorPipeParams &&
2566                                         (pSrc->pColorPipeParams->bEnableSTE     ||
2567                                          pSrc->pColorPipeParams->bEnableTCC));
2568 
2569     pRenderData->bIECP              = ((pSrc->pColorPipeParams &&
2570                                         (pSrc->pColorPipeParams->bEnableSTE     ||
2571                                          pSrc->pColorPipeParams->bEnableTCC))   ||
2572                                         pRenderData->bBeCsc                     ||
2573                                         pRenderData->bProcamp);
2574 
2575     // Vebox can be bypassed if no feature is needed
2576     if (!(pRenderData->bDenoise          ||
2577           pRenderData->bDeinterlace      ||
2578           pRenderData->bIECP             ||
2579           pRenderData->bHdr3DLut         ||
2580           IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData)))
2581     {
2582         pRenderData->bVeboxBypass = true;
2583     }
2584 
2585     if (pSrc->pHDRParams)
2586     {
2587         pRenderData->bBT2020TosRGB       = false;
2588         pRenderData->b2PassesCSC         = false;
2589 
2590         // For H2S, it is possible that there is no HDR params for render target.
2591         pRenderData->uiMaxContentLevelLum = pSrc->pHDRParams->MaxCLL;
2592         if (pSrc->pHDRParams->EOTF == VPHAL_HDR_EOTF_SMPTE_ST2084)
2593         {
2594             pRenderData->hdrMode = VPHAL_HDR_MODE_TONE_MAPPING;
2595             if (pRenderTarget->pHDRParams)
2596             {
2597                 pRenderData->uiMaxDisplayLum = pRenderTarget->pHDRParams->max_display_mastering_luminance;
2598                 if (pRenderTarget->pHDRParams->EOTF == VPHAL_HDR_EOTF_SMPTE_ST2084)
2599                 {
2600                     pRenderData->hdrMode = VPHAL_HDR_MODE_H2H;
2601                 }
2602             }
2603         }
2604     }
2605 
2606     if (pSrc->p3DLutParams)
2607     {
2608         pRenderData->bBT2020TosRGB = false;
2609         pRenderData->b2PassesCSC   = false;
2610     }
2611 finish:
2612     return;
2613 }
2614 
2615 //!
2616 //! \brief    Vebox initialize STMM History
2617 //! \details  Initialize STMM History surface
2618 //! Description:
2619 //!   This function is used by VEBox for initializing
2620 //!   the STMM surface.  The STMM / Denoise history is a custom surface used
2621 //!   for both input and output. Each cache line contains data for 4 4x4s.
2622 //!   The STMM for each 4x4 is 8 bytes, while the denoise history is 1 byte
2623 //!   and the chroma denoise history is 1 byte for each U and V.
2624 //!   Byte    Data\n
2625 //!   0       STMM for 2 luma values at luma Y=0, X=0 to 1\n
2626 //!   1       STMM for 2 luma values at luma Y=0, X=2 to 3\n
2627 //!   2       Luma Denoise History for 4x4 at 0,0\n
2628 //!   3       Not Used\n
2629 //!   4-5     STMM for luma from X=4 to 7\n
2630 //!   6       Luma Denoise History for 4x4 at 0,4\n
2631 //!   7       Not Used\n
2632 //!   8-15    Repeat for 4x4s at 0,8 and 0,12\n
2633 //!   16      STMM for 2 luma values at luma Y=1,X=0 to 1\n
2634 //!   17      STMM for 2 luma values at luma Y=1, X=2 to 3\n
2635 //!   18      U Chroma Denoise History\n
2636 //!   19      Not Used\n
2637 //!   20-31   Repeat for 3 4x4s at 1,4, 1,8 and 1,12\n
2638 //!   32      STMM for 2 luma values at luma Y=2,X=0 to 1\n
2639 //!   33      STMM for 2 luma values at luma Y=2, X=2 to 3\n
2640 //!   34      V Chroma Denoise History\n
2641 //!   35      Not Used\n
2642 //!   36-47   Repeat for 3 4x4s at 2,4, 2,8 and 2,12\n
2643 //!   48      STMM for 2 luma values at luma Y=3,X=0 to 1\n
2644 //!   49      STMM for 2 luma values at luma Y=3, X=2 to 3\n
2645 //!   50-51   Not Used\n
2646 //!   36-47   Repeat for 3 4x4s at 3,4, 3,8 and 3,12\n
2647 //! \param    [in] iSurfaceIndex
2648 //!           Index of STMM surface array
2649 //! \return   MOS_STATUS
2650 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2651 //!
VeboxInitSTMMHistory(int32_t iSurfaceIndex)2652 MOS_STATUS VPHAL_VEBOX_STATE::VeboxInitSTMMHistory(
2653     int32_t                      iSurfaceIndex)
2654 {
2655     MOS_STATUS          eStatus;
2656     PMOS_INTERFACE      pOsInterface;
2657     uint32_t            dwSize;
2658     int32_t             x, y;
2659     uint8_t*            pByte;
2660     MOS_LOCK_PARAMS     LockFlags;
2661     PVPHAL_VEBOX_STATE  pVeboxState = this;
2662 
2663     eStatus         = MOS_STATUS_SUCCESS;
2664     pOsInterface    = pVeboxState->m_pOsInterface;
2665 
2666     MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS));
2667 
2668     LockFlags.WriteOnly    = 1;
2669     LockFlags.TiledAsTiled = 1; // Set TiledAsTiled flag for STMM surface initialization.
2670 
2671     // Lock the surface for writing
2672     pByte = (uint8_t*)pOsInterface->pfnLockResource(
2673         pOsInterface,
2674         &(pVeboxState->STMMSurfaces[iSurfaceIndex].OsResource),
2675         &LockFlags);
2676 
2677     VPHAL_RENDER_CHK_NULL(pByte);
2678 
2679     dwSize = pVeboxState->STMMSurfaces[iSurfaceIndex].dwWidth >> 2;
2680 
2681     // Fill STMM surface with DN history init values.
2682     for (y = 0; y < (int32_t)pVeboxState->STMMSurfaces[iSurfaceIndex].dwHeight; y++)
2683     {
2684         for (x = 0; x < (int32_t)dwSize; x++)
2685         {
2686             MOS_FillMemory(pByte, 2, DNDI_HISTORY_INITVALUE);
2687             // skip denosie history init.
2688             pByte += 4;
2689         }
2690 
2691         pByte += pVeboxState->STMMSurfaces[iSurfaceIndex].dwPitch - pVeboxState->STMMSurfaces[iSurfaceIndex].dwWidth;
2692     }
2693 
2694     // Unlock the surface
2695     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnUnlockResource(
2696             pOsInterface,
2697             &(pVeboxState->STMMSurfaces[iSurfaceIndex].OsResource)));
2698 
2699 finish:
2700     return eStatus;
2701 }
2702 
2703 #if VEBOX_AUTO_DENOISE_SUPPORTED
2704 //!
2705 //! \brief    Vebox initialize Spatial Configuration Surface
2706 //! \details  Initialize Spatial Configuration surface
2707 //! Description:
2708 //!   This function is used by VEBox for initializing
2709 //!   the Spatial Attributes Configuration surface.
2710 //!   The GEN9+ DN kernel will use the init data in this surface and write back output data
2711 //! \return   MOS_STATUS
2712 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2713 //!
VeboxInitSpatialAttributesConfiguration()2714 MOS_STATUS VPHAL_VEBOX_STATE::VeboxInitSpatialAttributesConfiguration()
2715 {
2716     MOS_STATUS          eStatus;
2717     PMOS_INTERFACE      pOsInterface;
2718     VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATION *pSpatialAttributesConfiguration;
2719     MOS_LOCK_PARAMS     LockFlags;
2720     PVPHAL_VEBOX_STATE  pVeboxState = this;
2721 
2722     eStatus = MOS_STATUS_SUCCESS;
2723     pOsInterface = pVeboxState->m_pOsInterface;
2724 
2725     MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS));
2726 
2727     LockFlags.WriteOnly = 1;
2728 
2729     // Lock the surface for writing
2730     pSpatialAttributesConfiguration = (VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATION*)pOsInterface->pfnLockResource(
2731         pOsInterface,
2732         &(pVeboxState->VeboxSpatialAttributesConfigurationSurface.OsResource),
2733         &LockFlags);
2734 
2735     VPHAL_RENDER_CHK_NULL(pSpatialAttributesConfiguration);
2736     *pSpatialAttributesConfiguration = g_cInit_VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATION;
2737 
2738     // Unlock the surface
2739     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnUnlockResource(
2740         pOsInterface,
2741         &(pVeboxState->VeboxSpatialAttributesConfigurationSurface.OsResource)));
2742 
2743 finish:
2744     return eStatus;
2745 }
2746 #endif
2747 
2748 //!
2749 //! \brief    Update Vebox Execution State for Vebox/Render parallelism
2750 //! \details
2751 //!     Purpose   : Handle Vebox execution state machine transitions
2752 //!
2753 //!     Mode0:    Enter or stay in this state as long has (a) there are no future
2754 //!               frames present or (b) FRC is active. Parallel execution is
2755 //!               handled different in FRC mode. (c) Vebox/SFC output path is
2756 //!               applied. Parallel execution is not needed when it is Vebox/SFC
2757 //!               to output. Mode0 is considered the legacy serial vebox execution mode.
2758 //!     Mode0To2: Enter this state when a future frame becomes present. In this
2759 //!               state, perform a one time start up sequence in order to transistion
2760 //!               to Mode2 parallel execution state.
2761 //!     Mode2:    Enter this state as long a future frame is present. This is the
2762 //!               steady parallel execution state where we process 1 frame ahead.
2763 //!               i.e. On BLT(N), we do vebox on the future frame N+1 and composite
2764 //!               frame N in the same BLT().
2765 //!     Mode2To0: Enter this state when in Mode2 and no future frame is present.
2766 //!               Transition back to Mode0.
2767 //! \param    [in] pSrcSurface
2768 //!           Pointer to input surface of Vebox
2769 //! \param    [in] OutputPipe
2770 //!           The output path the driver uses to write the RenderTarget
2771 //! \return   MOS_STATUS
2772 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2773 //!
UpdateVeboxExecutionState(PVPHAL_SURFACE pSrcSurface,VPHAL_OUTPUT_PIPE_MODE OutputPipe)2774 MOS_STATUS VPHAL_VEBOX_STATE::UpdateVeboxExecutionState(
2775     PVPHAL_SURFACE          pSrcSurface,
2776     VPHAL_OUTPUT_PIPE_MODE  OutputPipe)
2777 {
2778     MOS_STATUS  eStatus;
2779     bool        bSameSamples;
2780     bool        bOutOfBound;
2781     int32_t     iSameSampleThreshold;
2782     PVPHAL_VEBOX_STATE      pVeboxState  = this;
2783 
2784     VPHAL_RENDER_ASSERT(pVeboxState);
2785     VPHAL_RENDER_ASSERT(pSrcSurface);
2786 
2787     eStatus                 = MOS_STATUS_SUCCESS;
2788     bSameSamples            = false;
2789     bOutOfBound             = false;
2790     iSameSampleThreshold    = pVeboxState->iSameSampleThreshold;;
2791 
2792     if (IS_VEBOX_EXECUTION_MODE_PARALLEL_CAPABLE(pVeboxState->m_pVeboxExecState))
2793     {
2794         if ((pVeboxState->m_pVeboxExecState->bFrcActive)  ||
2795             (OutputPipe != VPHAL_OUTPUT_PIPE_MODE_COMP))
2796         {
2797             SET_VEBOX_EXECUTION_MODE(pVeboxState->m_pVeboxExecState, VEBOX_EXEC_MODE_0);
2798         }
2799         else if (pSrcSurface->uFwdRefCount == 0)
2800         {
2801             // Transition Mode2 to Mode0
2802             if (IS_VEBOX_EXECUTION_MODE_2(pVeboxState->m_pVeboxExecState))
2803             {
2804                 SET_VEBOX_EXECUTION_MODE(pVeboxState->m_pVeboxExecState, VEBOX_EXEC_MODE_2_TO_0);
2805 
2806                 // In the following case
2807                 //    Blt#    Bwd   Curr  Fwd       Field    bSameSample
2808                 //    ----------------------------------------------------------
2809                 //    Blt0    F1     F2    F3       Top       false
2810                 //    Blt1    F2     F3    nullptr  Bot       true -> No render
2811                 // Driver will still output last blt result through the SameSample flow.
2812                 // Since mode 2 has already toggled the output pair,
2813                 // we need to toggle the output pair back.
2814                 // For other cases that introduce new render, RenderMode0() will reset the outputpair.
2815                 pVeboxState->m_pVeboxExecState->bDIOutputPair01 = !pVeboxState->m_pVeboxExecState->bDIOutputPair01;
2816 
2817                 if (IS_VEBOX_EXECUTION_MODE_2_TO_0(pVeboxState->m_pVeboxExecState))
2818                 {
2819                     SET_VEBOX_EXECUTION_MODE(pVeboxState->m_pVeboxExecState, VEBOX_EXEC_MODE_0);
2820                 }
2821             }
2822             else // Steady Mode0 state
2823             {
2824                 VPHAL_RENDER_ASSERT(
2825                     IS_VEBOX_EXECUTION_MODE_0(pVeboxState->m_pVeboxExecState) ||
2826                     IS_VEBOX_EXECUTION_MODE_2_TO_0(pVeboxState->m_pVeboxExecState));
2827             }
2828         }
2829         else // Future Frame present
2830         {
2831             // Transition Mode0 to Mode2
2832             if (IS_VEBOX_EXECUTION_MODE_0(pVeboxState->m_pVeboxExecState))
2833             {
2834                 // Raise the FFDI surface number for mode 2 use.
2835                 pVeboxState->iNumFFDISurfaces = 4;
2836 
2837                 // When previous blt is Mode0,
2838                 // pVeboxState->iCurFrameID are previous blt's current frame
2839                 // pVeboxState->iPrvFrameID are previous blt's bwd frame
2840                 bSameSamples   =
2841                     (pSrcSurface->uBwdRefCount > 0 && pSrcSurface->pBwdRef) &&
2842                     WITHIN_BOUNDS(
2843                             pSrcSurface->FrameID - pVeboxState->iCurFrameID,
2844                             -iSameSampleThreshold,
2845                             iSameSampleThreshold) &&
2846                     WITHIN_BOUNDS(
2847                             pSrcSurface->pBwdRef->FrameID - pVeboxState->iPrvFrameID,
2848                             -iSameSampleThreshold,
2849                             iSameSampleThreshold);
2850 
2851                 bOutOfBound    =
2852                     (pSrcSurface->uBwdRefCount > 0 && pSrcSurface->pBwdRef) &&
2853                     OUT_OF_BOUNDS(
2854                             pSrcSurface->pBwdRef->FrameID - pVeboxState->iCurFrameID,
2855                             -iSameSampleThreshold,
2856                             iSameSampleThreshold);
2857 
2858                 // Only switch to mode 2 for non-SameSample, non-frame repeat,
2859                 // and non-frame drop case.
2860                 // The case we want to switch mode are marked OK in this table:
2861                 // bSameSamples bOutOfBound Switch   Note
2862                 // ----------------------------------------------------------
2863                 //    true        true       NG     Same Sample / Frame Repeat
2864                 //    true        false      NG     Self-reference frame Repeat
2865                 //    false       true       NG     Frame Drop
2866                 //    false       false      OK     Normal case
2867                 //
2868                 // 1. SameSample case in interlaced mode. Already has sample
2869                 //    for output and will not do new render, and thus no way
2870                 //    to switch to mode 2. Switch to Mode0To2 now will stuck
2871                 //    in the state forever.
2872                 //    One example that causing the issue:
2873                 //    Blt#    Bwd   Curr  Fwd       Field    bSameSamples
2874                 //    ----------------------------------------------------------
2875                 //    Blt0    F1     F2    nullptr  Top       false
2876                 //    Blt1    F1     F2    F3       Bot       true -> No render
2877                 // 2. Frame Reapt case in both progressive/interlaced modes.
2878                 //    Future frame might stay future for a while and not in use
2879                 //    as next blt's current.
2880                 //    And, in mode 2 driver will output the previous blt's future frame.
2881                 //    In repeating frame scene it is not expected to do so.
2882                 //    Keep in mode 0 until new frames are received.
2883                 // 3. Frame-drop case, the player or hw resource might not
2884                 //    rich enough yet, another frame drop might occur immediately.
2885                 //    To help smooth playback, only switch to mode2 when the player
2886                 //    can provide consecutive two blts without frame drop.
2887                 if (!bSameSamples && !bOutOfBound)
2888                 {
2889                     SET_VEBOX_EXECUTION_MODE(pVeboxState->m_pVeboxExecState, VEBOX_EXEC_MODE_0_TO_2);
2890                 }
2891             }
2892             else // Steady Mode2 state
2893             {
2894                 VPHAL_RENDER_ASSERT(
2895                     IS_VEBOX_EXECUTION_MODE_2(pVeboxState->m_pVeboxExecState) ||
2896                     IS_VEBOX_EXECUTION_MODE_0_TO_2(pVeboxState->m_pVeboxExecState));
2897 
2898                 VPHAL_RENDER_ASSERT(pSrcSurface->pFwdRef);
2899 
2900                 // When previous blt is Mode2,
2901                 // pVeboxState->iCurFrameID are previous blt's future frame
2902                 // pVeboxState->iPrvFrameID are previous blt's current frame
2903                 bSameSamples   =
2904                     WITHIN_BOUNDS(
2905                             pSrcSurface->pFwdRef->FrameID - pVeboxState->iCurFrameID,
2906                             -iSameSampleThreshold,
2907                             iSameSampleThreshold) &&
2908                     WITHIN_BOUNDS(
2909                             pSrcSurface->FrameID - pVeboxState->iPrvFrameID,
2910                             -iSameSampleThreshold,
2911                             iSameSampleThreshold);
2912 
2913                 bOutOfBound    =
2914                     OUT_OF_BOUNDS(
2915                             pSrcSurface->FrameID - pVeboxState->iCurFrameID,
2916                             -iSameSampleThreshold,
2917                             iSameSampleThreshold);
2918 
2919                 // If previous blt's future frame are not coming as this blt's
2920                 // current frame, we cannot use the pre-rendered results.
2921                 // Two possibilities:
2922                 // Case 1: SameSameples.
2923                 //         Current remains current, future remains future.
2924                 //         a. For interlaced, Keep in Mode 2, can reuse the previous output.
2925                 //         b. For progressive, current flow is to render with new parameters.
2926                 //            Cannot stay in mode2, to avoid output the previous blt's
2927                 //            future frame as current.
2928                 // Case 2: Discontinuity - hence can't reuse previous surfaces
2929                 //         i.e !bSameSamples && OutOfBound.
2930                 //         Nothing can be reused.
2931                 //
2932                 //         Both cases can switch back to mode 0To2 for render new current frame
2933                 //         as well as new future frame.
2934                 //         But such abnormal condition often due to player's intended bahavior.
2935                 //         It may outputing static menu, or wrong reference frame given.
2936                 //         The extra render of furture frame in Mode0To2 might not be
2937                 //         used in next blt.
2938                 //         So switch to mode0 to save bandwidth.
2939                 //         If the player can keep providing future frame without repeating
2940                 //         or frame drop, we can resume to mode 2 in next blt.
2941 
2942                 if ((!bSameSamples && bOutOfBound) ||
2943                     (bSameSamples && !pSrcSurface->pDeinterlaceParams))
2944                 {
2945                     SET_VEBOX_EXECUTION_MODE(pVeboxState->m_pVeboxExecState, VEBOX_EXEC_MODE_0);
2946                 }
2947 
2948             }
2949         }
2950     }
2951 
2952     return eStatus;
2953 }
2954 
2955 //!
2956 //! \brief    Copy and update vebox state
2957 //! \details  Copy and update vebox state for input frame.
2958 //! \param    [in] pSrcSurface
2959 //!           Pointer to input surface of Vebox
2960 //! \return   MOS_STATUS
2961 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2962 //!
VeboxCopyAndUpdateVeboxState(PVPHAL_SURFACE pSrcSurface)2963 MOS_STATUS VPHAL_VEBOX_STATE::VeboxCopyAndUpdateVeboxState(
2964     PVPHAL_SURFACE           pSrcSurface)
2965 {
2966     PVPHAL_VEBOX_STATE       pVeboxState = this;
2967     PVPHAL_VEBOX_RENDER_DATA pRenderData = GetLastExecRenderData();
2968 
2969     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2970 
2971     VPHAL_RENDER_CHK_NULL(pRenderData);
2972     VPHAL_RENDER_ASSERT(pVeboxState);
2973     VPHAL_RENDER_ASSERT(pRenderData);
2974     VPHAL_RENDER_ASSERT(pSrcSurface);
2975 
2976     // Setup VEBOX State
2977     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxSetupIndirectStates(
2978             pSrcSurface,
2979             IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData) ?
2980             pRenderData->pRenderTarget              :
2981             pVeboxState->FFDISurfaces[0]));
2982 
2983     // Copy VEBOX State
2984     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxCopyVeboxStates());
2985 
2986     // Update VEBOX State
2987     VPHAL_RENDER_CHK_STATUS(VeboxUpdateVeboxStates(pSrcSurface));
2988 
2989 finish:
2990     return eStatus;
2991 }
2992 
2993 //!
2994 //! \brief    Vebox render mode2
2995 //! \details  VEBOX/IECP Rendering for future frame
2996 //!           [Flow] 1. For future frame; send cmd.
2997 //!                  2. setup state for next vebox operation.
2998 //!                  3. Request "speculative" copy state, update state.
2999 //! \param    [in] pSrcSurface
3000 //!           Pointer to input surface of Vebox
3001 //! \param    [in] pOutputSurface
3002 //!           Pointer to output surface of Vebox
3003 //! \return   MOS_STATUS
3004 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3005 //!
VeboxRenderMode2(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutputSurface)3006 MOS_STATUS VPHAL_VEBOX_STATE::VeboxRenderMode2(
3007     PVPHAL_SURFACE           pSrcSurface,
3008     PVPHAL_SURFACE           pOutputSurface)
3009 {
3010     PMOS_INTERFACE           pOsInterface;
3011     PVPHAL_SURFACE           pRefSurface;
3012     MOS_STATUS               eStatus;
3013     PVPHAL_VEBOX_STATE       pVeboxState = this;
3014     PVPHAL_VEBOX_RENDER_DATA pRenderData = GetLastExecRenderData();
3015 
3016     MOS_UNUSED(pOutputSurface);
3017 
3018     VPHAL_RENDER_CHK_NULL(pRenderData);
3019     VPHAL_RENDER_ASSERT(pVeboxState);
3020     VPHAL_RENDER_ASSERT(pRenderData);
3021     VPHAL_RENDER_ASSERT(pSrcSurface);
3022     VPHAL_RENDER_ASSERT(pOutputSurface);
3023     VPHAL_RENDER_ASSERT((IS_VEBOX_EXECUTION_MODE_2(pVeboxState->m_pVeboxExecState) == true));
3024 
3025     // Initialize Variables
3026     pOsInterface    = pVeboxState->m_pOsInterface;
3027     eStatus         = MOS_STATUS_SUCCESS;
3028 
3029     // Ensure the input is ready to be read
3030     pOsInterface->pfnSyncOnResource(
3031         pOsInterface,
3032         &pSrcSurface->OsResource,
3033         MOS_GPU_CONTEXT_VEBOX,
3034         false);
3035 
3036     if (pRenderData->bRefValid)
3037     {
3038         pOsInterface->pfnSyncOnResource(
3039             pOsInterface,
3040             &pSrcSurface->pFwdRef->OsResource,
3041             MOS_GPU_CONTEXT_VEBOX,
3042             false);
3043     }
3044 
3045     // Set up reference surfaces. Should pick up future frame
3046     pRefSurface = VeboxSetReference(pSrcSurface);
3047 
3048     // Set current DN output buffer
3049     pRenderData->iCurDNOut = pVeboxState->iCurDNIndex;
3050 
3051     // Set the FMD output frames
3052     if (pVeboxState->m_pVeboxExecState->bDIOutputPair01 == true)
3053     {
3054         pRenderData->iFrame0      = 0;
3055         pRenderData->iFrame1      = 1;
3056         pVeboxState->m_pVeboxExecState->bDIOutputPair01 = false;
3057     }
3058     else
3059     {
3060         pRenderData->iFrame0      = 2;
3061         pRenderData->iFrame1      = 3;
3062         pVeboxState->m_pVeboxExecState->bDIOutputPair01 = true;
3063     }
3064 
3065     // Setup Motion history for DI
3066     // for ffDI, ffDN and ffDNDI cases
3067     pRenderData->iCurHistIn  = (pVeboxState->iCurStmmIndex) & 1;
3068     pRenderData->iCurHistOut = (pVeboxState->iCurStmmIndex + 1) & 1;
3069 
3070     // Set current frame. Previous frame is set in VeboxSetReference()
3071     CopySurfaceValue(pVeboxState->m_currentSurface, pSrcSurface->pFwdRef);
3072 
3073     // Set current/previous timestamps for next call
3074     pVeboxState->iCurFrameID = pSrcSurface->pFwdRef->FrameID;
3075     pVeboxState->iPrvFrameID = pSrcSurface->FrameID;
3076 
3077     // Allocate Resources if needed
3078     VPHAL_RENDER_CHK_STATUS(pVeboxState->AllocateResources());
3079 
3080     // For CP HM which requires to use render engine for copy and
3081     // update Vebox heap, speculative copy has already been done in previous
3082     // blt call to increase the Vebox & Render engine parallelism.
3083     // For LM, CPU can lock & update the resource quickly here because
3084     // previous blt's Vebox workload should be already done.
3085     // Thus, here we do the copy & update only for LM.
3086     if (!pOsInterface->osCpInterface->IsHMEnabled())
3087     {
3088         // Setup, Copy and Update VEBOX State
3089         VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxCopyAndUpdateVeboxState(pSrcSurface));
3090     }
3091 
3092     // Send VEBOX Command Buffer
3093     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxSendVeboxCmd());
3094 
3095 #if 0
3096     // FMD Calc extra variances has been moved to after composition
3097     // to prevent blocking Vebox / Composition parallelism.
3098     REQUEST_VEBOX_POSTPONED_FMD_CALC(pVeboxState->m_pVeboxExecState);
3099 #endif
3100 
3101     //--------------------------------------------------------------------------
3102     // ffDN and ffDNDI cases
3103     //--------------------------------------------------------------------------
3104     if (pRenderData->bDenoise)
3105     {
3106         CopySurfaceValue(pVeboxState->m_currentSurface, pVeboxState->FFDNSurfaces[pRenderData->iCurDNOut]);
3107     }
3108 
3109     //--------------------------------------------------------------------------
3110     // Swap buffers for next iteration
3111     //--------------------------------------------------------------------------
3112     pVeboxState->iCurDNIndex     = (pRenderData->iCurDNOut + 1) & 1;
3113     pVeboxState->iCurStmmIndex   = (pVeboxState->iCurStmmIndex + 1) & 1;
3114 
3115 finish:
3116     return eStatus;
3117 }
3118 
3119 //!
3120 //! \brief    Vebox render mode0to2
3121 //! \details  Purpose   : VEBOX/IECP Rendering for current and future frame
3122 //!           [Flow] 1. For current frame; setup state, copy state, update state, send cmd.
3123 //!                  2. For future frame;  setup state, copy state, update state, send cmd.
3124 //!                  3. setup state for next vebox operation.
3125 //!                  4. Request "speculative" copy state, update state.
3126 //! \param    [in] pSrcSurface
3127 //!           Pointer to input surface of Vebox
3128 //! \param    [in] pOutputSurface
3129 //!           Pointer to output surface of Vebox
3130 //! \return   MOS_STATUS
3131 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3132 //!
VeboxRenderMode0To2(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutputSurface)3133 MOS_STATUS VPHAL_VEBOX_STATE::VeboxRenderMode0To2(
3134     PVPHAL_SURFACE           pSrcSurface,
3135     PVPHAL_SURFACE           pOutputSurface)
3136 {
3137     PMOS_INTERFACE           pOsInterface;
3138     PVPHAL_SURFACE           pRefSurface;
3139     MOS_STATUS               eStatus;
3140     PVPHAL_VEBOX_STATE       pVeboxState = this;
3141     PVPHAL_VEBOX_RENDER_DATA pRenderData = GetLastExecRenderData();
3142 
3143     MOS_UNUSED(pOutputSurface);
3144 
3145     VPHAL_RENDER_CHK_NULL(pRenderData);
3146     VPHAL_RENDER_ASSERT(pVeboxState);
3147     VPHAL_RENDER_ASSERT(pRenderData);
3148     VPHAL_RENDER_ASSERT(pSrcSurface);
3149     VPHAL_RENDER_ASSERT(pOutputSurface);
3150     VPHAL_RENDER_ASSERT((IS_VEBOX_EXECUTION_MODE_0_TO_2(pVeboxState->m_pVeboxExecState) == true));
3151 
3152     // Initialize Variables
3153     pOsInterface    = pVeboxState->m_pOsInterface;
3154     eStatus         = MOS_STATUS_SUCCESS;
3155 
3156     // =========================================================================
3157     // 1st operation (frame 1 - current surface)
3158     // =========================================================================
3159 
3160     // Ensure the input is ready to be read
3161     pOsInterface->pfnSyncOnResource(
3162         pOsInterface,
3163         &pSrcSurface->OsResource,
3164         MOS_GPU_CONTEXT_VEBOX,
3165         false);
3166 
3167     if (pRenderData->bRefValid)
3168     {
3169         pOsInterface->pfnSyncOnResource(
3170             pOsInterface,
3171             &pSrcSurface->pBwdRef->OsResource,
3172             MOS_GPU_CONTEXT_VEBOX,
3173             false);
3174     }
3175 
3176     // Set up reference surfaces
3177     pRefSurface = VeboxSetReference(pSrcSurface);
3178 
3179     // Set current DN output buffer
3180     pRenderData->iCurDNOut = pVeboxState->iCurDNIndex;
3181 
3182     // To avoid ambiguity, for Mode0To2,
3183     // Always render 1st frame to 01 pair,
3184     //        render 2nd frame to 23 pair,
3185     //        and use 01 pair as output in mode0To2.
3186     // No need to toggle the DIOutputPair01 flag here.
3187     pVeboxState->m_pVeboxExecState->bDIOutputPair01 = true;
3188 
3189     // Set the FMD output frames
3190     pRenderData->iFrame0 = 0;
3191     pRenderData->iFrame1 = 1;
3192 
3193     // Setup Motion history for DI
3194     // for ffDI, ffDN and ffDNDI cases
3195     pRenderData->iCurHistIn  = (pVeboxState->iCurStmmIndex) & 1;
3196     pRenderData->iCurHistOut = (pVeboxState->iCurStmmIndex + 1) & 1;
3197 
3198     // Set current src = current primary input
3199     CopySurfaceValue(pVeboxState->m_currentSurface, pSrcSurface);
3200 
3201     // Allocate Resources if needed
3202     VPHAL_RENDER_CHK_STATUS(pVeboxState->AllocateResources());
3203 
3204     // Set current/previous timestamps for next call
3205     pVeboxState->iCurFrameID = pSrcSurface->FrameID;
3206 
3207     if (pRenderData->bRefValid)
3208     {
3209         VPHAL_RENDER_CHK_NULL(pRefSurface);
3210 
3211         pVeboxState->iPrvFrameID = pRefSurface->FrameID;
3212     }
3213     else
3214     {
3215         pVeboxState->iPrvFrameID = -1;
3216     }
3217 
3218     // Setup, Copy and Update VEBOX State
3219     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxCopyAndUpdateVeboxState(pSrcSurface));
3220 
3221     // Send VEBOX Command Buffer
3222     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxSendVeboxCmd());
3223 
3224     // Next phase synchronization with Render Engine
3225     pOsInterface->pfnSyncGpuContext(
3226         pOsInterface,
3227         MOS_GPU_CONTEXT_VEBOX,
3228         RenderGpuContext);
3229 
3230     //--------------------------------------------------------------------------
3231     // ffDN and ffDNDI cases
3232     //--------------------------------------------------------------------------
3233     if (pRenderData->bDenoise)
3234     {
3235         CopySurfaceValue(pVeboxState->m_currentSurface, pVeboxState->FFDNSurfaces[pRenderData->iCurDNOut]);
3236     }
3237 
3238     //--------------------------------------------------------------------------
3239     // Swap buffers for next iteration
3240     //--------------------------------------------------------------------------
3241     pVeboxState->iCurDNIndex     = (pRenderData->iCurDNOut + 1) & 1;
3242     pVeboxState->iCurStmmIndex   = (pVeboxState->iCurStmmIndex + 1) & 1;
3243 
3244     // Set the first frame flag
3245     if (pVeboxState->bFirstFrame)
3246     {
3247         pVeboxState->bFirstFrame = false;
3248     }
3249 
3250     // End 1st operation (frame 1 - current surface)
3251 
3252     // Switch state
3253     SET_VEBOX_EXECUTION_MODE(pVeboxState->m_pVeboxExecState, VEBOX_EXEC_MODE_2);
3254 
3255     // In VpHal_VeboxGetStatisticsSurfaceOffsets, the offset of vebox statistics surface
3256     // address is based on whether bDN/DIEnabled in the previous function call. We get
3257     // bDN/DIEnabled here, so that bDN/DIEnabled can be used at the beginning of the next
3258     // function call.
3259     // When Spatial DI enabled and Temporal DI disabled, the vebox statistics surface
3260     // layout is same as the case when only DN enabled, so use DNEnabled to include the
3261     // case when Spatial DI enabled.
3262     pVeboxState->bDNEnabled = pRenderData->bDenoise         ||
3263                              pRenderData->bChromaDenoise    ||
3264                              ((pRenderData->bDeinterlace    ||
3265                                pVeboxState->IsQueryVarianceEnabled()) &&
3266                               !pRenderData->bRefValid);
3267 
3268     pVeboxState->bDIEnabled = (pRenderData->bDeinterlace   ||
3269                               pVeboxState->IsQueryVarianceEnabled()) &&
3270                              pRenderData->bRefValid;
3271 
3272     // =========================================================================
3273     // 2nd operation (frame 2 - future surface)
3274     // =========================================================================
3275 
3276     // Set render flags for frame 2
3277     pVeboxState->VeboxSetRenderingFlags(
3278         pSrcSurface,
3279         pRenderData->pRenderTarget);
3280 
3281     if (pRenderData->bRefValid)
3282     {
3283         // Ensure the input is ready to be read
3284         pOsInterface->pfnSyncOnResource(
3285             pOsInterface,
3286             &pSrcSurface->pFwdRef->OsResource,
3287             MOS_GPU_CONTEXT_VEBOX,
3288             false);
3289     }
3290 
3291     // Set up reference surfaces.
3292     // It set pVeboxState->PreviousSurface w/ the correct surface.
3293     // pReference is not used.
3294     pRefSurface = VeboxSetReference(pSrcSurface);
3295 
3296     // Set current DN output buffer
3297     pRenderData->iCurDNOut = pVeboxState->iCurDNIndex;
3298 
3299     // Set the FMD output frames
3300     pRenderData->iFrame0 = 2;
3301     pRenderData->iFrame1 = 3;
3302 
3303     // Setup Motion history for DI
3304     // for ffDI, ffDN and ffDNDI cases
3305     pRenderData->iCurHistIn  = (pVeboxState->iCurStmmIndex) & 1;
3306     pRenderData->iCurHistOut = (pVeboxState->iCurStmmIndex + 1) & 1;
3307 
3308     // Set current frame. Previous frame is set in VeboxSetReference()
3309     CopySurfaceValue(pVeboxState->m_currentSurface, pSrcSurface->pFwdRef);
3310 
3311     // Set current/previous timestamps for next call
3312     pVeboxState->iCurFrameID = pSrcSurface->pFwdRef->FrameID;
3313     pVeboxState->iPrvFrameID = pSrcSurface->FrameID;
3314 
3315     // Setup, Copy and Update VEBOX State
3316     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxCopyAndUpdateVeboxState(pSrcSurface));
3317 
3318     // Send VEBOX Command Buffer
3319     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxSendVeboxCmd());
3320 
3321     //--------------------------------------------------------------------------
3322     // ffDN and ffDNDI cases
3323     //--------------------------------------------------------------------------
3324     if (pRenderData->bDenoise)
3325     {
3326         CopySurfaceValue(pVeboxState->m_currentSurface, pVeboxState->FFDNSurfaces[pRenderData->iCurDNOut]);
3327     }
3328 
3329     //--------------------------------------------------------------------------
3330     // Swap buffers for next iteration
3331     //--------------------------------------------------------------------------
3332     pVeboxState->iCurDNIndex     = (pRenderData->iCurDNOut + 1) & 1;
3333     pVeboxState->iCurStmmIndex   = (pVeboxState->iCurStmmIndex + 1) & 1;
3334 
3335     // End 2nd operation (frame 2 - future surface)
3336 
3337 finish:
3338     return eStatus;
3339 }
3340 
3341 //!
3342 //! \brief    Check whether DN surface limitation is satisfied
3343 //! \param    [in] bDenoise
3344 //!           Flag to indicate whether DN is enabled
3345 //! \param    [in] CurrentSurface
3346 //!           Input surface of Vebox
3347 //! \param    [in] FFDNSurface
3348 //!           DN surface of Vebox
3349 //! \return   bool
3350 //!           Return true for limitation satisfied, otherwise false
3351 //!
VeboxDNSurfaceLimitationSatisfied(bool bDenoise,VPHAL_SURFACE * CurrentSurface,VPHAL_SURFACE * FFDNSurface)3352 bool VPHAL_VEBOX_STATE::VeboxDNSurfaceLimitationSatisfied(
3353     bool                    bDenoise,
3354     VPHAL_SURFACE           *CurrentSurface,
3355     VPHAL_SURFACE           *FFDNSurface)
3356 {
3357     if (bDenoise == false)
3358     {
3359         return true;
3360     }
3361     else
3362     {
3363         if (CurrentSurface->bIsCompressed   == FFDNSurface->bIsCompressed   &&
3364             CurrentSurface->bCompressible   == FFDNSurface->bCompressible   &&
3365             CurrentSurface->CompressionMode == FFDNSurface->CompressionMode &&
3366             CurrentSurface->dwWidth         == FFDNSurface->dwWidth         &&
3367             CurrentSurface->dwHeight        == FFDNSurface->dwHeight        &&
3368             CurrentSurface->dwPitch         == FFDNSurface->dwPitch)
3369         {
3370             return true;
3371         }
3372         else
3373         {
3374             return false;
3375         }
3376     }
3377 }
3378 
3379 //!
3380 //! \brief    Vebox Render mode0
3381 //! \details  VEBOX/IECP Rendering for current frame
3382 //!           [Flow] 1. For current frame; setup state, copy state, update state, send cmd.
3383 //! \param    [in] pSrcSurface
3384 //!           Pointer to input surface of Vebox
3385 //! \param    [in] pOutputSurface
3386 //!           Pointer to output surface of Vebox
3387 //! \return   MOS_STATUS
3388 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3389 //!
VeboxRenderMode0(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutputSurface)3390 MOS_STATUS VPHAL_VEBOX_STATE::VeboxRenderMode0(
3391     PVPHAL_SURFACE           pSrcSurface,
3392     PVPHAL_SURFACE           pOutputSurface)
3393 {
3394     PMOS_INTERFACE        pOsInterface;
3395     PVPHAL_SURFACE        pRefSurface;
3396     MOS_STATUS            eStatus;
3397     PVPHAL_VEBOX_STATE          pVeboxState = this;
3398     PVPHAL_VEBOX_RENDER_DATA    pRenderData = GetLastExecRenderData();
3399 
3400     VPHAL_RENDER_CHK_NULL(pRenderData);
3401     VPHAL_RENDER_ASSERT(pVeboxState);
3402     VPHAL_RENDER_ASSERT(pRenderData);
3403     VPHAL_RENDER_ASSERT(pSrcSurface);
3404     VPHAL_RENDER_ASSERT(pOutputSurface);
3405     VPHAL_RENDER_ASSERT((IS_VEBOX_EXECUTION_MODE_0(pVeboxState->m_pVeboxExecState) == true));
3406 
3407     // Initialize Variables
3408     pOsInterface            = pVeboxState->m_pOsInterface;
3409     eStatus                 = MOS_STATUS_SUCCESS;
3410 
3411     // Ensure the input is ready to be read
3412     pOsInterface->pfnSyncOnResource(
3413         pOsInterface,
3414         &pSrcSurface->OsResource,
3415         MOS_GPU_CONTEXT_VEBOX,
3416         false);
3417 
3418     if (pRenderData->bRefValid)
3419     {
3420         pOsInterface->pfnSyncOnResource(
3421             pOsInterface,
3422             &pSrcSurface->pBwdRef->OsResource,
3423             MOS_GPU_CONTEXT_VEBOX,
3424             false);
3425     }
3426 
3427     // Set up reference surfaces
3428     pRefSurface = VeboxSetReference(pSrcSurface);
3429 
3430     if (pSrcSurface->bPreAPGWorkloadEnable && pRefSurface != nullptr)
3431     {
3432         pRefSurface->bPreAPGWorkloadEnable = false;
3433         pRenderData->bRefValid = false;
3434         MOS_ZeroMemory(m_previousSurface, sizeof(VPHAL_SURFACE));
3435     }
3436     // Set current DN output buffer
3437     pRenderData->iCurDNOut = pVeboxState->iCurDNIndex;
3438 
3439     // Set the FMD output frames
3440     pRenderData->iFrame0   = 0;
3441     pRenderData->iFrame1   = 1;
3442 
3443     // Always use 01 pair in mode0. In Mode2, may fall back to Mode0 so need to reset.
3444     pVeboxState->m_pVeboxExecState->bDIOutputPair01 = true;
3445 
3446     // Setup Motion history for DI
3447     // for ffDI, ffDN and ffDNDI cases
3448     pRenderData->iCurHistIn  = (pVeboxState->iCurStmmIndex) & 1;
3449     pRenderData->iCurHistOut = (pVeboxState->iCurStmmIndex + 1) & 1;
3450 
3451     // Set current src = current primary input
3452     CopySurfaceValue(pVeboxState->m_currentSurface, pSrcSurface);
3453 
3454     // Set current/previous timestamps for next call
3455     // If DN surface limitation is not satisfied, e.g. input uncompressed, DN compressed, then need to re-allocate DN surfaces.
3456     // When rcMaxSrc changed we should call AllocateResources to increase Statistics buffer size.
3457     if (pRenderData->bSameSamples                    &&
3458         !pVeboxState->m_currentSurface->bMaxRectChanged &&
3459         IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData)        &&
3460         VeboxDNSurfaceLimitationSatisfied(pRenderData->bDenoise, pVeboxState->m_currentSurface, pVeboxState->FFDNSurfaces[0]))
3461     {
3462         // Do nothing when VEBOX+SFC scenario's BLT2 case hits here
3463     }
3464     else
3465     {
3466         // Allocate Resources if needed
3467         VPHAL_RENDER_CHK_STATUS(pVeboxState->AllocateResources());
3468 
3469         pVeboxState->iCurFrameID = pSrcSurface->FrameID;
3470     }
3471 
3472     if (pRenderData->bRefValid)
3473     {
3474         VPHAL_RENDER_CHK_NULL(pRefSurface);
3475 
3476         pVeboxState->iPrvFrameID = pRefSurface->FrameID;
3477     }
3478     else
3479     {
3480         if (pRenderData->bSameSamples  &&
3481             IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData))
3482         {
3483             // Do nothing when VEBOX+SFC scenario's BLT2 case hits here
3484         }
3485         else
3486         {
3487             pVeboxState->iPrvFrameID = -1;
3488         }
3489     }
3490 
3491     // Setup, Copy and Update VEBOX State
3492     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxCopyAndUpdateVeboxState(pSrcSurface));
3493 
3494     // Setup SFC State if SFC is needed for current rendering
3495     if (IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData))
3496     {
3497         m_sfcPipeState->SetStereoChannel(pVeboxState->uiCurrentChannel);
3498 
3499         VPHAL_RENDER_CHK_STATUS(m_sfcPipeState->SetupSfcState(
3500             pSrcSurface,
3501             pOutputSurface,
3502             pRenderData));
3503     }
3504 
3505     // Send VEBOX Command Buffer
3506     VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxSendVeboxCmd());
3507 
3508     //--------------------------------------------------------------------------
3509     // ffDN and ffDNDI cases
3510     //--------------------------------------------------------------------------
3511     if (pRenderData->bDenoise)
3512     {
3513         CopySurfaceValue(pVeboxState->m_currentSurface, pVeboxState->FFDNSurfaces[pRenderData->iCurDNOut]);
3514     }
3515 
3516     if ((pRenderData->bDeinterlace ||
3517         !pRenderData->bRefValid)   &&
3518         pRenderData->bSameSamples  &&
3519         IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData))
3520     {
3521         CopySurfaceValue(pVeboxState->m_currentSurface, pVeboxState->FFDNSurfaces[(pRenderData->iCurDNOut + 1) & 1]);
3522     }
3523     else
3524     {
3525         //--------------------------------------------------------------------------
3526         // Swap buffers for next iteration
3527         //--------------------------------------------------------------------------
3528         pVeboxState->iCurDNIndex     = (pRenderData->iCurDNOut + 1) & 1;
3529         pVeboxState->iCurStmmIndex   = (pVeboxState->iCurStmmIndex + 1) & 1;
3530     }
3531 
3532     // Set the first frame flag
3533     if (pVeboxState->bFirstFrame)
3534     {
3535         pVeboxState->bFirstFrame = false;
3536     }
3537 
3538 finish:
3539     return eStatus;
3540 }
3541 
GetOutputSurfForDiSameSampleWithSFC(PVPHAL_SURFACE pSrcSurface)3542 PVPHAL_SURFACE VPHAL_VEBOX_STATE::GetOutputSurfForDiSameSampleWithSFC(
3543     PVPHAL_SURFACE pSrcSurface)
3544 {
3545     PVPHAL_VEBOX_STATE       pVeboxState    = this;
3546     PVPHAL_VEBOX_RENDER_DATA pRenderData    = pVeboxState->GetLastExecRenderData();
3547     PVPHAL_SURFACE           pOutputSurface = pSrcSurface;
3548     if (!pRenderData)
3549     {
3550         VPHAL_RENDER_ASSERTMESSAGE("pRenderData is nullptr!");
3551         return nullptr;
3552     }
3553 
3554     // Update rect sizes in FFDI surface if input surface rect size changes
3555     if (pSrcSurface->rcSrc.left      != pVeboxState->FFDISurfaces[0]->rcSrc.left     ||
3556         pSrcSurface->rcSrc.right     != pVeboxState->FFDISurfaces[0]->rcSrc.right    ||
3557         pSrcSurface->rcSrc.top       != pVeboxState->FFDISurfaces[0]->rcSrc.top      ||
3558         pSrcSurface->rcSrc.bottom    != pVeboxState->FFDISurfaces[0]->rcSrc.bottom   ||
3559         pSrcSurface->rcDst.left      != pVeboxState->FFDISurfaces[0]->rcDst.left     ||
3560         pSrcSurface->rcDst.right     != pVeboxState->FFDISurfaces[0]->rcDst.right    ||
3561         pSrcSurface->rcDst.top       != pVeboxState->FFDISurfaces[0]->rcDst.top      ||
3562         pSrcSurface->rcDst.bottom    != pVeboxState->FFDISurfaces[0]->rcDst.bottom   ||
3563         pSrcSurface->rcMaxSrc.left   != pVeboxState->FFDISurfaces[0]->rcMaxSrc.left  ||
3564         pSrcSurface->rcMaxSrc.right  != pVeboxState->FFDISurfaces[0]->rcMaxSrc.right ||
3565         pSrcSurface->rcMaxSrc.top    != pVeboxState->FFDISurfaces[0]->rcMaxSrc.top   ||
3566         pSrcSurface->rcMaxSrc.bottom != pVeboxState->FFDISurfaces[0]->rcMaxSrc.bottom)
3567     {
3568         pVeboxState->FFDISurfaces[0]->rcSrc    = pSrcSurface->rcSrc;
3569         pVeboxState->FFDISurfaces[0]->rcDst    = pSrcSurface->rcDst;
3570         pVeboxState->FFDISurfaces[0]->rcMaxSrc = pSrcSurface->rcMaxSrc;
3571     }
3572 
3573     if (pSrcSurface->rcSrc.left      != pVeboxState->FFDISurfaces[1]->rcSrc.left     ||
3574         pSrcSurface->rcSrc.right     != pVeboxState->FFDISurfaces[1]->rcSrc.right    ||
3575         pSrcSurface->rcSrc.top       != pVeboxState->FFDISurfaces[1]->rcSrc.top      ||
3576         pSrcSurface->rcSrc.bottom    != pVeboxState->FFDISurfaces[1]->rcSrc.bottom   ||
3577         pSrcSurface->rcDst.left      != pVeboxState->FFDISurfaces[1]->rcDst.left     ||
3578         pSrcSurface->rcDst.right     != pVeboxState->FFDISurfaces[1]->rcDst.right    ||
3579         pSrcSurface->rcDst.top       != pVeboxState->FFDISurfaces[1]->rcDst.top      ||
3580         pSrcSurface->rcDst.bottom    != pVeboxState->FFDISurfaces[1]->rcDst.bottom   ||
3581         pSrcSurface->rcMaxSrc.left   != pVeboxState->FFDISurfaces[1]->rcMaxSrc.left  ||
3582         pSrcSurface->rcMaxSrc.right  != pVeboxState->FFDISurfaces[1]->rcMaxSrc.right ||
3583         pSrcSurface->rcMaxSrc.top    != pVeboxState->FFDISurfaces[1]->rcMaxSrc.top   ||
3584         pSrcSurface->rcMaxSrc.bottom != pVeboxState->FFDISurfaces[1]->rcMaxSrc.bottom)
3585     {
3586         pVeboxState->FFDISurfaces[1]->rcSrc    = pSrcSurface->rcSrc;
3587         pVeboxState->FFDISurfaces[1]->rcDst    = pSrcSurface->rcDst;
3588         pVeboxState->FFDISurfaces[1]->rcMaxSrc = pSrcSurface->rcMaxSrc;
3589     }
3590 
3591     // Update IEF parameters in FFDI surface
3592     pVeboxState->FFDISurfaces[0]->pIEFParams   = pSrcSurface->pIEFParams;
3593     pVeboxState->FFDISurfaces[1]->pIEFParams   = pSrcSurface->pIEFParams;
3594 
3595     // Set BLT1's Current DI Output as BLT2's input, it is always under Mode0
3596     // BLT1 output 1st field of current frame for the following cases:
3597     // a) 30fps (bSingleField),
3598     // c) 60fps 2nd field
3599     if (pRenderData->bSingleField                                               ||
3600         (pSrcSurface->SampleType == SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD)     ||
3601         (pSrcSurface->SampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD) ||
3602         (pSrcSurface->SampleType == SAMPLE_SINGLE_BOTTOM_FIELD)                 ||
3603         (pSrcSurface->SampleType == SAMPLE_PROGRESSIVE))
3604     {
3605         pOutputSurface = pVeboxState->FFDISurfaces[1];
3606     }
3607     else
3608     {
3609         // First sample output - 2nd field of the previous frame
3610         pOutputSurface = pVeboxState->FFDISurfaces[0];
3611     }
3612 
3613     // Force vebox to bypass data on BLT2
3614     pRenderData->bDeinterlace   = false;
3615     pRenderData->bIECP          = false;
3616     pRenderData->bDenoise       = false;
3617     pRenderData->bChromaDenoise = false;
3618 #if VEBOX_AUTO_DENOISE_SUPPORTED
3619     pRenderData->bAutoDenoise   = false;
3620 #endif
3621     pRenderData->bRefValid      = false;
3622 
3623     return pOutputSurface;
3624 }
3625 
3626 //!
3627 //! \brief    Vebox Rendering
3628 //! \details  Vebox rendering, do all the staff for Vebox process,
3629 //!           include implementation of VEBOX/IECP features,
3630 //!           execution of Vebox/Render parallelism,
3631 //!           CPU/GPU (for CP HM) path for Vebox state heap update,
3632 //!           setup input/output/statistics/STMM surface,
3633 //! \param    [in] pcRenderParams
3634 //!           Pointer to Render parameters
3635 //! \param    [in,out] pRenderPassData
3636 //!           Pointer to Render data
3637 //! \return   MOS_STATUS
3638 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3639 //!
Render(PCVPHAL_RENDER_PARAMS pcRenderParams,RenderpassData * pRenderPassData)3640 MOS_STATUS VPHAL_VEBOX_STATE::Render(
3641     PCVPHAL_RENDER_PARAMS  pcRenderParams,
3642     RenderpassData         *pRenderPassData)
3643 {
3644     PRENDERHAL_INTERFACE     pRenderHal;
3645     PMOS_INTERFACE           pOsInterface;
3646     MOS_STATUS               eStatus;
3647     PVPHAL_VEBOX_RENDER_DATA pRenderData;
3648     bool                     bRender;
3649     bool                     bDIVeboxBypass;
3650     PVPHAL_VEBOX_STATE       pVeboxState = this;
3651     PVPHAL_SURFACE           pSrcSurface;
3652     PVPHAL_SURFACE           pOutputSurface;
3653 
3654     MOS_UNUSED(pcRenderParams);
3655 
3656     pSrcSurface     = pRenderPassData->pSrcSurface;
3657     pOutputSurface  = pRenderPassData->pOutSurface;
3658 
3659     VPHAL_RENDER_ASSERT(pVeboxState);
3660     VPHAL_RENDER_ASSERT(pSrcSurface);
3661     VPHAL_RENDER_ASSERT(pOutputSurface);
3662 
3663     // Initialize Variables
3664     pRenderHal              = pVeboxState->m_pRenderHal;
3665     pOsInterface            = pVeboxState->m_pOsInterface;
3666     eStatus                 = MOS_STATUS_SUCCESS;
3667     bRender                 = false;
3668     bDIVeboxBypass          = false;
3669     pRenderData             = pVeboxState->GetLastExecRenderData();
3670 
3671     VPHAL_RENDER_CHK_NULL(pRenderData);
3672 
3673     VPHAL_DBG_STATE_DUMPPER_SET_CURRENT_STAGE(VPHAL_DBG_STAGE_VEBOX);
3674 
3675     // Check bSameSamples only when reference is avaliable, DI, Variance Query is enabled
3676     if (pRenderData->bRefValid     &&
3677         pRenderData->bSameSamples  &&
3678         (pRenderData->bDeinterlace || pVeboxState->IsQueryVarianceEnabled()))
3679     {
3680         // No frames to generate -> output frames already in buffer
3681         if (IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData) &&
3682             pRenderData->bDeinterlace)                // Vebox + SFC
3683         {
3684             bDIVeboxBypass = true;
3685             pSrcSurface    = GetOutputSurfForDiSameSampleWithSFC(pSrcSurface);
3686         }
3687         else
3688         {
3689             // Need not submit Vebox commands, jump out accordingly
3690             goto dndi_sample_out;
3691         }
3692     }
3693 
3694     if (pcRenderParams->bAPGWorkloadEnable)
3695     {
3696         pSrcSurface->bPreAPGWorkloadEnable = true;
3697         pRenderData->bRefValid = false;
3698     }
3699     else
3700     {
3701         pSrcSurface->bPreAPGWorkloadEnable = false;
3702     }
3703 
3704     if (IS_VEBOX_EXECUTION_MODE_0_TO_2(pVeboxState->m_pVeboxExecState))
3705     {
3706         // Transition from serial to parallel mode. 2 vebox operations, current
3707         // and future frames
3708         VPHAL_RENDER_CHK_STATUS(VeboxRenderMode0To2(
3709             pSrcSurface,
3710             pOutputSurface));
3711     }
3712     else if (IS_VEBOX_EXECUTION_MODE_2(pVeboxState->m_pVeboxExecState))
3713     {
3714         // Parallel mode. 1 vebox operation, future frame
3715         VPHAL_RENDER_CHK_STATUS(VeboxRenderMode2(
3716             pSrcSurface,
3717             pOutputSurface));
3718     }
3719     else if (IS_VEBOX_EXECUTION_MODE_0(pVeboxState->m_pVeboxExecState))
3720     {
3721         // Legacy serial mode. 1 vebox operation, current frame
3722         VPHAL_RENDER_CHK_STATUS(VeboxRenderMode0(
3723             pSrcSurface,
3724             pOutputSurface));
3725     }
3726     else
3727     {
3728         VPHAL_RENDER_ASSERTMESSAGE("Invalid VEBox state.");
3729         goto finish;
3730     }
3731 
3732     VPHAL_DBG_STATE_DUMPPER_DUMP_VEBOX_STATES(pRenderHal, pVeboxState);
3733 
3734     if (IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData))
3735     {
3736         goto sfc_sample_out;
3737     }
3738 
3739     if (IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
3740     {
3741         goto vebox_out_in_RT;
3742     }
3743 
3744 dndi_sample_out:
3745     if (IS_VEBOX_EXECUTION_MODE_2(pVeboxState->m_pVeboxExecState))
3746     {
3747         // Select output surface that was rendered in the previous blt
3748         // It will be used in VpHal_VeboxSetDiOutput()
3749         // Note: After toggling it, pRenderData->iCurDNOut does not represent
3750         // the one that is rendered this time
3751         pRenderData->iCurDNOut = (pRenderData->iCurDNOut + 1) & 1;
3752     }
3753 
3754     // Select DI sample to be used for compositing stage
3755     VPHAL_RENDER_CHK_STATUS(VeboxSetDiOutput(pSrcSurface, pOutputSurface));
3756 
3757     VPHAL_RENDER_EXITMESSAGE("Exit with DI output.");
3758     goto finish;
3759 
3760 sfc_sample_out:
3761     if (pVeboxState->m_pVeboxExecState->bDIOutputPair01)
3762     {
3763         pRenderData->iFrame0 = pRenderData->bSameSamples ? 1 : 0;
3764     }
3765     else
3766     {
3767         pRenderData->iFrame0 = pRenderData->bSameSamples ? 3 : 2;
3768     }
3769 
3770     // Feature reporting
3771     m_reporting->GetFeatures().iecp    = pRenderData->bIECP;
3772     m_reporting->GetFeatures().denoise = pRenderData->bDenoise;
3773 
3774     if (pRenderData->bDeinterlace)
3775     {
3776         m_reporting->GetFeatures().deinterlaceMode =
3777             (pRenderData->bSingleField &&
3778                 (!pRenderData->bRefValid  ||
3779                 pSrcSurface->pDeinterlaceParams->DIMode == DI_MODE_BOB)) ?
3780             VPHAL_DI_REPORT_ADI_BOB                                   :    // VEBOX BOB
3781             VPHAL_DI_REPORT_ADI;                                           // ADI
3782     }
3783 
3784     // Select SFC output
3785     VPHAL_RENDER_EXITMESSAGE("Exit with SFC output.");
3786     goto finish;
3787 
3788 vebox_out_in_RT:
3789     VPHAL_RENDER_EXITMESSAGE("Exit VEBOX with CSC output.");
3790 
3791 finish:
3792     // In VpHal_VeboxGetStatisticsSurfaceOffsets, the offset of vebox statistics surface
3793     // address is based on whether bDN/DIEnabled in the previous function call. We get
3794     // bDN/DIEnabled here, so that bDN/DIEnabled can be used at the beginning of the next
3795     // function call.
3796     // When Spatial DI enabled and Temporal DI disabled, the vebox statistics surface
3797     // layout is same as the case when only DN enabled, so use DNEnabled to include the
3798     // case when Spatial DI enabled.
3799     if (pRenderData->bSameSamples  &&
3800         IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData))
3801     {
3802         // Do nothing when VEBOX+SFC scenario's BLT2 case hits here
3803     }
3804     else
3805     {
3806         pVeboxState->bDNEnabled = pRenderData->bDenoise         ||
3807                                   pRenderData->bChromaDenoise   ||
3808                                   ((pRenderData->bDeinterlace   ||
3809                                    pVeboxState->IsQueryVarianceEnabled()) &&
3810                                   !pRenderData->bRefValid);
3811 
3812         pVeboxState->bDIEnabled = (pRenderData->bDeinterlace    ||
3813                                    pVeboxState->IsQueryVarianceEnabled()) &&
3814                                    pRenderData->bRefValid;
3815     }
3816 
3817     // Switch GPU Context to Render Engine
3818     pOsInterface->pfnSetGpuContext(pOsInterface, RenderGpuContext);
3819 
3820     // Vebox feature report -- set the output pipe
3821     if (pRenderData->b2PassesCSC)
3822     {   //set 2passcsc outputpipe to VPHAL_OUTPUT_PIPE_MODE_COMP for final report.
3823         SET_VPHAL_OUTPUT_PIPE(pRenderData, VPHAL_OUTPUT_PIPE_MODE_COMP);
3824     }
3825     m_reporting->GetFeatures().outputPipeMode = pRenderData->OutputPipe;
3826     m_reporting->GetFeatures().diScdMode      = pRenderData->VeboxDNDIParams.bSyntheticFrame;
3827 
3828     // DI with ref 2nd filed use SFC output
3829     // Update VEBOX usage report here
3830     if (bDIVeboxBypass)
3831     {
3832         m_reporting->GetFeatures().veFeatureInUse = false;
3833     }
3834     else
3835     {
3836         m_reporting->GetFeatures().veFeatureInUse = !pRenderData->bVeboxBypass;
3837     }
3838 
3839     return eStatus;
3840 }
3841 
3842 //!
3843 //! \brief    Set DI output frame
3844 //! \details  Choose 2nd Field of Previous frame, 1st Field of Current frame
3845 //!           or both frames
3846 //! \param    [in] pRenderData
3847 //!           Pointer to Render data
3848 //! \param    [in] pVeboxState
3849 //!           Pointer to Vebox State
3850 //! \param    [in] pVeboxMode
3851 //!           Pointer to Vebox Mode
3852 //! \return   GFX_MEDIA_VEBOX_DI_OUTPUT_MODE
3853 //!           Return Previous/Current/Both frames
3854 //!
SetDIOutputFrame(PVPHAL_VEBOX_RENDER_DATA pRenderData,PVPHAL_VEBOX_STATE pVeboxState,PMHW_VEBOX_MODE pVeboxMode)3855 GFX_MEDIA_VEBOX_DI_OUTPUT_MODE VPHAL_VEBOX_STATE::SetDIOutputFrame(
3856     PVPHAL_VEBOX_RENDER_DATA pRenderData,
3857     PVPHAL_VEBOX_STATE       pVeboxState,
3858     PMHW_VEBOX_MODE          pVeboxMode)
3859 {
3860     // for 30i->30fps + SFC
3861     if (IS_VPHAL_OUTPUT_PIPE_SFC(pRenderData) && !pRenderData->b60fpsDi)
3862     {
3863         // Set BLT1's Current DI Output as BLT2's input, it is always under Mode0
3864         // BLT1 output 1st field of current frame for the following cases:
3865         if (pVeboxMode->DNDIFirstFrame                                                            ||
3866             (pVeboxState->m_currentSurface->SampleType == SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD) ||
3867             (pVeboxState->m_currentSurface->SampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD)   ||
3868             (pVeboxState->m_currentSurface->SampleType == SAMPLE_SINGLE_TOP_FIELD)                   ||
3869             (pVeboxState->m_currentSurface->SampleType == SAMPLE_PROGRESSIVE))
3870         {
3871             return MEDIA_VEBOX_DI_OUTPUT_CURRENT;
3872         }
3873         else
3874         {
3875             // First sample output - 2nd field of the previous frame
3876             return MEDIA_VEBOX_DI_OUTPUT_PREVIOUS;
3877         }
3878     }
3879     // for 30i->60fps or other 30i->30fps cases
3880     else
3881     {
3882         if (IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
3883         {
3884             // Align with the logic in SetupDiIecpState. The previous output surface is not needed for OUTPUT_PIPE_VEBOX case.
3885             return MEDIA_VEBOX_DI_OUTPUT_CURRENT;
3886         }
3887         else
3888         {
3889             return pVeboxMode->DNDIFirstFrame ?
3890                 MEDIA_VEBOX_DI_OUTPUT_CURRENT :
3891                 MEDIA_VEBOX_DI_OUTPUT_BOTH;
3892         }
3893     }
3894 }
3895 
3896 //!
3897 //! \brief    Vebox post-composition activity for parallel engine
3898 //! \details  update Vebox state heap, and FMD extra variances
3899 //! \param    [in] pVeboxExecState
3900 //!           Pointer to Vebox execution state
3901 //! \param    [in] pPriSurface
3902 //!           Pointer to primary surface of compostion, which was processed in last Vebox call
3903 //! \return   MOS_STATUS
3904 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
3905 //!
PostCompRender(PVPHAL_VEBOX_EXEC_STATE pVeboxExecState,PVPHAL_SURFACE pPriSurface)3906 MOS_STATUS VPHAL_VEBOX_STATE::PostCompRender(
3907     PVPHAL_VEBOX_EXEC_STATE     pVeboxExecState,
3908     PVPHAL_SURFACE              pPriSurface)
3909 {
3910     MOS_STATUS              eStatus;
3911     PMOS_INTERFACE          pOsInterface;
3912     PVPHAL_VEBOX_STATE      pVeboxState = this;
3913 
3914     VPHAL_RENDER_ASSERT(pVeboxState);
3915 
3916     eStatus             = MOS_STATUS_SUCCESS;
3917     pOsInterface        = pVeboxState->m_pOsInterface;
3918 
3919     // In Mode0To2 or Mode2, speculatively copy vebox state information for use
3920     // in next vebox op based on last vebox op's state info.
3921     if (IS_VEBOX_SPECULATIVE_COPY_REQUESTED(pVeboxExecState))
3922     {
3923         VPHAL_RENDER_CHK_STATUS(pVeboxState->VeboxCopyAndUpdateVeboxState(
3924             pPriSurface));
3925 
3926         RESET_VEBOX_SPECULATIVE_COPY(pVeboxExecState);
3927     }
3928 
3929 finish:
3930     return eStatus;
3931 }
3932 
3933 //!
3934 //! \brief    Check if 2 passes CSC are needed
3935 //! \param    [in] pSrc
3936 //!           Pointer to input surface of Vebox
3937 //! \param    [in] pRenderTarget
3938 //!           Pointer to Render targe surface of VPP BLT
3939 //! \return   bool
3940 //!           return true if 2 Passes CSC is needed, otherwise false
3941 //!
VeboxIs2PassesCSCNeeded(PVPHAL_SURFACE pSrc,PVPHAL_SURFACE pRenderTarget)3942 bool VPHAL_VEBOX_STATE::VeboxIs2PassesCSCNeeded(
3943     PVPHAL_SURFACE              pSrc,
3944     PVPHAL_SURFACE              pRenderTarget)
3945 {
3946     bool bRet                   = false;
3947     bool b2PassesCSCNeeded      = false;
3948     bool bFormatSupported       = false;
3949     bool bPlatformSupported     = false;
3950     PVPHAL_VEBOX_STATE          pVeboxState = this;
3951     PVPHAL_VEBOX_RENDER_DATA    pRenderData = GetLastExecRenderData();
3952 
3953     MOS_OS_CHK_NULL_NO_STATUS(pVeboxState);
3954     MOS_OS_CHK_NULL_NO_STATUS(pSrc);
3955     MOS_OS_CHK_NULL_NO_STATUS(pRenderTarget);
3956     MOS_OS_CHK_NULL_NO_STATUS(pRenderData);
3957 
3958     // 2 Passes CSC is used in BT2020YUV->BT601/709YUV
3959     // Isolate decoder require SFC output, but SFC can not support RGB input,
3960     // so sRGB need two pass, that same as original logic.
3961     if (IS_COLOR_SPACE_BT2020_YUV(pSrc->ColorSpace))
3962     {
3963         if ((pRenderTarget->ColorSpace == CSpace_BT601)           ||
3964             (pRenderTarget->ColorSpace == CSpace_BT709)           ||
3965             (pRenderTarget->ColorSpace == CSpace_BT601_FullRange) ||
3966             (pRenderTarget->ColorSpace == CSpace_BT709_FullRange) ||
3967             (pRenderTarget->ColorSpace == CSpace_stRGB)           ||
3968             (pRenderTarget->ColorSpace == CSpace_sRGB))
3969         {
3970             b2PassesCSCNeeded = (pRenderData->bHdr3DLut || pSrc->p3DLutParams) ? false : true;
3971         }
3972     }
3973 
3974     // VEBOX support input format
3975     bFormatSupported       = pVeboxState->IsFormatSupported(pSrc);
3976     // Platform support 2 passes CSC
3977     bPlatformSupported     = Is2PassesCscPlatformSupported();
3978 
3979     bRet = bFormatSupported && bPlatformSupported && b2PassesCSCNeeded;
3980 
3981 finish:
3982     return bRet;
3983 }
3984 
3985 //!
3986 //! \brief    copy Report data about features
3987 //! \details  copy Report data from this render
3988 //! \param    [out] pReporting
3989 //!           pointer to the Report data to copy data to
3990 //!
CopyFeatureReporting(VphalFeatureReport * pReporting)3991 void VPHAL_VEBOX_STATE::CopyFeatureReporting(VphalFeatureReport* pReporting)
3992 {
3993     pReporting->GetFeatures().iecp                  = m_reporting->GetFeatures().iecp;
3994     pReporting->GetFeatures().denoise               = m_reporting->GetFeatures().denoise;
3995     pReporting->GetFeatures().deinterlaceMode       = m_reporting->GetFeatures().deinterlaceMode;
3996     pReporting->GetFeatures().outputPipeMode        = m_reporting->GetFeatures().outputPipeMode;
3997     pReporting->GetFeatures().vpMMCInUse            = bEnableMMC;
3998     pReporting->GetFeatures().veFeatureInUse        = m_reporting->GetFeatures().veFeatureInUse;
3999 }
4000 
4001 //!
4002 //! \brief    copy Report data about resources
4003 //! \details  copy Report data from this render
4004 //! \param    [out] pReporting
4005 //!           pointer to the Report data to copy data to
4006 //!
CopyResourceReporting(VphalFeatureReport * pReporting)4007 void VPHAL_VEBOX_STATE::CopyResourceReporting(VphalFeatureReport* pReporting)
4008 {
4009     // Report Vebox intermediate surface
4010     pReporting->GetFeatures().ffdiCompressible   = m_reporting->GetFeatures().ffdiCompressible;
4011     pReporting->GetFeatures().ffdiCompressMode   = m_reporting->GetFeatures().ffdiCompressMode;
4012     pReporting->GetFeatures().ffdnCompressible   = m_reporting->GetFeatures().ffdnCompressible;
4013     pReporting->GetFeatures().ffdnCompressMode   = m_reporting->GetFeatures().ffdnCompressMode;
4014     pReporting->GetFeatures().stmmCompressible   = m_reporting->GetFeatures().stmmCompressible;
4015     pReporting->GetFeatures().stmmCompressMode   = m_reporting->GetFeatures().stmmCompressMode;
4016     pReporting->GetFeatures().scalerCompressible = m_reporting->GetFeatures().scalerCompressible;
4017     pReporting->GetFeatures().scalerCompressMode = m_reporting->GetFeatures().scalerCompressMode;
4018     pReporting->GetFeatures().diScdMode          = m_reporting->GetFeatures().diScdMode;
4019 }
4020 
4021 //!
4022 //! \brief    copy Report data
4023 //! \details  copy Report data from this render
4024 //! \param    [out] pReporting
4025 //!           pointer to the Report data to copy data to
4026 //!
CopyReporting(VphalFeatureReport * pReporting)4027 void VPHAL_VEBOX_STATE::CopyReporting(VphalFeatureReport* pReporting)
4028 {
4029     VPHAL_RENDER_ASSERT(pReporting);
4030 
4031     CopyFeatureReporting(pReporting);
4032     CopyResourceReporting(pReporting);
4033 }
4034 
4035 //!
4036 //! \brief    Allocate sfc temp surface for Vebox output
4037 //! \details  Allocate sfc temp surface for Vebox output
4038 //! \param    VphalRenderer* pRenderer
4039 //!           [in,out] VPHAL renderer pointer
4040 //! \param    PCVPHAL_RENDER_PARAMS pcRenderParams
4041 //!           [in] Const pointer to VPHAL render parameter
4042 //! \param    PVPHAL_VEBOX_RENDER_DATA pRenderData
4043 //!           [in] pointer to VPHAL VEBOX render parameter
4044 //! \param    PVPHAL_SURFACE pInSurface
4045 //!           [in] Pointer to input surface
4046 //! \param    PVPHAL_SURFACE pOutSurface
4047 //!           [in] Pointer to output surface
4048 //! \return   MOS_STATUS
4049 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4050 //!
AllocateSfcTempSurfaces(VphalRenderer * pRenderer,PCVPHAL_RENDER_PARAMS pcRenderParams,PVPHAL_VEBOX_RENDER_DATA pRenderData,PVPHAL_SURFACE pInSurface,PVPHAL_SURFACE pOutSurface)4051 MOS_STATUS VPHAL_VEBOX_STATE::AllocateSfcTempSurfaces(
4052     VphalRenderer                  *pRenderer,
4053     PCVPHAL_RENDER_PARAMS           pcRenderParams,
4054     PVPHAL_VEBOX_RENDER_DATA        pRenderData,
4055     PVPHAL_SURFACE                  pInSurface,
4056     PVPHAL_SURFACE                  pOutSurface)
4057 {
4058     MOS_STATUS               eStatus;
4059     PMOS_INTERFACE           pOsInterface;
4060     PVPHAL_VEBOX_STATE       pVeboxState;
4061     PVPHAL_SURFACE           pInSurfaceExt;
4062     PVPHAL_SURFACE           pOutSurfaceExt;
4063     PVPHAL_SURFACE           pSfcTempSurface;
4064     bool                     bAllocated;
4065     MOS_FORMAT               surfaceFormat;
4066     uint32_t                 dwSurfaceWidth;
4067     uint32_t                 dwSurfaceHeight;
4068 
4069     VPHAL_RENDER_CHK_NULL(pInSurface);
4070     VPHAL_RENDER_CHK_NULL(pOutSurface);
4071     VPHAL_RENDER_CHK_NULL(pRenderer);
4072     VPHAL_RENDER_CHK_NULL(pcRenderParams);
4073     VPHAL_RENDER_CHK_NULL(pRenderData);
4074 
4075     eStatus                 = MOS_STATUS_SUCCESS;
4076     dwSurfaceWidth          = pOutSurface->dwWidth;
4077     dwSurfaceHeight         = pOutSurface->dwHeight;
4078     surfaceFormat           = pInSurface->Format;
4079 
4080     eStatus                 = MOS_STATUS_SUCCESS;
4081     pVeboxState             = (PVPHAL_VEBOX_STATE)pRenderer->pRender[VPHAL_RENDER_ID_VEBOX + pRenderer->uiCurrentChannel];
4082     pOsInterface            = pRenderer->GetOsInterface();
4083     pSfcTempSurface         = pVeboxState->m_sfcTempSurface;
4084 
4085     VPHAL_RENDER_CHK_NULL(pSfcTempSurface);
4086 
4087     // Copy rect sizes so that if input surface state needs to adjust,
4088     // output surface can be adjustted also.
4089     pSfcTempSurface->rcSrc = pOutSurface->rcSrc;
4090     pSfcTempSurface->rcDst = pOutSurface->rcDst;
4091 
4092     // Sfc intermediate surface should be Y tile for best performance meanwhile enable MMC.
4093     VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface(
4094         pOsInterface,
4095         pSfcTempSurface,
4096         "VeboxSfcTempSurface",
4097         surfaceFormat,
4098         MOS_GFXRES_2D,
4099         MOS_TILE_Y,
4100         dwSurfaceWidth,
4101         dwSurfaceHeight,
4102         true,
4103         MOS_MMC_MC,
4104         &bAllocated));
4105 
4106     // Copy max src rect
4107     pSfcTempSurface->rcMaxSrc      = pOutSurface->rcMaxSrc;
4108     pSfcTempSurface->iPalette      = pOutSurface->iPalette;
4109     pSfcTempSurface->SampleType    = pOutSurface->SampleType;
4110     pSfcTempSurface->ColorSpace    = pInSurface->ColorSpace;
4111     pSfcTempSurface->Format        = surfaceFormat;
4112     pSfcTempSurface->SurfType      = pOutSurface->SurfType;
4113     pSfcTempSurface->FrameID       = pOutSurface->FrameID;
4114     pSfcTempSurface->ScalingMode   = pOutSurface->ScalingMode;
4115     pSfcTempSurface->ChromaSiting  = pOutSurface->ChromaSiting;
4116 
4117     if (pInSurface->pLumaKeyParams)
4118     {
4119         if (!pSfcTempSurface->pLumaKeyParams)
4120         {
4121             pSfcTempSurface->pLumaKeyParams = (PVPHAL_LUMAKEY_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_LUMAKEY_PARAMS));
4122             VPHAL_RENDER_CHK_NULL(pSfcTempSurface->pLumaKeyParams);
4123         }
4124 
4125         MOS_SecureMemcpy(pSfcTempSurface->pLumaKeyParams, sizeof(VPHAL_LUMAKEY_PARAMS),
4126             pInSurface->pLumaKeyParams, sizeof(VPHAL_LUMAKEY_PARAMS));
4127     }
4128     else
4129     {
4130         MOS_FreeMemory(pSfcTempSurface->pLumaKeyParams);
4131         pSfcTempSurface->pLumaKeyParams = nullptr;
4132     }
4133 
4134     if (pInSurface->pBlendingParams)
4135     {
4136         if (!pSfcTempSurface->pBlendingParams)
4137         {
4138             pSfcTempSurface->pBlendingParams = (PVPHAL_BLENDING_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_BLENDING_PARAMS));
4139             VPHAL_RENDER_CHK_NULL(pSfcTempSurface->pBlendingParams);
4140         }
4141 
4142         MOS_SecureMemcpy(pSfcTempSurface->pBlendingParams, sizeof(VPHAL_BLENDING_PARAMS),
4143             pInSurface->pBlendingParams, sizeof(VPHAL_BLENDING_PARAMS));
4144     }
4145     else
4146     {
4147         MOS_FreeMemory(pSfcTempSurface->pBlendingParams);
4148         pSfcTempSurface->pBlendingParams = nullptr;
4149     }
4150 
4151 finish:
4152     return eStatus;
4153 }
4154 
AllocateSfc2ndTempSurfaces(VphalRenderer * pRenderer,PCVPHAL_RENDER_PARAMS pcRenderParams,PVPHAL_VEBOX_RENDER_DATA pRenderData,PVPHAL_SURFACE pInSurface,PVPHAL_SURFACE pOutSurface)4155 MOS_STATUS VPHAL_VEBOX_STATE::AllocateSfc2ndTempSurfaces(
4156     VphalRenderer                  *pRenderer,
4157     PCVPHAL_RENDER_PARAMS           pcRenderParams,
4158     PVPHAL_VEBOX_RENDER_DATA        pRenderData,
4159     PVPHAL_SURFACE                  pInSurface,
4160     PVPHAL_SURFACE                  pOutSurface)
4161 {
4162     MOS_STATUS               eStatus;
4163     PMOS_INTERFACE           pOsInterface;
4164     PVPHAL_VEBOX_STATE       pVeboxState;
4165     PVPHAL_SURFACE           pInSurfaceExt;
4166     PVPHAL_SURFACE           pOutSurfaceExt;
4167     PVPHAL_SURFACE           pSfcTempSurface;
4168     bool                     bAllocated;
4169     MOS_FORMAT               surfaceFormat;
4170     uint32_t                 dwSurfaceWidth;
4171     uint32_t                 dwSurfaceHeight;
4172 
4173     VPHAL_RENDER_CHK_NULL(pInSurface);
4174     VPHAL_RENDER_CHK_NULL(pOutSurface);
4175     VPHAL_RENDER_CHK_NULL(pRenderer);
4176     VPHAL_RENDER_CHK_NULL(pcRenderParams);
4177     VPHAL_RENDER_CHK_NULL(pRenderData);
4178 
4179     eStatus                 = MOS_STATUS_SUCCESS;
4180     dwSurfaceWidth          = pOutSurface->dwWidth;
4181     dwSurfaceHeight         = pOutSurface->dwHeight;
4182     surfaceFormat           = pInSurface->Format;
4183 
4184     eStatus                 = MOS_STATUS_SUCCESS;
4185     pVeboxState             = (PVPHAL_VEBOX_STATE)pRenderer->pRender[VPHAL_RENDER_ID_VEBOX + pRenderer->uiCurrentChannel];
4186     pOsInterface            = pRenderer->GetOsInterface();
4187     pSfcTempSurface         = pVeboxState->m_sfc2ndTempSurface;
4188 
4189     VPHAL_RENDER_CHK_NULL(pSfcTempSurface);
4190 
4191     // Copy rect sizes so that if input surface state needs to adjust,
4192     // output surface can be adjustted also.
4193     pSfcTempSurface->rcSrc = pOutSurface->rcSrc;
4194     pSfcTempSurface->rcDst = pOutSurface->rcDst;
4195 
4196     // Sfc intermediate surface should be Y tile for best performance meanwhile enable MMC.
4197     VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface(
4198         pOsInterface,
4199         pSfcTempSurface,
4200         "VeboxSfcTempSurface",
4201         surfaceFormat,
4202         MOS_GFXRES_2D,
4203         MOS_TILE_Y,
4204         dwSurfaceWidth,
4205         dwSurfaceHeight,
4206         true,
4207         MOS_MMC_MC,
4208         &bAllocated));
4209 
4210     // Copy max src rect
4211     pSfcTempSurface->rcMaxSrc      = pOutSurface->rcMaxSrc;
4212     pSfcTempSurface->iPalette      = pOutSurface->iPalette;
4213     pSfcTempSurface->SampleType    = pOutSurface->SampleType;
4214     pSfcTempSurface->ColorSpace    = pInSurface->ColorSpace;
4215     pSfcTempSurface->Format        = surfaceFormat;
4216     pSfcTempSurface->SurfType      = pOutSurface->SurfType;
4217     pSfcTempSurface->FrameID       = pOutSurface->FrameID;
4218 
4219     if (pInSurface->pLumaKeyParams)
4220     {
4221         if (!pSfcTempSurface->pLumaKeyParams)
4222         {
4223             pSfcTempSurface->pLumaKeyParams = (PVPHAL_LUMAKEY_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_LUMAKEY_PARAMS));
4224             VPHAL_RENDER_CHK_NULL(pSfcTempSurface->pLumaKeyParams);
4225         }
4226 
4227         MOS_SecureMemcpy(pSfcTempSurface->pLumaKeyParams, sizeof(VPHAL_LUMAKEY_PARAMS),
4228             pInSurface->pLumaKeyParams, sizeof(VPHAL_LUMAKEY_PARAMS));
4229     }
4230     else
4231     {
4232         MOS_FreeMemory(pSfcTempSurface->pLumaKeyParams);
4233         pSfcTempSurface->pLumaKeyParams = nullptr;
4234     }
4235 
4236     if (pInSurface->pBlendingParams)
4237     {
4238         if (!pSfcTempSurface->pBlendingParams)
4239         {
4240             pSfcTempSurface->pBlendingParams = (PVPHAL_BLENDING_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_BLENDING_PARAMS));
4241             VPHAL_RENDER_CHK_NULL(pSfcTempSurface->pBlendingParams);
4242         }
4243 
4244         MOS_SecureMemcpy(pSfcTempSurface->pBlendingParams, sizeof(VPHAL_BLENDING_PARAMS),
4245             pInSurface->pBlendingParams, sizeof(VPHAL_BLENDING_PARAMS));
4246     }
4247     else
4248     {
4249         MOS_FreeMemory(pSfcTempSurface->pBlendingParams);
4250         pSfcTempSurface->pBlendingParams = nullptr;
4251     }
4252 
4253 finish:
4254     return eStatus;
4255 }
4256 
DestorySfcTempSurface()4257 void VPHAL_VEBOX_STATE::DestorySfcTempSurface()
4258 {
4259     if (m_sfcTempSurface)
4260     {
4261         m_pOsInterface->pfnFreeResource(
4262             m_pOsInterface,
4263             &m_sfcTempSurface->OsResource);
4264         MOS_FreeMemAndSetNull(m_sfcTempSurface->pBlendingParams);
4265         MOS_FreeMemAndSetNull(m_sfcTempSurface->pLumaKeyParams);
4266         MOS_Delete(m_sfcTempSurface);
4267         m_sfcTempSurface = nullptr;
4268     }
4269 
4270     // Free SFC temp surface
4271     if (m_sfc2ndTempSurface)
4272     {
4273         m_pOsInterface->pfnFreeResource(
4274             m_pOsInterface,
4275             &m_sfc2ndTempSurface->OsResource);
4276         MOS_FreeMemAndSetNull(m_sfc2ndTempSurface->pBlendingParams);
4277         MOS_FreeMemAndSetNull(m_sfc2ndTempSurface->pLumaKeyParams);
4278         MOS_Delete(m_sfc2ndTempSurface);
4279         m_sfc2ndTempSurface = nullptr;
4280     }
4281 }
4282 
VpHal_VeboxAllocateTempSurfaces(VphalRenderer * pRenderer,PCVPHAL_RENDER_PARAMS pcRenderParams,PVPHAL_VEBOX_RENDER_DATA pRenderData,PVPHAL_SURFACE pInSurface,PVPHAL_SURFACE pOutSurface,PVPHAL_SURFACE pAllocatedSurface)4283 MOS_STATUS VpHal_VeboxAllocateTempSurfaces(
4284     VphalRenderer                   *pRenderer,
4285     PCVPHAL_RENDER_PARAMS           pcRenderParams,
4286     PVPHAL_VEBOX_RENDER_DATA        pRenderData,
4287     PVPHAL_SURFACE                  pInSurface,
4288     PVPHAL_SURFACE                  pOutSurface,
4289     PVPHAL_SURFACE                  pAllocatedSurface)
4290 {
4291     MOS_STATUS               eStatus;
4292     PMOS_INTERFACE           pOsInterface        = nullptr;
4293     PVPHAL_VEBOX_STATE       pVeboxState         = nullptr;
4294     bool                     bAllocated;
4295     VPHAL_CSPACE             surfaceColorSpace;
4296     MOS_FORMAT               surfaceFormat;
4297     uint32_t                 dwSurfaceWidth;
4298     uint32_t                 dwSurfaceHeight;
4299 
4300     VPHAL_RENDER_CHK_NULL(pInSurface);
4301     VPHAL_RENDER_CHK_NULL(pOutSurface);
4302     VPHAL_RENDER_CHK_NULL(pRenderer);
4303     VPHAL_RENDER_CHK_NULL(pcRenderParams);
4304     VPHAL_RENDER_CHK_NULL(pRenderData);
4305 
4306     pOsInterface = pRenderer->GetOsInterface();
4307     VPHAL_RENDER_CHK_NULL(pOsInterface);
4308 
4309     eStatus             = MOS_STATUS_SUCCESS;
4310     dwSurfaceWidth      = pInSurface->dwWidth;
4311     dwSurfaceHeight     = pInSurface->dwHeight;
4312     surfaceFormat       = pOutSurface->Format;
4313     surfaceColorSpace   = pOutSurface->ColorSpace;
4314 
4315     if (IS_YUV_FORMAT(pOutSurface->Format) || IS_ALPHA_YUV_FORMAT(pOutSurface->Format))
4316     {
4317         surfaceFormat       = Format_R10G10B10A2;
4318         surfaceColorSpace   = (IS_COLOR_SPACE_BT2020(pOutSurface->ColorSpace)) ? CSpace_BT2020_RGB : CSpace_sRGB;
4319     }
4320 
4321     // Hdr intermediate surface should be Y tile for best performance
4322     VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface(
4323         pOsInterface,
4324         pAllocatedSurface,
4325         "VeboxHdrOutputSurface",
4326         surfaceFormat,
4327         MOS_GFXRES_2D,
4328         MOS_TILE_Y,
4329         dwSurfaceWidth,
4330         dwSurfaceHeight,
4331         false,
4332         MOS_MMC_DISABLED,
4333         &bAllocated));
4334 
4335     VPHAL_RENDER_CHK_NULL(pAllocatedSurface);
4336 
4337     // Copy rect sizes so that if input surface state needs to adjust,
4338     // output surface can be adjusted also.
4339     pAllocatedSurface->rcSrc            = pInSurface->rcSrc;
4340     pAllocatedSurface->rcDst            = pInSurface->rcSrc;
4341     pAllocatedSurface->rcMaxSrc         = pInSurface->rcSrc;
4342     pAllocatedSurface->Rotation         = pInSurface->Rotation;
4343     pAllocatedSurface->SampleType       = pInSurface->SampleType;
4344     pAllocatedSurface->ColorSpace       = surfaceColorSpace;
4345     pAllocatedSurface->Format           = surfaceFormat;
4346     pAllocatedSurface->SurfType         = pInSurface->SurfType;
4347     pAllocatedSurface->SampleType       = pInSurface->SampleType;
4348     pAllocatedSurface->ScalingMode      = pInSurface->ScalingMode;
4349     pAllocatedSurface->bIEF             = pInSurface->bIEF;
4350     pAllocatedSurface->FrameID          = pInSurface->FrameID;
4351 
4352     if (pInSurface->pBlendingParams)
4353     {
4354         if (!pAllocatedSurface->pBlendingParams)
4355         {
4356             pAllocatedSurface->pBlendingParams = (PVPHAL_BLENDING_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_BLENDING_PARAMS));
4357             VPHAL_RENDER_CHK_NULL(pAllocatedSurface->pBlendingParams);
4358         }
4359 
4360         MOS_SecureMemcpy(pAllocatedSurface->pBlendingParams, sizeof(VPHAL_BLENDING_PARAMS),
4361             pInSurface->pBlendingParams, sizeof(VPHAL_BLENDING_PARAMS));
4362     }
4363     else
4364     {
4365         MOS_FreeMemory(pAllocatedSurface->pBlendingParams);
4366         pAllocatedSurface->pBlendingParams = nullptr;
4367     }
4368 
4369     if (pInSurface->pHDRParams)
4370     {
4371         if (!pAllocatedSurface->pHDRParams)
4372         {
4373             pAllocatedSurface->pHDRParams = (PVPHAL_HDR_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_HDR_PARAMS));
4374             VPHAL_RENDER_CHK_NULL(pAllocatedSurface->pHDRParams);
4375         }
4376         if (pOutSurface->pHDRParams)
4377         {
4378             MOS_SecureMemcpy(pAllocatedSurface->pHDRParams, sizeof(VPHAL_HDR_PARAMS),
4379                 pOutSurface->pHDRParams, sizeof(VPHAL_HDR_PARAMS));
4380         }
4381     }
4382     else
4383     {
4384         MOS_FreeMemory(pAllocatedSurface->pHDRParams);
4385         pAllocatedSurface->pHDRParams = nullptr;
4386     }
4387 
4388 finish:
4389     return eStatus;
4390 }
4391 
4392 //!
4393 //! \brief    Perform Rendering in VEBOX
4394 //! \details  Check whether VEBOX Rendering is enabled. When it's enabled, perform VEBOX Rendering
4395 //!           on the input surface and get the output surface
4396 //! \param    [in,out] pRenderer
4397 //!           VPHAL renderer pointer
4398 //! \param    [in] pcRenderParams
4399 //!           Const pointer to VPHAL render parameter
4400 //! \param    [in,out] pRenderPassData
4401 //!           Pointer to RenderpassData structure
4402 //! \return   MOS_STATUS
4403 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4404 //!
VpHal_RndrRenderVebox(VphalRenderer * pRenderer,PCVPHAL_RENDER_PARAMS pcRenderParams,RenderpassData * pRenderPassData)4405 MOS_STATUS VpHal_RndrRenderVebox(
4406     VphalRenderer           *pRenderer,
4407     PCVPHAL_RENDER_PARAMS   pcRenderParams,
4408     RenderpassData          *pRenderPassData)
4409 {
4410     MOS_STATUS               eStatus;
4411     PMOS_INTERFACE           pOsInterface   = nullptr;
4412     RenderState              *pRenderState  = nullptr;
4413     VphalFeatureReport*      pReport        = nullptr;
4414     PVPHAL_SURFACE           pOutSurface    = nullptr;
4415     PVPHAL_SURFACE           pInSurface     = nullptr;
4416     RECT                     rcTempOut      = {};
4417     RECT                     rcTemp         = {};
4418     RECT                     rcTempIn       = {};
4419     PVPHAL_VEBOX_STATE       pVeboxState    = nullptr;
4420     PVPHAL_VEBOX_RENDER_DATA pRenderData    = nullptr;
4421     bool                     bVeboxOutput   = false;
4422 
4423     //------------------------------------------------------
4424     VPHAL_RENDER_ASSERT(pRenderer);
4425     VPHAL_RENDER_ASSERT(pcRenderParams);
4426     VPHAL_RENDER_CHK_NULL(pRenderer->GetOsInterface());
4427     //------------------------------------------------------
4428 
4429     eStatus                 = MOS_STATUS_SUCCESS;
4430     pOsInterface            = pRenderer->GetOsInterface();
4431     pReport                 = pRenderer->GetReport();
4432     pRenderState            = pRenderer->pRender[VPHAL_RENDER_ID_VEBOX + pRenderer->uiCurrentChannel];
4433     pOutSurface             = pRenderPassData->GetTempOutputSurface();
4434     pVeboxState             = (PVPHAL_VEBOX_STATE)pRenderState;
4435     pRenderData             = pVeboxState->GetLastExecRenderData();
4436     pInSurface              = (PVPHAL_SURFACE)pRenderPassData->pSrcSurface;
4437     bVeboxOutput            = false;
4438 
4439     pRenderPassData->bOutputGenerated  = false;
4440 
4441     VPHAL_RENDER_CHK_NULL(pRenderState);
4442     VPHAL_RENDER_CHK_NULL(pVeboxState);
4443     VPHAL_RENDER_CHK_NULL(pVeboxState->m_sfcTempSurface);
4444     VPHAL_RENDER_CHK_NULL(pVeboxState->m_sfc2ndTempSurface);
4445     VPHAL_RENDER_ASSERT(pRenderState->GetRenderHalInterface());
4446 
4447     pRenderPassData->bCompNeeded  = true;
4448 
4449     if (!pRenderState->GetRenderDisableFlag())
4450     {
4451         MOS_ZeroMemory(pOutSurface, sizeof(VPHAL_SURFACE));
4452 
4453         pRenderPassData->bCompNeeded = false;
4454 
4455         // Check if DNDI Render can be applied
4456         if (!pRenderState->IsNeeded(
4457             pcRenderParams,
4458             pRenderPassData))
4459         {
4460             goto finish;
4461         }
4462 
4463         VPHAL_RENDER_CHK_NULL(pRenderData);
4464 
4465         if (pRenderData->b2PassesCSC)
4466         {   // First step of two pass CSC in vebox for Linux BT.2020 -> BT.601/709/RGB
4467 
4468             if (!pRenderPassData->bCompNeeded)
4469             {   //the flage is set due to VeboxIs2PassesCSCNeeded() in GetOutputPipe()
4470                 VPHAL_RENDER_ASSERTMESSAGE(" Failed to run two pass CSC in render ");
4471                 VPHAL_RENDER_CHK_STATUS(MOS_STATUS_INVALID_PARAMETER)
4472             }
4473 
4474             SET_VPHAL_OUTPUT_PIPE(pRenderData, VPHAL_OUTPUT_PIPE_MODE_VEBOX);
4475             pRenderData->pRenderTarget = &pVeboxState->m_BT2020CSCTempSurface;
4476             //set input/output for vebox
4477             pRenderPassData->pSrcSurface = pInSurface;
4478             pRenderPassData->pOutSurface = &pVeboxState->m_BT2020CSCTempSurface;
4479 
4480             VPHAL_RENDER_CHK_STATUS(pVeboxState->Render(
4481                 pcRenderParams,
4482                 pRenderPassData));
4483 
4484             pRenderPassData->b2CSCNeeded = true;
4485 
4486             pRenderPassData->bOutputGenerated = true;
4487 
4488             pRenderState->CopyReporting(pReport);
4489             goto finish;
4490         }
4491 
4492         if (pRenderPassData->bCompNeeded == false)
4493         {
4494             // Render Target is the output surface
4495             pOutSurface = pcRenderParams->pTarget[0];
4496         }
4497 
4498         rcTemp = pcRenderParams->pTarget[0]->rcDst;
4499         rcTempIn = pcRenderParams->pSrc[0]->rcDst;
4500         if (pVeboxState->m_sfcPipeState && pVeboxState->m_sfcPipeState->m_bSFC2Pass)
4501         {
4502             if (0 == pRenderData->fScaleX || 0 == pRenderData->fScaleY)
4503             {
4504                 VPHAL_RENDER_ASSERTMESSAGE("Invalid scaling ratio in pRenderData during SFC 2 pass scaling!");
4505             }
4506 
4507             //SFC 2 pass, here is the output surface of first pass.
4508             float                    TempfScaleX = 1.0;
4509             float                    TempfScaleY = 1.0;
4510             if ((pRenderData->fScaleX >= 0.0625F) && (pRenderData->fScaleX < 0.125F))
4511             {
4512                 if (pVeboxState->m_sfcPipeState->m_bSFC2PassPerfMode)
4513                 {
4514                     TempfScaleX = 0.125F;
4515                 }
4516                 else
4517                 {
4518                     TempfScaleX = 0.5F;
4519                 }
4520             }
4521             else if ((pRenderData->fScaleX > 8.0F) && (pRenderData->fScaleX <= 16.0F))
4522             {
4523                 TempfScaleX = 2.0F;
4524             }
4525 
4526             if ((pRenderData->fScaleY >= 0.0625F) && (pRenderData->fScaleY < 0.125F))
4527             {
4528                 if (pVeboxState->m_sfcPipeState->m_bSFC2PassPerfMode)
4529                 {
4530                     TempfScaleY = 0.125F;
4531                 }
4532                 else
4533                 {
4534                     TempfScaleY = 0.5F;
4535                 }
4536             }
4537             else if ((pRenderData->fScaleY > 8.0F) && (pRenderData->fScaleY <= 16.0F))
4538             {
4539                 TempfScaleY = 2.0F;
4540             }
4541 
4542             //May Lose Precision after 0.x
4543             if (pInSurface->Rotation == VPHAL_ROTATION_IDENTITY ||
4544                 pInSurface->Rotation == VPHAL_ROTATION_180      ||
4545                 pInSurface->Rotation == VPHAL_MIRROR_HORIZONTAL ||
4546                 pInSurface->Rotation == VPHAL_MIRROR_VERTICAL)
4547             {
4548                 if ((TempfScaleX == 1.0F) && pVeboxState->m_sfcPipeState->m_bSFC2PassPerfMode)
4549                 {
4550                     rcTempOut.right = pInSurface->rcDst.right - pInSurface->rcDst.left;
4551                 }
4552                 else
4553                 {
4554                     rcTempOut.right  = (long)((pInSurface->rcSrc.right - pInSurface->rcSrc.left) * TempfScaleX);
4555                 }
4556                 if ((TempfScaleY == 1.0F) && pVeboxState->m_sfcPipeState->m_bSFC2PassPerfMode)
4557                 {
4558                     rcTempOut.bottom = pInSurface->rcDst.bottom - pInSurface->rcDst.top;
4559                 }
4560                 else
4561                 {
4562                     rcTempOut.bottom = (long)((pInSurface->rcSrc.bottom - pInSurface->rcSrc.top) * TempfScaleY);
4563                 }
4564             }
4565             else
4566             {
4567                 if ((TempfScaleX == 1.0F) && pVeboxState->m_sfcPipeState->m_bSFC2PassPerfMode)
4568                 {
4569                     rcTempOut.bottom = pInSurface->rcDst.right - pInSurface->rcDst.left;
4570                 }
4571                 else
4572                 {
4573                     rcTempOut.bottom = (long)((pInSurface->rcSrc.right - pInSurface->rcSrc.left) * TempfScaleX);
4574                 }
4575                 if ((TempfScaleY == 1.0F) && pVeboxState->m_sfcPipeState->m_bSFC2PassPerfMode)
4576                 {
4577                     rcTempOut.right = pInSurface->rcDst.bottom - pInSurface->rcDst.top;
4578                 }
4579                 else
4580                 {
4581                     rcTempOut.right = (long)((pInSurface->rcSrc.bottom - pInSurface->rcSrc.top) * TempfScaleY);
4582                 }
4583             }
4584 
4585             VPHAL_RENDER_NORMALMESSAGE("x scaling ratio %f, y %f, 1st pass sfc scaling ratio %f",
4586               pRenderData->fScaleX, pRenderData->fScaleY, TempfScaleX);
4587         }
4588 
4589         if (pVeboxState->m_sfcPipeState && (pRenderPassData->bSFCScalingOnly || pVeboxState->m_sfcPipeState->m_bSFC2Pass))
4590         {
4591             if (pRenderPassData->bSFCScalingOnly && !pVeboxState->m_sfcPipeState->m_bSFC2Pass)
4592             {
4593                 rcTempOut.right   = (long)((pInSurface->rcDst.right - pInSurface->rcDst.left));
4594                 rcTempOut.bottom  = (long)((pInSurface->rcDst.bottom - pInSurface->rcDst.top));
4595             }
4596 
4597             pOutSurface->rcDst    = rcTempOut;
4598             pOutSurface->rcSrc    = rcTempOut;
4599             pOutSurface->dwWidth  = rcTempOut.right;
4600             pOutSurface->dwHeight = rcTempOut.bottom;
4601             pInSurface->rcDst     = rcTempOut;
4602 
4603             VPHAL_RENDER_CHK_STATUS(pVeboxState->AllocateSfcTempSurfaces(pRenderer, pcRenderParams, pRenderData, pInSurface, pOutSurface));
4604             pOutSurface = pVeboxState->m_sfcTempSurface;
4605             // Reset rendering flags for SFC since output surface changed
4606             pVeboxState->m_sfcPipeState->SetRenderingFlags(
4607                 pcRenderParams->pColorFillParams,
4608                 pcRenderParams->pCompAlpha,
4609                 pInSurface,
4610                 pOutSurface,
4611                 pRenderData);
4612         }
4613 
4614         pRenderPassData->pOutSurface    = pOutSurface;
4615 
4616         bVeboxOutput = IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData);
4617         if (pRenderData->bHdr3DLut)
4618         {
4619             PVPHAL_SURFACE pTargetSurface = (PVPHAL_SURFACE)pcRenderParams->pTarget[0];
4620             // If VEBOX output, write the output to render target
4621             if (bVeboxOutput)
4622             {
4623                 pRenderData->pRenderTarget       = pTargetSurface;
4624                 pRenderPassData->pOutSurface     = pTargetSurface;
4625             }
4626             else
4627             {
4628                 VpHal_VeboxAllocateTempSurfaces(pRenderer, pcRenderParams, pRenderData, pcRenderParams->pSrc[0], pcRenderParams->pTarget[0], &pRenderer->IntermediateSurface);
4629                 SET_VPHAL_OUTPUT_PIPE(pRenderData, VPHAL_OUTPUT_PIPE_MODE_VEBOX);
4630                 SET_VEBOX_EXECUTION_MODE(pVeboxState->m_pVeboxExecState, VEBOX_EXEC_MODE_0);
4631                 pOutSurface                       = &pRenderer->IntermediateSurface;
4632                 pRenderData->pRenderTarget        = &pRenderer->IntermediateSurface;
4633                 // If VEBOX does not output directly, write the output to intermediate surface
4634                 pRenderPassData->pOutSurface      = pOutSurface;
4635             }
4636         }
4637 
4638         //Disable cache for output surface in vebox only condition
4639         if (IS_VPHAL_OUTPUT_PIPE_VEBOX(pRenderData))
4640         {
4641             MOS_HW_RESOURCE_DEF                 Usage;
4642             MEMORY_OBJECT_CONTROL_STATE         MemObjCtrl;
4643             VPHAL_SET_SURF_MEMOBJCTL(pVeboxState->DnDiSurfMemObjCtl.CurrentOutputSurfMemObjCtl, MOS_MP_RESOURCE_USAGE_DEFAULT);
4644         }
4645 
4646         VPHAL_RENDER_CHK_STATUS(pRenderState->Render(
4647                                                 pcRenderParams,
4648                                                 pRenderPassData))
4649 
4650         if (pVeboxState->m_sfcPipeState && (pRenderPassData->bSFCScalingOnly || pVeboxState->m_sfcPipeState->m_bSFC2Pass))
4651         {
4652             pInSurface = pVeboxState->m_sfcTempSurface;
4653             pInSurface->rcMaxSrc = pInSurface->rcSrc;
4654             pInSurface->rcDst    = rcTempIn;
4655             pInSurface->ScalingMode = pRenderPassData->pSrcSurface->ScalingMode;
4656 
4657             // recover the orignal rcDst for the second loop
4658             pcRenderParams->pTarget[0]->rcDst    = rcTemp;
4659             pcRenderParams->pTarget[0]->rcSrc    = rcTemp;
4660             pcRenderParams->pTarget[0]->dwWidth  = rcTemp.right;
4661             pcRenderParams->pTarget[0]->dwHeight = rcTemp.bottom;
4662 
4663             // Render Target is the output surface
4664             pOutSurface = pcRenderParams->pTarget[0];
4665             pRenderData->pRenderTarget = pOutSurface;
4666             pRenderPassData->pSrcSurface = pInSurface;
4667         }
4668 
4669         //SFC second pass
4670         if (pVeboxState->m_sfcPipeState && pVeboxState->m_sfcPipeState->m_bSFC2Pass)
4671         {
4672             // Second time vebox rending for scaling / colorfill/rotation on SFC, disable all other features
4673             pVeboxState->m_sfcPipeState->m_bSFC2Pass = false;
4674             pRenderData->bDenoise = false;
4675             pRenderData->bDeinterlace = false;
4676             pRenderData->bQueryVariance = false;
4677             pRenderData->bRefValid = false;
4678 
4679             VPHAL_RENDER_NORMALMESSAGE("2nd pass sfc scaling ratio x = %f, y = %f",
4680               (long)((pInSurface->rcDst.right - pInSurface->rcDst.left) / (pInSurface->rcSrc.right - pInSurface->rcSrc.left)),
4681               (long)((pInSurface->rcDst.bottom - pInSurface->rcDst.top) / (pInSurface->rcSrc.bottom - pInSurface->rcSrc.top)));
4682 
4683             if (pRenderPassData->bSFCScalingOnly)
4684             {// only the multi-layers use the SFC 2pass need the second sfc tempsurfaces.
4685                 VPHAL_RENDER_CHK_STATUS(pVeboxState->AllocateSfc2ndTempSurfaces(pRenderer, pcRenderParams, pRenderData, pInSurface, pOutSurface));
4686                 pRenderPassData->pOutSurface = pVeboxState->m_sfc2ndTempSurface;
4687                 // Reset rendering flags for SFC since output surface changed
4688                 pVeboxState->m_sfcPipeState->SetRenderingFlags(
4689                     pcRenderParams->pColorFillParams,
4690                     pcRenderParams->pCompAlpha,
4691                     pInSurface,
4692                     pRenderPassData->pOutSurface,
4693                     pRenderData);
4694             }
4695             else
4696             {   // reset the output surface as targetsurface.
4697                 pRenderPassData->pOutSurface = pOutSurface;
4698                 pInSurface->SurfType         = SURF_IN_PRIMARY;
4699                 pVeboxState->m_sfcPipeState->SetRenderingFlags(
4700                     pcRenderParams->pColorFillParams,
4701                     pcRenderParams->pCompAlpha,
4702                     pInSurface,
4703                     pRenderPassData->pOutSurface,
4704                     pRenderData);
4705             }
4706 
4707             VPHAL_RENDER_CHK_STATUS(pVeboxState->Render(
4708               pcRenderParams,
4709               pRenderPassData));
4710         }
4711         pRenderState->CopyReporting(pReport);
4712 
4713         if (pRenderPassData->bCompNeeded)
4714         {
4715             pRenderPassData->bOutputGenerated = true;
4716         }
4717 
4718         if (pRenderData->bHdr3DLut && !bVeboxOutput)
4719         {
4720             pRenderPassData->bOutputGenerated   = true;
4721             pRenderPassData->bCompNeeded        = true;
4722             if (pOutSurface && pcRenderParams->pSrc[0])
4723             {
4724                 pRenderPassData->pOutSurface->rcSrc      = pcRenderParams->pSrc[0]->rcSrc;
4725                 pRenderPassData->pOutSurface->rcDst      = pcRenderParams->pSrc[0]->rcDst;
4726                 pRenderPassData->pOutSurface->rcMaxSrc   = pcRenderParams->pSrc[0]->rcMaxSrc;
4727                 pRenderPassData->pOutSurface->iLayerID   = -1;
4728                 pRenderPassData->pOutSurface->iPalette   = -1;
4729             }
4730         }
4731     }
4732 
4733 finish:
4734     VPHAL_RENDER_NORMALMESSAGE("VPOutputPipe = %d, VEFeatureInUse = %d",
4735         pRenderer->GetReport()->GetFeatures().outputPipeMode, pRenderer->GetReport()->GetFeatures().veFeatureInUse);
4736 
4737     return eStatus;
4738 }
UpdateRenderGpuContext(MOS_GPU_CONTEXT renderGpuContext)4739 MOS_STATUS VPHAL_VEBOX_STATE::UpdateRenderGpuContext(
4740     MOS_GPU_CONTEXT renderGpuContext)
4741 {
4742     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4743     if (MOS_RCS_ENGINE_USED(renderGpuContext))
4744     {
4745         RenderGpuContext = renderGpuContext;
4746         VPHAL_RENDER_NORMALMESSAGE("RenderGpuContext turns to %d", renderGpuContext);
4747     }
4748     else
4749     {
4750         VPHAL_RENDER_ASSERTMESSAGE("Invalid Render GpuContext: %d! Update RenderGpuContext Failed", renderGpuContext);
4751     }
4752 
4753     return eStatus;
4754 }
4755 
VPHAL_VEBOX_STATE(PMOS_INTERFACE pOsInterface,PMHW_VEBOX_INTERFACE pVeboxInterface,PMHW_SFC_INTERFACE pSfcInterface,PRENDERHAL_INTERFACE pRenderHal,PVPHAL_VEBOX_EXEC_STATE pVeboxExecState,PVPHAL_RNDR_PERF_DATA pPerfData,const VPHAL_DNDI_CACHE_CNTL & dndiCacheCntl,MOS_STATUS * peStatus)4756 VPHAL_VEBOX_STATE::VPHAL_VEBOX_STATE(
4757     PMOS_INTERFACE                  pOsInterface,
4758     PMHW_VEBOX_INTERFACE            pVeboxInterface,
4759     PMHW_SFC_INTERFACE              pSfcInterface,
4760     PRENDERHAL_INTERFACE            pRenderHal,
4761     PVPHAL_VEBOX_EXEC_STATE         pVeboxExecState,
4762     PVPHAL_RNDR_PERF_DATA           pPerfData,
4763     const VPHAL_DNDI_CACHE_CNTL     &dndiCacheCntl,
4764     MOS_STATUS                      *peStatus) :
4765     RenderState(pOsInterface, pRenderHal, pPerfData, peStatus),
4766     m_pVeboxInterface(pVeboxInterface),
4767     m_pSfcInterface(pSfcInterface),
4768     m_currKernelId(baseKernelMaxNumID),
4769     m_pVeboxExecState(pVeboxExecState)
4770 {
4771     // External components
4772     m_IECP                  = nullptr;
4773     m_sfcPipeState          = nullptr;
4774     m_pKernelDllState       = nullptr;
4775     m_pLastExecRenderData   = nullptr;
4776     CscOutputCspace         = CSpace_Any;
4777     CscInputCspace          = CSpace_Any;
4778     m_BT2020CSCTempSurface  = {};
4779 
4780     int i;
4781     for (i = 0; i < 9; i++)
4782     {
4783         fCscCoeff[i] = 0.0f;
4784     }
4785 
4786     for (i = 0; i < 3; i++)
4787     {
4788         fCscInOffset[i] = 0.0f;
4789         fCscOutOffset[i] = 0.0f;
4790     }
4791 
4792     // Front End CSC
4793     fFeCscCoeff                = nullptr;
4794     fFeCscInOffset             = nullptr;
4795     fFeCscOutOffset            = nullptr;
4796 
4797     for (i = 0; i < 2; i++)
4798     {
4799         SearchFilter[i] = {};
4800     }
4801 
4802     // Threshold for discontinuity check
4803     iSameSampleThreshold = 0;
4804 
4805     // Resources
4806     m_currentSurface            = nullptr;           //!< Current frame
4807     m_previousSurface           = nullptr;           //!< Previous frame
4808     RenderHalCurrentSurface     = {};                //!< Current frame for MHW
4809     RenderHalPreviousSurface    = {};                //!< Previous frame for MHW
4810 
4811     for (i = 0; i < VPHAL_MAX_NUM_FFDI_SURFACES; i++)
4812     {
4813         FFDISurfaces[i] = nullptr;
4814     }
4815     VeboxRGBHistogram               = {};
4816     VeboxStatisticsSurface          = {};            //!< Statistics Surface for VEBOX
4817     RenderHalVeboxStatisticsSurface = {};            //!< Statistics Surface for VEBOX for MHW
4818 #if VEBOX_AUTO_DENOISE_SUPPORTED
4819     VeboxTempSurface                = {};            //!< Temp Surface for Vebox State update kernels
4820     VeboxSpatialAttributesConfigurationSurface = {}; //!< Spatial Attributes Configuration Surface for DN kernel Gen9+
4821     RenderHalVeboxSpatialAttributesConfigurationSurface = {}; //!< Spatial Attributes Configuration Surface for DN kernel Gen9+ for MHW
4822     VeboxHeapResource    = {};                       //!< Vebox Heap resource for DN kernel
4823     tmpResource          = {};                       //!< Temp resource for DN kernel
4824     RenderHalVeboxHeapResource = {};                 //!< Vebox Heap resource for DN kernel for MHW
4825     RenderHalTmpResource       = {};                 //!< Temp resource for DN kernel for MHW
4826 #endif
4827 
4828     // DNDI
4829     for (i = 0; i < VPHAL_NUM_FFDN_SURFACES; i++)
4830     {
4831         FFDNSurfaces[i] = nullptr;
4832     }
4833 
4834     for (i = 0; i < VPHAL_NUM_STMM_SURFACES; i++)
4835     {
4836         STMMSurfaces[i] = {};
4837     }
4838 
4839     // BNE system memory pointer
4840     pBNEData    = nullptr;                          //!< System memory for GNE calculating
4841     dwBNESize   = 0;                                //!< System memory size for BNE surface
4842 
4843     // Statistics
4844     dwVeboxPerBlockStatisticsWidth  = 0;            //!< Per block statistics width
4845     dwVeboxPerBlockStatisticsHeight = 0;            //!< Per block statistics height
4846 
4847     //!< Surface memory object control
4848     // Get cache settings
4849     DnDiSurfMemObjCtl = dndiCacheCntl;
4850 
4851     // Batch Buffers
4852     iBatchBufferCount = 0;                          //!< Number of batch buffers
4853     for (i = 0; i < VPHAL_DNDI_BUFFERS_MAX; i++)
4854     {
4855         BatchBuffer[i] = {};
4856         BufferParam[i] = {};
4857     }
4858 
4859     // Denoise output control
4860     iCurDNIndex = 0;                                //!< Current index of Denoise Output
4861 
4862     // DNDI
4863     iNumFFDISurfaces    = 0;                        //!< Actual number of FFDISurfaces. Is <= VPHAL_NUM_FFDI_SURFACES
4864     iCurStmmIndex       = 0;                        //!< Current index of Motion History Buffer
4865     dwGlobalNoiseLevel  = 0;                        //!< Global Noise Level
4866 
4867     // Chroma DN
4868     iCurHistIndex       = 0;                        //!< Current index of Chroma Denoise History Buffer
4869     dwGlobalNoiseLevelU = 0;                        //!< Global Noise Level for U
4870     dwGlobalNoiseLevelV = 0;                        //!< Global Noise Level for V
4871     bFirstFrame         = false;                    //!< First frame case for Chroma DN
4872 
4873     // timestamps for DI output control
4874     iCurFrameID = 0;                                //!< Current Frame ID
4875     iPrvFrameID = 0;                                //!< Previous Frame ID
4876 
4877     // for Pre-Processing
4878     bSameSamples    = false;                        //!< True for second DI
4879     iCallID         = 0;                            //!< Current render call ID;
4880     bDNEnabled      = false;                        //!< DN was enabled in the previous call
4881     bDIEnabled      = false;                        //!< DI was enabled in the previous call
4882 
4883     // Platform dependent states
4884     pKernelParamTable   = nullptr;                  //!< Kernel Parameter table
4885 
4886     // HW Params
4887     dwKernelUpdate      = 0;                        //!< Enable/Disable kernel update
4888 
4889     dwCompBypassMode    = 0;                        //!< Bypass Composition Optimization read from User feature keys
4890 
4891     // Debug parameters
4892     pKernelName                          = nullptr; //!< Kernel Used for current rendering
4893     bNullHwRenderDnDi                    = false;   //!< Null rendering for DnDi function
4894 
4895     bEnableMMC                           = false;   //!< Memory compression enbale flag - read from User feature keys
4896     bDisableTemporalDenoiseFilter        = false;   //!< Temporal denoise filter disable flag - read from User feature keys
4897     bDisableTemporalDenoiseFilterUserKey = false;   //!< Backup temporal denoise filter disable flag - read from User feature keys
4898 
4899     uiCurrentChannel                     = 0;
4900 
4901     RenderGpuContext = pOsInterface ? (pOsInterface->CurrentGpuContextOrdinal) : MOS_GPU_CONTEXT_RENDER;
4902 
4903     Vebox3DLookUpTables = { };
4904 
4905     m_hvsDenoiser         = nullptr;
4906     m_hvsKernelBinary     = nullptr;
4907     m_hvsKernelBinarySize = 0;
4908 
4909     bPhasedSubmission     = false;
4910 }
4911 
~VPHAL_VEBOX_STATE()4912 VPHAL_VEBOX_STATE::~VPHAL_VEBOX_STATE()
4913 {
4914     PRENDERHAL_INTERFACE pRenderHal;
4915     PMHW_BATCH_BUFFER    pBuffer;
4916     int32_t              i;
4917     PVPHAL_VEBOX_STATE                  pVeboxState = this;
4918 
4919     VPHAL_RENDER_ASSERT(pVeboxState);
4920 
4921     pRenderHal   = pVeboxState->m_pRenderHal;
4922 
4923     VPHAL_RENDER_ASSERT(pRenderHal);
4924 
4925     MOS_FreeMemAndSetNull(m_currentSurface);
4926     MOS_FreeMemAndSetNull(m_previousSurface);
4927 
4928     for (uint32_t i = 0; i < VPHAL_NUM_FFDN_SURFACES; i++)
4929     {
4930         MOS_FreeMemAndSetNull(FFDNSurfaces[i]);
4931     }
4932 
4933     for (uint32_t i = 0; i < VPHAL_MAX_NUM_FFDI_SURFACES; i++)
4934     {
4935         MOS_FreeMemAndSetNull(FFDISurfaces[i]);
4936     }
4937 
4938     // Destroy Batch Buffers
4939     for (i = 0; i < pVeboxState->iBatchBufferCount; i++)
4940     {
4941         pBuffer = &pVeboxState->BatchBuffer[i];
4942         pRenderHal->pfnFreeBB(pRenderHal, pBuffer);
4943     }
4944 
4945     if (m_pLastExecRenderData)
4946     {
4947         MOS_Delete(m_pLastExecRenderData);
4948         m_pLastExecRenderData = nullptr;
4949     }
4950 
4951     if (m_IECP)
4952     {
4953         MOS_Delete(m_IECP);
4954         m_IECP = nullptr;
4955     }
4956 
4957     // Destroy SFC state
4958     if (m_sfcPipeState)
4959     {
4960         MOS_Delete(m_sfcPipeState);
4961         m_sfcPipeState = nullptr;
4962     }
4963 
4964     // Free SFC temp surface
4965     DestorySfcTempSurface();
4966 
4967     MOS_Delete(m_hvsDenoiser);
4968 }
4969 
VeboxSetHVSDNParams(PVPHAL_SURFACE pSrcSurface)4970 MOS_STATUS VPHAL_VEBOX_STATE::VeboxSetHVSDNParams(
4971     PVPHAL_SURFACE pSrcSurface)
4972 {
4973     MOS_STATUS eStatus                                    = MOS_STATUS_UNKNOWN;
4974     PRENDERHAL_INTERFACE pRenderHal                       = nullptr;
4975     PVPHAL_VEBOX_STATE pVeboxState                        = this;
4976     PVPHAL_VEBOX_RENDER_DATA pRenderData                  = nullptr;
4977 
4978     pRenderHal   = pVeboxState->m_pRenderHal;
4979     pRenderData  = GetLastExecRenderData();
4980 
4981     VPHAL_RENDER_CHK_NULL_RETURN(pSrcSurface);
4982     VPHAL_RENDER_CHK_NULL_RETURN(pSrcSurface->pDenoiseParams);
4983     VPHAL_RENDER_CHK_NULL_RETURN(pRenderHal);
4984     VPHAL_RENDER_CHK_NULL_RETURN(pRenderData);
4985 
4986     if (nullptr == m_hvsDenoiser)
4987     {
4988         m_hvsDenoiser = MOS_New(VphalHVSDenoiser, pRenderHal);
4989         if (m_hvsDenoiser)
4990         {
4991             m_hvsDenoiser->InitKernelParams(m_hvsKernelBinary, m_hvsKernelBinarySize);
4992         }
4993         else
4994         {
4995             VPHAL_RENDER_ASSERTMESSAGE("New VphalHVSDenoiser Failed!");
4996             eStatus = MOS_STATUS_NULL_POINTER;
4997             return eStatus;
4998         }
4999     }
5000 
5001     if (m_hvsDenoiser)
5002     {
5003         m_hvsDenoiser->Render(pSrcSurface);
5004         uint32_t *pHVSDenoiseParam = (uint32_t *)m_hvsDenoiser->GetDenoiseParams();
5005         if (pHVSDenoiseParam)
5006         {
5007             // Media kernel computed the HVS Denoise Parameters according to the specific mapping function.
5008             // Programming these Parameters to VEBOX for processing.
5009             VPHAL_RENDER_NORMALMESSAGE("Set HVS Denoised Parameters to VEBOX DNDI params");
5010             // DW0
5011             pRenderData->VeboxDNDIParams.dwDenoiseMPThreshold       = (pHVSDenoiseParam[0] & 0x0000001f);
5012             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwDenoiseMPThreshold %d", pRenderData->VeboxDNDIParams.dwDenoiseMPThreshold);
5013             pRenderData->VeboxDNDIParams.dwDenoiseHistoryDelta      = (pHVSDenoiseParam[0] & 0x00000f00) >> 8;
5014             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwDenoiseHistoryDelta %d", pRenderData->VeboxDNDIParams.dwDenoiseHistoryDelta);
5015             pRenderData->VeboxDNDIParams.dwDenoiseMaximumHistory    = (pHVSDenoiseParam[0] & 0x000ff000) >> 12;
5016             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwDenoiseMaximumHistory %d", pRenderData->VeboxDNDIParams.dwDenoiseMaximumHistory);
5017             pRenderData->VeboxDNDIParams.dwDenoiseSTADThreshold     = (pHVSDenoiseParam[0] & 0xfff00000) >> 20;
5018             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwDenoiseSTADThreshold %d", pRenderData->VeboxDNDIParams.dwDenoiseSTADThreshold);
5019             // DW1
5020             pRenderData->VeboxDNDIParams.dwLTDThreshold             = (pHVSDenoiseParam[1] & 0x000003ff);
5021             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwLTDThreshold %d", pRenderData->VeboxDNDIParams.dwLTDThreshold);
5022             pRenderData->VeboxDNDIParams.dwTDThreshold              = (pHVSDenoiseParam[1] & 0x000ffc00) >> 10;
5023             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwTDThreshold %d", pRenderData->VeboxDNDIParams.dwTDThreshold);
5024             pRenderData->VeboxDNDIParams.dwDenoiseASDThreshold      = (pHVSDenoiseParam[1] & 0xfff00000) >> 20;
5025             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwDenoiseASDThreshold %d", pRenderData->VeboxDNDIParams.dwDenoiseASDThreshold);
5026             // DW2
5027             pRenderData->VeboxDNDIParams.dwDenoiseSCMThreshold      = (pHVSDenoiseParam[2] & 0x0fff0000) >> 16;
5028             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwDenoiseSCMThreshold %d", pRenderData->VeboxDNDIParams.dwDenoiseSCMThreshold);
5029             // DW4
5030             pRenderData->VeboxDNDIParams.dwChromaLTDThreshold       = (pHVSDenoiseParam[4] & 0x0000003f);
5031             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwChromaLTDThreshold %d", pRenderData->VeboxDNDIParams.dwChromaLTDThreshold);
5032             pRenderData->VeboxDNDIParams.dwChromaTDThreshold        = (pHVSDenoiseParam[4] & 0x00000fc0) >> 6;
5033             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwChromaTDThreshold %d", pRenderData->VeboxDNDIParams.dwChromaTDThreshold);
5034             pRenderData->VeboxDNDIParams.dwChromaSTADThreshold      = (pHVSDenoiseParam[4] & 0x00ff0000) >> 16;
5035             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwChromaSTADThreshold %d", pRenderData->VeboxDNDIParams.dwChromaSTADThreshold);
5036             // DW5
5037             pRenderData->VeboxDNDIParams.dwPixRangeWeight[0]        = (pHVSDenoiseParam[5] & 0x0000001f);
5038             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeWeight[0] %d", pRenderData->VeboxDNDIParams.dwPixRangeWeight[0]);
5039             pRenderData->VeboxDNDIParams.dwPixRangeWeight[1]        = (pHVSDenoiseParam[5] & 0x000003e0) >> 5;
5040             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeWeight[1] %d", pRenderData->VeboxDNDIParams.dwPixRangeWeight[1]);
5041             pRenderData->VeboxDNDIParams.dwPixRangeWeight[2]        = (pHVSDenoiseParam[5] & 0x00007c00) >> 10;
5042             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeWeight[2] %d", pRenderData->VeboxDNDIParams.dwPixRangeWeight[2]);
5043             pRenderData->VeboxDNDIParams.dwPixRangeWeight[3]        = (pHVSDenoiseParam[5] & 0x000f8000) >> 15;
5044             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeWeight[3] %d", pRenderData->VeboxDNDIParams.dwPixRangeWeight[3]);
5045             pRenderData->VeboxDNDIParams.dwPixRangeWeight[4]        = (pHVSDenoiseParam[5] & 0x01f00000) >> 20;
5046             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeWeight[4] %d", pRenderData->VeboxDNDIParams.dwPixRangeWeight[4]);
5047             pRenderData->VeboxDNDIParams.dwPixRangeWeight[5]        = (pHVSDenoiseParam[5] & 0x3e000000) >> 25;
5048             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeWeight[5] %d", pRenderData->VeboxDNDIParams.dwPixRangeWeight[5]);
5049             // DW7
5050             pRenderData->VeboxDNDIParams.dwPixRangeThreshold[5]     = (pHVSDenoiseParam[7] & 0x1fff0000) >> 16;
5051             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeThreshold[5] %d", pRenderData->VeboxDNDIParams.dwPixRangeThreshold[5]);
5052             // DW8
5053             pRenderData->VeboxDNDIParams.dwPixRangeThreshold[4]     = (pHVSDenoiseParam[8] & 0x1fff0000) >> 16;
5054             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeThreshold[4] %d", pRenderData->VeboxDNDIParams.dwPixRangeThreshold[4]);
5055             pRenderData->VeboxDNDIParams.dwPixRangeThreshold[3]     = (pHVSDenoiseParam[8] & 0x00001fff);
5056             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeThreshold[3] %d", pRenderData->VeboxDNDIParams.dwPixRangeThreshold[3]);
5057             // DW9
5058             pRenderData->VeboxDNDIParams.dwPixRangeThreshold[2]     = (pHVSDenoiseParam[9] & 0x1fff0000) >> 16;
5059             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeThreshold[2] %d", pRenderData->VeboxDNDIParams.dwPixRangeThreshold[2]);
5060             pRenderData->VeboxDNDIParams.dwPixRangeThreshold[1]     = (pHVSDenoiseParam[9] & 0x00001fff);
5061             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeThreshold[1] %d", pRenderData->VeboxDNDIParams.dwPixRangeThreshold[1]);
5062             // DW10
5063             pRenderData->VeboxDNDIParams.dwPixRangeThreshold[0]     = (pHVSDenoiseParam[10] & 0x1fff0000) >> 16;
5064             VPHAL_RENDER_NORMALMESSAGE("HVS: pRenderData->VeboxDNDIParams.dwPixRangeThreshold[0] %d", pRenderData->VeboxDNDIParams.dwPixRangeThreshold[0]);
5065 
5066             eStatus = MOS_STATUS_SUCCESS;
5067         }
5068     }
5069 
5070     return eStatus;
5071 }
5072 
5073 //!
5074 //! \brief Comp can be bypassed when the following conditions are all met
5075 //!        1. Single Layer input only
5076 //!        2. Single render target only
5077 //!        3. Blending Disabled
5078 //!        4. Interlaced Scaling Disabled
5079 //!        5. Field Weaving Disabled
5080 //!        6. LumaKey Disabled
5081 //!        8. Constriction Disabled
5082 //!
IS_COMP_BYPASS_FEASIBLE(bool _bCompNeeded,PCVPHAL_RENDER_PARAMS _pcRenderParams,PVPHAL_SURFACE _pSrcSurface)5083 bool VPHAL_VEBOX_STATE::IS_COMP_BYPASS_FEASIBLE(bool _bCompNeeded, PCVPHAL_RENDER_PARAMS _pcRenderParams, PVPHAL_SURFACE _pSrcSurface)
5084 {
5085     VPHAL_RENDER_NORMALMESSAGE(
5086         "_bCompNeeded %d, \
5087          uSrcCount %d, \
5088          uDstCount %d, \
5089          pBlendingParams %p, \
5090          bInterlacedScaling %d, \
5091          bFieldWeaving %d, \
5092          pLumaKeyParams %p, \
5093          pConstriction %p",
5094         _bCompNeeded,
5095         _pcRenderParams->uSrcCount,
5096         _pcRenderParams->uDstCount,
5097         _pSrcSurface->pBlendingParams,
5098         _pSrcSurface->bInterlacedScaling,
5099         _pSrcSurface->bFieldWeaving,
5100         _pSrcSurface->pLumaKeyParams,
5101         _pcRenderParams->pConstriction);
5102 
5103     return (_bCompNeeded == false &&
5104             _pcRenderParams->uSrcCount == 1 &&
5105             _pcRenderParams->uDstCount == 1 &&
5106             _pSrcSurface->pBlendingParams == nullptr &&
5107             _pSrcSurface->bInterlacedScaling == false &&
5108             _pSrcSurface->bFieldWeaving == false &&
5109             _pSrcSurface->pLumaKeyParams == nullptr &&
5110             _pcRenderParams->pConstriction == nullptr);
5111 }
5112 
5113 //!
5114 //! \brief Vebox can be the output pipe when the following conditions are all met
5115 //!        1. User feature keys value "Bypass Composition" is enabled.
5116 //!        2. Single render target only
5117 //!        3. Src Size = Dst Size
5118 //!        4. Max Src Size >= Src Size
5119 //!        5. rcSrc's top/left are zero
5120 //!        6. No Colorfill
5121 //!        7. IEF Disabled
5122 //!        8. Input is progressive
5123 //!        9. Rotation Disabled
5124 //!        10. Variance Query is disabled
5125 //!        11. Input format is supported by Vebox
5126 //!        12. RT format is supported by Vebox
5127 //!        13. 2PassCSC is not supported by Vebox only
5128 //!        14. Alpha Fill is disabled or when it's enabled, it's not background Alpha Fill mode
5129 //!        15. Dst parameters top/left are zero.
5130 //!
IS_OUTPUT_PIPE_VEBOX_FEASIBLE(PVPHAL_VEBOX_STATE _pVeboxState,PCVPHAL_RENDER_PARAMS _pcRenderParams,PVPHAL_SURFACE _pSrcSurface)5131 bool VPHAL_VEBOX_STATE::IS_OUTPUT_PIPE_VEBOX_FEASIBLE(PVPHAL_VEBOX_STATE _pVeboxState, PCVPHAL_RENDER_PARAMS _pcRenderParams, PVPHAL_SURFACE _pSrcSurface)
5132 {
5133     VPHAL_RENDER_NORMALMESSAGE(
5134         "dwCompBypassMode %d, \
5135          _pcRenderParams->uDstCount %d, \
5136          SAME_SIZE_RECT(rcSrc, rcDst) %d, \
5137          RECT1_CONTAINS_RECT2(rcMaxSrc, rcSrc) %d, \
5138          rcSrc.top %d \
5139          rcSrc.left %d \
5140          SAME_SIZE_RECT(rcDst, pTarget[0]->rcDst) %d, \
5141          pIEFParams %d, \
5142          SampleType %d, \
5143          Rotation %d, \
5144          bQueryVariance %d, \
5145          IsFormatSupported %d, \
5146          IsRTFormatSupported %d, \
5147          VeboxIs2PassesCSCNeeded %d, \
5148          AlphaMode %d, \
5149          rcDst.top %d, \
5150          rcDst.left %d",
5151         _pVeboxState->dwCompBypassMode,
5152         _pcRenderParams->uDstCount,
5153         SAME_SIZE_RECT(_pSrcSurface->rcSrc, _pSrcSurface->rcDst),
5154         RECT1_CONTAINS_RECT2(_pSrcSurface->rcMaxSrc, _pSrcSurface->rcSrc),
5155         _pSrcSurface->rcSrc.top,
5156         _pSrcSurface->rcSrc.left,
5157         SAME_SIZE_RECT(_pSrcSurface->rcDst, _pcRenderParams->pTarget[0]->rcDst),
5158         _pSrcSurface->pIEFParams,
5159         _pSrcSurface->SampleType,
5160         _pSrcSurface->Rotation,
5161         _pSrcSurface->bQueryVariance,
5162         _pVeboxState->IsFormatSupported(_pSrcSurface),
5163         _pVeboxState->IsRTFormatSupported(_pSrcSurface, _pcRenderParams->pTarget[0]),
5164         _pVeboxState->VeboxIs2PassesCSCNeeded(_pSrcSurface, _pcRenderParams->pTarget[0]),
5165         (_pcRenderParams->pCompAlpha == nullptr || _pcRenderParams->pCompAlpha->AlphaMode != VPHAL_ALPHA_FILL_MODE_BACKGROUND),
5166         _pSrcSurface->rcDst.top,
5167         _pSrcSurface->rcDst.left);
5168 
5169     return (_pVeboxState->dwCompBypassMode != VPHAL_COMP_BYPASS_DISABLED &&
5170             _pcRenderParams->uDstCount == 1 &&
5171             SAME_SIZE_RECT(_pSrcSurface->rcSrc, _pSrcSurface->rcDst) &&
5172             RECT1_CONTAINS_RECT2(_pSrcSurface->rcMaxSrc, _pSrcSurface->rcSrc) &&
5173             _pSrcSurface->rcSrc.top == 0 &&
5174             _pSrcSurface->rcSrc.left == 0 &&
5175             SAME_SIZE_RECT(_pSrcSurface->rcDst, _pcRenderParams->pTarget[0]->rcDst) &&
5176             _pSrcSurface->pIEFParams == nullptr &&
5177             _pSrcSurface->SampleType == SAMPLE_PROGRESSIVE &&
5178             _pSrcSurface->Rotation == VPHAL_ROTATION_IDENTITY &&
5179             _pSrcSurface->bQueryVariance == false &&
5180             _pVeboxState->IsFormatSupported(_pSrcSurface) &&
5181             _pVeboxState->IsRTFormatSupported(_pSrcSurface, _pcRenderParams->pTarget[0]) &&
5182             !(_pVeboxState->VeboxIs2PassesCSCNeeded(_pSrcSurface, _pcRenderParams->pTarget[0])) &&
5183             (_pcRenderParams->pCompAlpha == nullptr ||
5184                 _pcRenderParams->pCompAlpha->AlphaMode != VPHAL_ALPHA_FILL_MODE_BACKGROUND) &&
5185             _pSrcSurface->rcDst.top == 0 &&
5186             _pSrcSurface->rcDst.left == 0);
5187 }
5188 
~VPHAL_VEBOX_RENDER_DATA()5189 VPHAL_VEBOX_RENDER_DATA::~VPHAL_VEBOX_RENDER_DATA()
5190 {
5191     if (m_pVeboxStateParams)
5192     {
5193         MOS_Delete(m_pVeboxStateParams);
5194         m_pVeboxStateParams = nullptr;
5195     }
5196 
5197     if (m_pVeboxIecpParams)
5198     {
5199         MOS_Delete(m_pVeboxIecpParams);
5200         m_pVeboxIecpParams = nullptr;
5201     }
5202 }
5203 
Init()5204 MOS_STATUS VPHAL_VEBOX_RENDER_DATA::Init()
5205 {
5206     // Vebox State Parameters
5207     // m_pVeboxStateParams needs to be set to nullptr in constructor
5208 
5209     if (!m_pVeboxStateParams)
5210     {
5211         m_pVeboxStateParams = MOS_New(VPHAL_VEBOX_STATE_PARAMS);
5212         if (!m_pVeboxStateParams)
5213         {
5214             return MOS_STATUS_NO_SPACE;
5215         }
5216     }
5217     m_pVeboxStateParams->Init();
5218 
5219 
5220     // Vebox IECP State Parameters
5221     // m_pVeboxIecpParams needs to be set to nullptr in constructor
5222     if (!m_pVeboxIecpParams)
5223     {
5224         m_pVeboxIecpParams = MOS_New(VPHAL_VEBOX_IECP_PARAMS);
5225         if (!m_pVeboxIecpParams)
5226         {
5227             return MOS_STATUS_NO_SPACE;
5228         }
5229     }
5230     m_pVeboxIecpParams->Init();
5231 
5232     // Flags
5233     bRefValid      = false;
5234     bSameSamples   = false;
5235     bProgressive   = false;
5236     bDenoise       = false;
5237 #if VEBOX_AUTO_DENOISE_SUPPORTED
5238     bAutoDenoise   = false;
5239 #endif
5240     bChromaDenoise = false;
5241     bOutOfBound    = false;
5242     bVDIWalker     = false;
5243     bIECP          = false;
5244     bColorPipe     = false;
5245     bProcamp       = false;
5246     // DNDI/Vebox
5247     bDeinterlace   = false;
5248     bSingleField   = false;
5249     bTFF           = false;
5250     bTopField      = false;
5251     bBeCsc         = false;
5252     bFeCsc         = false;
5253     bVeboxBypass   = false;
5254     b60fpsDi       = false;
5255     bQueryVariance = false;
5256     // Surface Information
5257     iFrame0        = 0;
5258     iFrame1        = 0;
5259     iCurDNIn       = 0;
5260     iCurDNOut      = 0;
5261     iCurHistIn     = 0;
5262     iCurHistOut    = 0;
5263     // Geometry
5264     iBlocksX       = 0;
5265     iBlocksY       = 0;
5266     iBindingTable  = 0;
5267     iMediaID0      = 0;
5268     iMediaID1      = 0;
5269     // Perf
5270     PerfTag        = VPHAL_NONE;
5271     // States
5272     pMediaState        = nullptr;
5273     pVeboxState        = nullptr;
5274     pRenderTarget      = nullptr;
5275     SamplerStateParams = { };
5276     VeboxDNDIParams    = { };
5277     pAlphaParams       = nullptr;
5278     // Batch Buffer rendering arguments
5279     BbArgs = { };
5280     // Vebox output parameters
5281     OutputPipe = VPHAL_OUTPUT_PIPE_MODE_COMP;
5282     // Kernel Information
5283     for (int i = 0; i < VPHAL_NUM_KERNEL_VEBOX; i++)
5284     {
5285         pKernelParam[i] = nullptr;
5286         KernelEntry[i]  = { };
5287     }
5288     pDNUVParams          = nullptr;
5289     iCurbeLength         = 0;
5290     iCurbeOffset         = 0;
5291     iInlineLength        = 0;
5292     // Debug parameters
5293     pKernelName          = nullptr;
5294     Component            = COMPONENT_UNKNOWN;
5295     // Memory compression flag
5296     bEnableMMC           = false;
5297 
5298     fScaleX              = 0.0f;
5299     fScaleY              = 0.0f;
5300 
5301     bHdr3DLut            = false;
5302     uiMaxDisplayLum      = 4000;
5303     uiMaxContentLevelLum = 1000;
5304     hdrMode              = VPHAL_HDR_MODE_NONE;
5305 
5306     return MOS_STATUS_SUCCESS;
5307 }
5308