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