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