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