1 /*===================== begin_copyright_notice ==================================
2 
3 # Copyright (c) 2022, Intel Corporation
4 
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 # and/or sell copies of the Software, and to permit persons to whom the
10 # Software is furnished to do so, subject to the following conditions:
11 
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
14 
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 # OTHER DEALINGS IN THE SOFTWARE.
22 
23 ======================= end_copyright_notice ==================================*/
24 //!
25 //! \file     vphal_renderer_xe_hpm.cpp
26 //! \brief    VPHAL top level rendering component and the entry to low level renderers
27 //! \details  The top renderer is responsible for coordinating the sequence of calls to low level renderers, e.g. DNDI or Comp
28 //!
29 #include "vphal_renderer_xe_hpm.h"
30 #if defined(ENABLE_KERNELS)
31 #include "igvpkrn_xe_hpg.h"
32 #include "igvpkrn_xe_hpg_cmfcpatch.h"
33 #endif
34 #include "vphal_render_vebox_xe_hpm.h"
35 #include "vphal_render_composite_xe_xpm.h"
36 #include "vp_debug.h"
37 
38 extern const Kdll_RuleEntry         g_KdllRuleTable_Xe_Hpm[];
39 
GetCacheCntl(PMOS_INTERFACE pOsInterface,PLATFORM * pPlatform,MEDIA_FEATURE_TABLE * pSkuTable,PVPHAL_RENDER_CACHE_CNTL pSettings)40 void VphalRendererXe_Hpm::GetCacheCntl(
41     PMOS_INTERFACE                      pOsInterface,
42     PLATFORM                            *pPlatform,
43     MEDIA_FEATURE_TABLE                 *pSkuTable,
44     PVPHAL_RENDER_CACHE_CNTL            pSettings)
45 
46 {
47     MOS_HW_RESOURCE_DEF                 Usage;
48     MEMORY_OBJECT_CONTROL_STATE         MemObjCtrl;
49 
50     VPHAL_RENDER_CHK_NULL_NO_STATUS_RETURN(pSettings);
51 
52     if (pSettings->bCompositing)
53     {
54         pSettings->Composite.bL3CachingEnabled = true;
55 
56         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Composite.PrimaryInputSurfMemObjCtl,   MOS_MP_RESOURCE_USAGE_SurfaceState_RCS);
57         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Composite.InputSurfMemObjCtl,          MOS_MP_RESOURCE_USAGE_SurfaceState_RCS);
58         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Composite.TargetSurfMemObjCtl,         MOS_MP_RESOURCE_USAGE_DEFAULT_RCS);
59     }
60     else
61     {
62         pSettings->Composite.bL3CachingEnabled = false;
63 
64         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Composite.PrimaryInputSurfMemObjCtl, MOS_MP_RESOURCE_USAGE_DEFAULT);
65         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Composite.InputSurfMemObjCtl,        MOS_MP_RESOURCE_USAGE_DEFAULT);
66         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Composite.TargetSurfMemObjCtl,       MOS_MP_RESOURCE_USAGE_DEFAULT);
67     }
68 
69     if (pSettings->bDnDi)
70     {
71         pSettings->DnDi.bL3CachingEnabled = false;
72 
73         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.CurrentInputSurfMemObjCtl,        MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
74         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.PreviousInputSurfMemObjCtl,       MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
75         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.STMMInputSurfMemObjCtl,           MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
76         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.STMMOutputSurfMemObjCtl,          MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
77         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.DnOutSurfMemObjCtl,               MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
78         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.CurrentOutputSurfMemObjCtl,       MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
79         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.StatisticsOutputSurfMemObjCtl,    MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
80         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.AlphaOrVignetteSurfMemObjCtl,     MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
81         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.LaceOrAceOrRgbHistogramSurfCtrl,  MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
82         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.SkinScoreSurfMemObjCtl,           MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
83         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.LaceLookUpTablesSurfMemObjCtl,    MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
84         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.Vebox3DLookUpTablesSurfMemObjCtl, MOS_MP_RESOURCE_USAGE_SurfaceState_FF);
85     }
86     else
87     {
88         pSettings->DnDi.bL3CachingEnabled = false;
89 
90         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.CurrentInputSurfMemObjCtl,        MOS_MP_RESOURCE_USAGE_DEFAULT);
91         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.PreviousInputSurfMemObjCtl,       MOS_MP_RESOURCE_USAGE_DEFAULT);
92         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.STMMInputSurfMemObjCtl,           MOS_MP_RESOURCE_USAGE_DEFAULT);
93         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.STMMOutputSurfMemObjCtl,          MOS_MP_RESOURCE_USAGE_DEFAULT);
94         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.DnOutSurfMemObjCtl,               MOS_MP_RESOURCE_USAGE_DEFAULT);
95         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.CurrentOutputSurfMemObjCtl,       MOS_MP_RESOURCE_USAGE_DEFAULT);
96         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.StatisticsOutputSurfMemObjCtl,    MOS_MP_RESOURCE_USAGE_DEFAULT);
97         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.AlphaOrVignetteSurfMemObjCtl,     MOS_MP_RESOURCE_USAGE_DEFAULT);
98         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.LaceOrAceOrRgbHistogramSurfCtrl,  MOS_MP_RESOURCE_USAGE_DEFAULT);
99         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.SkinScoreSurfMemObjCtl,           MOS_MP_RESOURCE_USAGE_DEFAULT);
100         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.LaceLookUpTablesSurfMemObjCtl,    MOS_MP_RESOURCE_USAGE_DEFAULT);
101         VPHAL_SET_SURF_MEMOBJCTL(pSettings->DnDi.Vebox3DLookUpTablesSurfMemObjCtl, MOS_MP_RESOURCE_USAGE_DEFAULT);
102     }
103 
104     if (pSettings->bLace)
105     {
106         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.FrameHistogramSurfaceMemObjCtl,                       MOS_MP_RESOURCE_USAGE_SurfaceState_RCS);
107         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.AggregatedHistogramSurfaceMemObjCtl,                  MOS_MP_RESOURCE_USAGE_SurfaceState_RCS);
108         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.StdStatisticsSurfaceMemObjCtl,                        MOS_MP_RESOURCE_USAGE_SurfaceState_RCS);
109         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.PwlfInSurfaceMemObjCtl,                               MOS_MP_RESOURCE_USAGE_SurfaceState_RCS);
110         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.PwlfOutSurfaceMemObjCtl,                              MOS_MP_RESOURCE_USAGE_SurfaceState_RCS);
111         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.WeitCoefSurfaceMemObjCtl,                             MOS_MP_RESOURCE_USAGE_SurfaceState_RCS);
112     }
113     else
114     {
115         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.FrameHistogramSurfaceMemObjCtl,                       MOS_MP_RESOURCE_USAGE_DEFAULT);
116         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.AggregatedHistogramSurfaceMemObjCtl,                  MOS_MP_RESOURCE_USAGE_DEFAULT);
117         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.StdStatisticsSurfaceMemObjCtl,                        MOS_MP_RESOURCE_USAGE_DEFAULT);
118         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.PwlfInSurfaceMemObjCtl,                               MOS_MP_RESOURCE_USAGE_DEFAULT);
119         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.PwlfOutSurfaceMemObjCtl,                              MOS_MP_RESOURCE_USAGE_DEFAULT);
120         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.WeitCoefSurfaceMemObjCtl,                             MOS_MP_RESOURCE_USAGE_DEFAULT);
121         VPHAL_SET_SURF_MEMOBJCTL(pSettings->Lace.GlobalToneMappingCurveLUTSurfaceMemObjCtl,            MOS_MP_RESOURCE_USAGE_DEFAULT);
122     }
123 
124 }
125 
AllocateRenderComponents(PMHW_VEBOX_INTERFACE pVeboxInterface,PMHW_SFC_INTERFACE pSfcInterface)126 MOS_STATUS VphalRendererXe_Hpm::AllocateRenderComponents(
127         PMHW_VEBOX_INTERFACE                pVeboxInterface,
128         PMHW_SFC_INTERFACE                  pSfcInterface)
129 {
130     MOS_STATUS              eStatus;
131     VPHAL_RENDER_CACHE_CNTL CacheCntl;
132 
133     VPHAL_RENDER_CHK_NULL_RETURN(m_pRenderHal);
134 
135     eStatus = MOS_STATUS_SUCCESS;
136 
137     // Get the cache settings
138     MOS_ZeroMemory(&CacheCntl, sizeof(CacheCntl));
139 
140     CacheCntl.bDnDi        = true;
141     CacheCntl.bCompositing = true;
142 
143     VPHAL_RENDERER_GET_CACHE_CNTL(this,
144         m_pOsInterface,
145         &m_pRenderHal->Platform,
146         m_pSkuTable,
147         &CacheCntl);
148 
149     // Initialize Advanced Processing Interface
150     pRender[VPHAL_RENDER_ID_VEBOX] = MOS_New(
151         VPHAL_VEBOX_STATE_XE_HPM,
152         m_pOsInterface,
153         pVeboxInterface,
154         pSfcInterface,
155         m_pRenderHal,
156         &VeboxExecState[0],
157         &PerfData,
158         CacheCntl.DnDi,
159         &eStatus);
160     if (!pRender[VPHAL_RENDER_ID_VEBOX] ||
161         (eStatus != MOS_STATUS_SUCCESS))
162     {
163         eStatus = MOS_STATUS_NO_SPACE;
164         VPHAL_RENDER_ASSERTMESSAGE("Allocate Vebox Render Fail.");
165         return eStatus;
166     }
167 
168     pRender[VPHAL_RENDER_ID_VEBOX2] = MOS_New(
169         VPHAL_VEBOX_STATE_XE_HPM,
170         m_pOsInterface,
171         pVeboxInterface,
172         pSfcInterface,
173         m_pRenderHal,
174         &VeboxExecState[1],
175         &PerfData,
176         CacheCntl.DnDi,
177         &eStatus);
178     if (!pRender[VPHAL_RENDER_ID_VEBOX2] ||
179         (eStatus != MOS_STATUS_SUCCESS))
180     {
181         eStatus = MOS_STATUS_NO_SPACE;
182         VPHAL_RENDER_ASSERTMESSAGE("Allocate Vebox Render Fail.");
183         return eStatus;
184     }
185 
186     // Allocate Composite State
187     pRender[VPHAL_RENDER_ID_COMPOSITE] = MOS_New(
188         CompositeStateXe_Xpm,
189         m_pOsInterface,
190         m_pRenderHal,
191         &PerfData,
192         CacheCntl.Composite,
193         &eStatus);
194     if (!pRender[VPHAL_RENDER_ID_COMPOSITE] ||
195         (eStatus != MOS_STATUS_SUCCESS))
196     {
197         eStatus = MOS_STATUS_NO_SPACE;
198         VPHAL_RENDER_ASSERTMESSAGE("Allocate Composite Render Fail.");
199         return eStatus;
200     }
201 
202     return eStatus;
203 }
204 
InitKdllParam()205 MOS_STATUS VphalRendererXe_Hpm::InitKdllParam()
206 {
207     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
208 
209     // Override kernel binary for CMFC/SWSB
210     if (bEnableCMFC)
211     {
212         pKernelDllRules  = g_KdllRuleTable_Xe_Hpm;
213 #if defined(ENABLE_KERNELS)
214         pcKernelBin      = (const void *)IGVPKRN_XE_HPG;
215         dwKernelBinSize  = IGVPKRN_XE_HPG_SIZE;
216         pcFcPatchBin     = (const void *)IGVPKRN_XE_HPG_CMFCPATCH;
217         dwFcPatchBinSize = IGVPKRN_XE_HPG_CMFCPATCH_SIZE;
218 #else
219         pcKernelBin      = nullptr;
220         dwKernelBinSize  = 0;
221         pcFcPatchBin     = nullptr;
222         dwFcPatchBinSize = 0;
223 #endif
224     }
225 
226     if ((NULL == pcFcPatchBin) || (0 == dwFcPatchBinSize))
227     {
228         bEnableCMFC = false;
229     }
230 
231     if (bEnableCMFC && (NULL != pcFcPatchBin) && (0 != dwFcPatchBinSize))
232     {
233         m_pRenderHal->bEnableP010SinglePass = true;
234     }
235     else
236     {
237         m_pRenderHal->bEnableP010SinglePass = false;
238     }
239 
240     return eStatus;
241 }
242 
Render(PCVPHAL_RENDER_PARAMS pcRenderParams)243 MOS_STATUS VphalRendererXe_Hpm::Render(
244     PCVPHAL_RENDER_PARAMS   pcRenderParams)
245 {
246     MOS_STATUS              eStatus;
247     PMOS_INTERFACE          pOsInterface;
248     PRENDERHAL_INTERFACE    pRenderHal;
249     VPHAL_RENDER_PARAMS     RenderParams;                                       // Make a copy of render params
250     PVPHAL_SURFACE          pSrcLeft[VPHAL_MAX_SOURCES];                        // Array of sources referring to left view stereo content
251     PVPHAL_SURFACE          pSrcRight[VPHAL_MAX_SOURCES];                       // Array of sources referring to right view stereo content
252     uint32_t                uiRenderPasses;                                     // Number of rendering passes in this one call to VpHal_RndrRender()
253     uint32_t                uiCurrentRenderPass;                                // Current render pass
254     uint32_t                uiDst;
255     VPHAL_GET_SURFACE_INFO  Info;
256 
257     //--------------------------------------------
258     VPHAL_RENDER_ASSERT(pcRenderParams);
259     VPHAL_RENDER_ASSERT(m_pOsInterface);
260     VPHAL_RENDER_ASSERT(m_pRenderHal);
261     VPHAL_RENDER_ASSERT(pKernelDllState);
262     VPHAL_RENDER_ASSERT(pRender[VPHAL_RENDER_ID_COMPOSITE]);
263     //--------------------------------------------
264 
265     eStatus         = MOS_STATUS_SUCCESS;
266     pOsInterface    = m_pOsInterface;
267     pRenderHal      = m_pRenderHal;
268 
269     // Validate render target
270     if (pcRenderParams->pTarget[0] == nullptr ||
271         Mos_ResourceIsNull(&(pcRenderParams->pTarget[0]->OsResource)))
272     {
273         VPHAL_RENDER_ASSERTMESSAGE("Invalid Render Target.");
274         eStatus = MOS_STATUS_UNKNOWN;
275         goto finish;
276     }
277 
278     // Protection mechanism, Only KBL+ support P010 output.
279     if (IsFormatSupported(pcRenderParams) == false)
280     {
281         VPHAL_RENDER_ASSERTMESSAGE("Invalid Render Target Output Format.");
282         eStatus = MOS_STATUS_UNKNOWN;
283         goto finish;
284     }
285 
286     VPHAL_DBG_STATE_DUMP_SET_CURRENT_FRAME_COUNT(uiFrameCounter);
287 
288     // Validate max number sources
289     if (pcRenderParams->uSrcCount > VPHAL_MAX_SOURCES)
290     {
291         VPHAL_RENDER_ASSERTMESSAGE("Invalid number of samples.");
292         eStatus = MOS_STATUS_UNKNOWN;
293         goto finish;
294     }
295 
296     // Validate max number targets
297     if (pcRenderParams->uDstCount > VPHAL_MAX_TARGETS)
298     {
299         VPHAL_RENDER_ASSERTMESSAGE("Invalid number of targets.");
300         eStatus = MOS_STATUS_UNKNOWN;
301         goto finish;
302     }
303 
304     // Copy the Render Params structure (so we can update it)
305     RenderParams = *pcRenderParams;
306 
307     VPHAL_DBG_PARAMETERS_DUMPPER_DUMP_XML(&RenderParams);
308     VPHAL_DBG_OCA_DUMPER_SET_RENDER_PARAM(pRenderHal, &RenderParams);
309 
310     // Get resource information for render target
311     MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
312 
313     for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
314     {
315         VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
316             m_pOsInterface,
317             &Info,
318             RenderParams.pTarget[uiDst]));
319     }
320 
321     // Set the component info
322     m_pOsInterface->Component = pcRenderParams->Component;
323 
324     // Init component(DDI entry point) info for perf measurement
325     m_pOsInterface->pfnSetPerfTag(m_pOsInterface, VPHAL_NONE);
326 
327     // Increment frame ID for performance measurement
328     m_pOsInterface->pfnIncPerfFrameID(m_pOsInterface);
329 
330     // Enable Turbo mode if sku present and DDI requests it
331     if (m_pSkuTable && MEDIA_IS_SKU(m_pSkuTable, FtrMediaTurboMode))
332     {
333         m_pRenderHal->bTurboMode = RenderParams.bTurboMode;
334     }
335 
336     // Reset feature reporting
337     m_reporting->InitReportValue();
338 
339     MOS_ZeroMemory(pSrcLeft,  sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
340     MOS_ZeroMemory(pSrcRight, sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
341 
342     VPHAL_RENDER_CHK_STATUS(PrepareSources(
343         &RenderParams,
344         pSrcLeft,
345         pSrcRight,
346         &uiRenderPasses));
347 
348     //set GpuContext
349     VPHAL_RENDER_CHK_STATUS(SetRenderGpuContext(RenderParams));
350 
351     // align rectangle and source surface
352     for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
353     {
354         VPHAL_RENDER_CHK_STATUS(VpHal_RndrRectSurfaceAlignment(RenderParams.pTarget[uiDst], RenderParams.pTarget[uiDst]->Format));
355     }
356 
357     for (uiCurrentRenderPass = 0;
358         uiCurrentRenderPass < uiRenderPasses;
359         uiCurrentRenderPass++)
360     {
361         // Assign source surfaces for current rendering pass
362         MOS_SecureMemcpy(
363             RenderParams.pSrc,
364             sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES,
365             (uiCurrentRenderPass == 0) ? pSrcLeft : pSrcRight,
366             sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
367 
368         MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
369 
370         for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
371         {
372             Info.S3dChannel = RenderParams.pTarget[uiDst]->Channel;
373             Info.ArraySlice = uiCurrentRenderPass;
374 
375             VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
376                 m_pOsInterface,
377                 &Info,
378                 RenderParams.pTarget[uiDst]));
379         }
380 
381         // Update channel. 0 = mono or stereo left, 1 = stereo right
382         uiCurrentChannel = uiCurrentRenderPass;
383 
384         // WA to void colorfill + rotation output cropution when Eu fusion is on.
385         bool bColorFill = false;
386         bool bRotation  = false;
387         if ((pcRenderParams->pTarget[0] != nullptr)
388             && (pcRenderParams->pSrc[0] != nullptr)
389             && (pcRenderParams->pColorFillParams != nullptr))
390         {
391             bColorFill =  (!RECT1_CONTAINS_RECT2(pcRenderParams->pSrc[0]->rcDst, pcRenderParams->pTarget[0]->rcDst)) ? true : false;
392             bRotation = (pcRenderParams->pSrc[0]->Rotation != VPHAL_ROTATION_IDENTITY) ? true : false;
393             m_pRenderHal->eufusionBypass = bColorFill && bRotation;
394 
395             VPHAL_RENDER_NORMALMESSAGE("eufusionBypass = %d", pRenderHal->eufusionBypass ? 1 : 0);
396         }
397         // for interlaced scaling : two field --> one interleaved mode
398         if (pcRenderParams->pSrc[0]->InterlacedScalingType == ISCALING_FIELD_TO_INTERLEAVED)
399         {
400             RenderParams.pSrc[0]->rcDst.bottom                   = RenderParams.pSrc[0]->rcDst.bottom / 2;
401             RenderParams.pSrc[0]->pBwdRef->rcDst.bottom          = RenderParams.pSrc[0]->rcDst.bottom;
402             RenderParams.pSrc[0]->pBwdRef->InterlacedScalingType = ISCALING_FIELD_TO_INTERLEAVED;
403             if (RenderParams.pSrc[0]->SampleType == SAMPLE_SINGLE_TOP_FIELD)
404             {
405                 RenderParams.pSrc[0]->pBwdRef->SampleType = SAMPLE_SINGLE_BOTTOM_FIELD;
406                 RenderParams.pTarget[0]->SampleType       = SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
407             }
408             else
409             {
410                 RenderParams.pSrc[0]->pBwdRef->SampleType = SAMPLE_SINGLE_TOP_FIELD;
411                 RenderParams.pTarget[0]->SampleType       = SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD;
412             }
413             if (RenderParams.pSrc[0]->pBwdRef->pDeinterlaceParams)
414             {
415                 MOS_FreeMemory(RenderParams.pSrc[0]->pBwdRef->pDeinterlaceParams);
416                 RenderParams.pSrc[0]->pBwdRef->pDeinterlaceParams = nullptr;
417             }
418 
419             for (int uiField = 0; uiField < 2; uiField++)
420             {
421                 if (uiField == 0)
422                 {
423                     VPHAL_RENDER_CHK_STATUS(RenderPass(&RenderParams));
424                 }
425                 else
426                 {
427                     RenderParams.pSrc[0] = RenderParams.pSrc[0]->pBwdRef;
428                     RenderParams.pSrc[0]->SurfType = SURF_IN_PRIMARY;
429                     VPHAL_RENDER_CHK_STATUS(RenderPass(&RenderParams));
430                 }
431             }
432         }
433         else
434         {
435             VPHAL_RENDER_CHK_STATUS(RenderScaling(&RenderParams));
436             VPHAL_RENDER_CHK_STATUS(RenderPass(&RenderParams));
437         }
438     }
439 finish:
440     uiFrameCounter++;
441     return eStatus;
442 }
443 
444 //!
445 //! \brief    Allocate surface dumper
446 //! \return   MOS_STATUS
447 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
448 //!
CreateSurfaceDumper()449 MOS_STATUS VphalRendererXe_Hpm::CreateSurfaceDumper()
450 {
451 #if (_DEBUG || _RELEASE_INTERNAL)
452     // Initialize Surface Dumper
453     VPHAL_DBG_SURF_DUMP_CREATE_XE_XPM();
454     VPHAL_RENDER_CHK_NULL_RETURN(m_surfaceDumper);
455 
456 #if !EMUL
457     VphalSurfaceDumperXe_Xpm *pSurfaceDumperXe_Xpm = dynamic_cast<VphalSurfaceDumperXe_Xpm *>(m_surfaceDumper);
458     VPHAL_RENDER_CHK_NULL_RETURN(pSurfaceDumperXe_Xpm);
459     VPHAL_RENDER_CHK_NULL_RETURN(pSurfaceDumperXe_Xpm->GetBltState());
460 #endif
461 #endif
462     return MOS_STATUS_SUCCESS;
463 }
464 
465 //!
466 //! \brief    Scaling function
467 //! \details  The scaling function is only for scaling without other VP features.
468 //!           Down scaling needs 2 pass if scaling ratio is >2 for better quality.
469 //!           Pass#1 DS to 1/2 target resolution; Pass #2: DS from 1/2 target resolution to target resolution
470 //! \param    [in,out] pRenderParams
471 //!           Pointer to VPHAL render parameter
472 //! \return   MOS_STATUS
473 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
474 //!
RenderScaling(PVPHAL_RENDER_PARAMS pRenderParams)475 MOS_STATUS VphalRendererXe_Hpm::RenderScaling(
476     PVPHAL_RENDER_PARAMS    pRenderParams)
477 {
478     MOS_STATUS                  eStatus                 = MOS_STATUS_SUCCESS;
479     PVPHAL_SURFACE              pSource                 = nullptr;              // Pointer to the primary and original source surface
480     PVPHAL_SURFACE              pTarget                 = nullptr;              // Pointer to the target surface
481     float                       fScaleX                 = 0.0;                  // The original scaling ratio in X axis
482     float                       fScaleY                 = 0.0;                  // the original scaling ratio in Y axis
483     PLATFORM                    Platform                = {};
484     bool                        bScalingFirst           = false;                // Need to scaling first or not?
485     bool                        b2PassScaling           = false;                // 2 Pass scaling
486     uint32_t                    dwAllocatedWidth        = 1280;                 // The width of intermediate surfaces
487     uint32_t                    dwAllocatedHeight       = 720;                  // The height of intermediate surfaces
488     RECT                        rectScalingRegion       = {0, 0, 1280, 720};    // Scaling region of down scaling
489     VPHAL_RENDER_PARAMS         renderParams            = {};
490     VPHAL_SURFACE               inputSurface            = {};
491     PVPHAL_3DLUT_PARAMS         p3DLutParams            = nullptr;
492     PVPHAL_SURFACE              pDSSurface              = nullptr;              // Always point to the down scaled surface
493     uint32_t                    dwHalfInWidth           = 1280;                 // Half of the processed input width
494     uint32_t                    dwHalfInHeight          = 720;                  // Half of the processed input height
495     RECT                        rectHalfInRegion        = {0, 0, 1280, 720};    // Half of the processed input region
496 
497     VPHAL_RENDER_CHK_NULL(pRenderParams);
498     VPHAL_RENDER_CHK_NULL(pRenderParams->pSrc);
499     VPHAL_RENDER_CHK_NULL(pRenderParams->pTarget);
500     VPHAL_RENDER_CHK_NULL(m_pSkuTable);
501     VPHAL_RENDER_CHK_NULL(m_pOsInterface);
502 
503     // Limited to 1 input and 1 output. If not 1->1, fall back to the typical video processing path.
504     if ((pRenderParams->uSrcCount != 1) || (pRenderParams->uDstCount != 1))
505     {
506         VPHAL_RENDER_NORMALMESSAGE(" Source Count %d, Destination Count %d", pRenderParams->uSrcCount, pRenderParams->uDstCount);
507         eStatus = MOS_STATUS_SUCCESS;
508         goto finish;
509     }
510 
511     pSource     = pRenderParams->pSrc[0];
512     pTarget     = pRenderParams->pTarget[0];
513     VPHAL_RENDER_CHK_NULL(pSource);
514     VPHAL_RENDER_CHK_NULL(pTarget);
515 
516     // Calculating the scaling ratio
517     fScaleX = (float)(pSource->rcDst.right - pSource->rcDst.left) /
518               (float)(pSource->rcSrc.right - pSource->rcSrc.left);
519     fScaleY = (float)(pSource->rcDst.bottom - pSource->rcDst.top) /
520               (float)(pSource->rcSrc.bottom - pSource->rcSrc.top);
521     b2PassScaling = (fScaleX < 0.5f) && (fScaleY < 0.5f);
522 
523     // Scaling first, then other VP features. It is enabled on server for HDR transcoding with 3DLUT enabled if down scaling as of now.
524     // 2 pass down scaling may be changed later according to the quality anaysis.
525     m_pOsInterface->pfnGetPlatform(m_pOsInterface, &Platform);
526     bScalingFirst = MEDIA_IS_SKU(m_pSkuTable, FtrScalingFirst) &&
527                      (pSource->p3DLutParams != nullptr)        &&
528                      (fScaleX < 1.0f && fScaleY < 1.0f);
529 
530     // If no need to scaling firstly, fall back to the typical video processing path.
531     if (!bScalingFirst)
532     {
533         eStatus = MOS_STATUS_SUCCESS;
534         goto finish;
535     }
536 
537     // Do the down scaling firstly, then 3DLUT VEBOX features.
538     // Allocate down scaling surfaces
539     for (uint32_t nIndex = 0; nIndex < VPHAL_MAX_NUM_DS_SURFACES; nIndex++)
540     {
541          if (m_pDSSurface[nIndex] == nullptr)
542          {
543              m_pDSSurface[nIndex] = (PVPHAL_SURFACE)MOS_AllocAndZeroMemory(sizeof(VPHAL_SURFACE));
544              VPHAL_RENDER_CHK_NULL(m_pDSSurface[nIndex]);
545          }
546     }
547 
548     // Calculate the size of processing region for 2 pass downscaling
549     dwHalfInWidth                   = (uint32_t)((0.5) * (float)(pSource->rcSrc.right - pSource->rcSrc.left));
550     dwHalfInHeight                  = (uint32_t)((0.5) * (float)(pSource->rcSrc.bottom- pSource->rcSrc.top));
551     dwHalfInWidth                   = MOS_ALIGN_CEIL(dwHalfInWidth, 4);
552     dwHalfInHeight                  = MOS_ALIGN_CEIL(dwHalfInHeight, 4);
553     rectHalfInRegion.top            = 0;
554     rectHalfInRegion.left           = 0;
555     rectHalfInRegion.right          = dwHalfInWidth;
556     rectHalfInRegion.bottom         = dwHalfInHeight;
557 
558     // Allocate intermediate surface for the first pass
559     dwAllocatedWidth                = MOS_MAX(dwHalfInWidth, pTarget->dwWidth);
560     dwAllocatedHeight               = MOS_MAX(dwHalfInHeight, pTarget->dwHeight);
561     VPHAL_RENDER_CHK_STATUS(AllocateSurface(pRenderParams, pSource, m_pDSSurface[0], dwAllocatedWidth, dwAllocatedHeight, pSource->Format));
562     // First pass scaling
563     {
564         // Use inputSurface instead of the pointer of the original input to keep it unchanged.
565         rectScalingRegion               = (b2PassScaling) ? rectHalfInRegion : pSource->rcDst;
566         p3DLutParams                    = pSource->p3DLutParams;
567         renderParams                    = *pRenderParams;
568         inputSurface                    = *pSource;
569         inputSurface.p3DLutParams       = nullptr;
570         inputSurface.rcDst              = rectScalingRegion;
571         m_pDSSurface[0]->rcSrc          = rectScalingRegion;
572         m_pDSSurface[0]->rcDst          = rectScalingRegion;
573         m_pDSSurface[0]->rcMaxSrc       = rectScalingRegion;
574         renderParams.pSrc[0]            = &inputSurface;
575         renderParams.pTarget[0]         = m_pDSSurface[0];
576         VPHAL_RENDER_CHK_STATUS(RenderPass(&renderParams));
577         m_pDSSurface[0]->rcSrc          = m_pDSSurface[0]->rcDst;
578         m_pDSSurface[0]->rcMaxSrc       = m_pDSSurface[0]->rcDst;
579         m_pDSSurface[0]->rcDst          = pSource->rcDst;
580         pDSSurface                      = m_pDSSurface[0];
581     }
582 
583     // Second pass scaling
584     if (b2PassScaling)
585     {
586         dwAllocatedWidth                = pTarget->dwWidth;
587         dwAllocatedHeight               = pTarget->dwHeight;
588         VPHAL_RENDER_CHK_STATUS(AllocateSurface(pRenderParams, pSource, m_pDSSurface[1], dwAllocatedWidth, dwAllocatedHeight, pSource->Format));
589         rectScalingRegion               = pSource->rcDst;
590         m_pDSSurface[0]->rcDst          = rectScalingRegion;
591         m_pDSSurface[1]->rcDst          = rectScalingRegion;
592 
593         inputSurface                    = *m_pDSSurface[0];
594         inputSurface.p3DLutParams       = nullptr;
595         renderParams.pSrc[0]            = &inputSurface;
596         renderParams.pTarget[0]         = m_pDSSurface[1];
597         VPHAL_RENDER_CHK_STATUS(RenderPass(&renderParams));
598         m_pDSSurface[1]->rcSrc           = m_pDSSurface[1]->rcDst;
599         m_pDSSurface[1]->rcMaxSrc        = m_pDSSurface[1]->rcDst;
600         m_pDSSurface[1]->rcDst           = pSource->rcDst;
601         pDSSurface                       = m_pDSSurface[1];
602     }
603 
604     // Attach 3DLUT parameters to the down scaled surface.
605     if (pSource->p3DLutParams)
606     {
607         if (pDSSurface->p3DLutParams == nullptr)
608         {
609             pDSSurface->p3DLutParams = (PVPHAL_3DLUT_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_3DLUT_PARAMS));
610             VPHAL_RENDER_CHK_NULL(pDSSurface->p3DLutParams);
611         }
612         MOS_SecureMemcpy(pDSSurface->p3DLutParams, sizeof(VPHAL_3DLUT_PARAMS), pSource->p3DLutParams, sizeof(VPHAL_3DLUT_PARAMS));
613     }
614     else
615     {
616         MOS_FreeMemory(pDSSurface->p3DLutParams);
617         pDSSurface->p3DLutParams = nullptr;
618     }
619 
620     pRenderParams->pSrc[0]  = pDSSurface;
621 
622 finish:
623     return eStatus;
624 }
625