1 /*
2 * Copyright (c) 2009-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.cpp
24 //! \brief Vphal Interface Definition
25 //! \details Vphal Interface Definition Including:
26 //! const and function
27 //!
28 #include "vphal.h"
29 #include "mos_os.h"
30 #include "mos_interface.h"
31 #include "mhw_vebox.h"
32 #include "renderhal_legacy.h"
33 #include "vphal_renderer.h"
34 #include "mos_solo_generic.h"
35 #include "media_interfaces_vphal.h"
36 #include "media_interfaces_mhw.h"
37 #include "mhw_vebox_itf.h"
38 #include "mos_oca_rtlog_mgr.h"
39 #include "vp_user_setting.h"
40
41 //!
42 //! \brief Allocate VPHAL Resources
43 //! \details Allocate VPHAL Resources
44 //! - Allocate and initialize HW states
45 //! - Allocate and initialize renderer states
46 //! \param [in] pVpHalSettings
47 //! Pointer to VPHAL Settings
48 //! \return MOS_STATUS
49 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
50 //!
Allocate(const VphalSettings * pVpHalSettings)51 MOS_STATUS VphalState::Allocate(
52 const VphalSettings *pVpHalSettings)
53 {
54 MHW_VEBOX_GPUNODE_LIMIT GpuNodeLimit;
55 RENDERHAL_SETTINGS_LEGACY RenderHalSettings;
56 MOS_GPU_NODE VeboxGpuNode;
57 MOS_GPU_CONTEXT VeboxGpuContext;
58 bool checkGpuCtxOverwriten = false;
59 bool addGpuCtxToCheckList = false;
60 MOS_STATUS eStatus;
61
62 VPHAL_PUBLIC_CHK_NULL(m_osInterface);
63 VPHAL_PUBLIC_CHK_NULL(pVpHalSettings);
64 VPHAL_PUBLIC_CHK_NULL(m_renderHal);
65
66 m_clearVideoViewMode = pVpHalSettings->clearVideoViewMode;
67
68 if ((MEDIA_IS_SKU(m_skuTable, FtrVERing) ||
69 MEDIA_IS_SKU(m_skuTable, FtrSFCPipe)) &&
70 !m_clearVideoViewMode)
71 {
72 MhwInterfaces * mhwInterfaces = nullptr;
73 MhwInterfaces::CreateParams params;
74 MOS_ZeroMemory(¶ms, sizeof(params));
75 params.Flags.m_sfc = MEDIA_IS_SKU(m_skuTable, FtrSFCPipe);
76 params.Flags.m_vebox = MEDIA_IS_SKU(m_skuTable, FtrVERing);
77
78 mhwInterfaces = MhwInterfaces::CreateFactory(params, m_osInterface);
79 if (mhwInterfaces)
80 {
81 SetMhwVeboxInterface(mhwInterfaces->m_veboxInterface);
82 SetMhwSfcInterface(mhwInterfaces->m_sfcInterface);
83
84 // MhwInterfaces always create CP and MI interfaces, so we have to delete those we don't need.
85 MOS_Delete(mhwInterfaces->m_miInterface);
86 m_osInterface->pfnDeleteMhwCpInterface(mhwInterfaces->m_cpInterface);
87 mhwInterfaces->m_cpInterface = nullptr;
88 MOS_Delete(mhwInterfaces);
89 }
90 else
91 {
92 VPHAL_DEBUG_ASSERTMESSAGE("Allocate MhwInterfaces failed");
93 eStatus = MOS_STATUS_NO_SPACE;
94 MT_ERR1(MT_VP_HAL_INIT, MT_CODE_LINE, __LINE__);
95 }
96 }
97
98 if (IsApoEnabled() &&
99 m_osInterface->apoMosEnabled &&
100 m_osInterface->bSetHandleInvalid)
101 {
102 checkGpuCtxOverwriten = true;
103 }
104 addGpuCtxToCheckList = checkGpuCtxOverwriten && !IsGpuContextReused(m_renderGpuContext);
105
106 if (IsRenderContextBasedSchedulingNeeded())
107 {
108 Mos_SetVirtualEngineSupported(m_osInterface, true);
109 m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
110 }
111
112 // Create Render GPU Context
113 {
114 MOS_GPUCTX_CREATOPTIONS_ENHANCED createOption = {};
115 VPHAL_PUBLIC_CHK_STATUS(m_osInterface->pfnCreateGpuContext(
116 m_osInterface,
117 m_renderGpuContext,
118 m_renderGpuNode,
119 &createOption));
120 }
121
122 // Set current GPU context
123 VPHAL_PUBLIC_CHK_STATUS(m_osInterface->pfnSetGpuContext(
124 m_osInterface,
125 m_renderGpuContext));
126
127 // Add gpu context entry, including stream 0 gpu contexts
128 // In legacy path, stream 0 gpu contexts could be reused, and will keep these stream 0 gpu contexts alive
129 // But its mapping relation could be overwritten in APO path
130 // Now, don't reuse these stream 0 gpu contexts overwritten by MediaContext in APO path
131 // Can not add reused GPU context
132 if (addGpuCtxToCheckList)
133 {
134 AddGpuContextToCheckList(m_renderGpuContext);
135 }
136
137 // Register Render GPU context with the event
138 VPHAL_PUBLIC_CHK_STATUS(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
139 m_osInterface,
140 m_renderGpuContext));
141
142 if (MEDIA_IS_SKU(m_skuTable, FtrVERing) && m_veboxInterface && !m_clearVideoViewMode)
143 {
144 GpuNodeLimit.bSfcInUse = MEDIA_IS_SKU(m_skuTable, FtrSFCPipe);
145
146 if (m_veboxItf)
147 {
148 // Check GPU Node decide logic together in this function
149 VPHAL_HW_CHK_STATUS(m_veboxItf->FindVeboxGpuNodeToUse(&GpuNodeLimit));
150
151 VeboxGpuNode = (MOS_GPU_NODE)(GpuNodeLimit.dwGpuNodeToUse);
152 VeboxGpuContext = (VeboxGpuNode == MOS_GPU_NODE_VE) ? MOS_GPU_CONTEXT_VEBOX : MOS_GPU_CONTEXT_VEBOX2;
153
154 VPHAL_PUBLIC_CHK_STATUS(m_veboxItf->CreateGpuContext(
155 m_osInterface,
156 VeboxGpuContext,
157 VeboxGpuNode));
158 }
159
160 // Check GPU Node decide logic together in this function
161 VPHAL_HW_CHK_STATUS(m_veboxInterface->FindVeboxGpuNodeToUse(&GpuNodeLimit));
162
163 VeboxGpuNode = (MOS_GPU_NODE)(GpuNodeLimit.dwGpuNodeToUse);
164 VeboxGpuContext = (VeboxGpuNode == MOS_GPU_NODE_VE) ? MOS_GPU_CONTEXT_VEBOX : MOS_GPU_CONTEXT_VEBOX2;
165
166 addGpuCtxToCheckList = checkGpuCtxOverwriten && !IsGpuContextReused(VeboxGpuContext);
167
168 // Create VEBOX/VEBOX2 Context
169 VPHAL_PUBLIC_CHK_STATUS(m_veboxInterface->CreateGpuContext(
170 m_osInterface,
171 VeboxGpuContext,
172 VeboxGpuNode));
173
174 // Add gpu context entry, including stream 0 gpu contexts
175 if (addGpuCtxToCheckList)
176 {
177 AddGpuContextToCheckList(VeboxGpuContext);
178 }
179
180 // Register Vebox GPU context with the Batch Buffer completion event
181 // Ignore if creation fails
182 VPHAL_PUBLIC_CHK_STATUS(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
183 m_osInterface,
184 MOS_GPU_CONTEXT_VEBOX));
185 }
186
187 // Allocate and initialize HW states
188 RenderHalSettings.iMediaStates = pVpHalSettings->mediaStates;
189 VPHAL_PUBLIC_CHK_STATUS(m_renderHal->pfnInitialize(m_renderHal, &RenderHalSettings));
190
191 if (!m_clearVideoViewMode)
192 {
193 if (m_veboxItf)
194 {
195 const MHW_VEBOX_HEAP *veboxHeap = nullptr;
196 m_veboxItf->GetVeboxHeapInfo(&veboxHeap);
197 uint32_t uiNumInstances = m_veboxItf->GetVeboxNumInstances();
198
199 if (uiNumInstances > 0 &&
200 veboxHeap == nullptr)
201 {
202 // Allocate VEBOX Heap
203 VPHAL_PUBLIC_CHK_STATUS(m_veboxItf->CreateHeap());
204 }
205 }
206
207 if (m_veboxInterface &&
208 m_veboxInterface->m_veboxSettings.uiNumInstances > 0 &&
209 m_veboxInterface->m_veboxHeap == nullptr)
210 {
211 VPHAL_PUBLIC_CHK_STATUS(m_veboxInterface->CreateHeap());
212 }
213 }
214
215 // Create renderer
216 VPHAL_RENDER_CHK_STATUS(CreateRenderer());
217
218 // Allocate and initialize renderer states
219 VPHAL_PUBLIC_CHK_STATUS(m_renderer->Initialize(pVpHalSettings, IsApoEnabled()));
220
221 finish:
222 return eStatus;
223 }
224
225 //!
226 //! \brief Check if need to apply AVS for specified surface
227 //! \details Check if need to apply AVS for specified surface
228 //! \param pSurf
229 //! [in] Pointer to VPHAL_SURFACE
230 //! \return bool
231 //! Return true if the input surface needs AVS scaling
232 //!
IsSurfNeedAvs(PVPHAL_SURFACE pSurf)233 static bool IsSurfNeedAvs(
234 PVPHAL_SURFACE pSurf)
235 {
236 VPHAL_PUBLIC_CHK_NULL_NO_STATUS(pSurf);
237
238 // Not perform AVS for surface with alpha channel.
239 if (IS_ALPHA_YUV_FORMAT(pSurf->Format))
240 {
241 return false;
242 }
243
244 if (pSurf->SurfType == SURF_IN_PRIMARY ||
245 pSurf->SurfType == SURF_IN_SUBSTREAM)
246 {
247 if (pSurf->pBlendingParams)
248 {
249 return false;
250 }
251
252 if (IS_YUV_FORMAT(pSurf->Format))
253 {
254 // Not perform AVS for surface with VPHAL_SCALING_NEAREST
255 // or VPHAL_SCALING_BILINEAR scaling mode.
256 if (pSurf->ScalingMode == VPHAL_SCALING_AVS ||
257 pSurf->ScalingMode == VPHAL_SCALING_ADV_QUALITY)
258 {
259 return true;
260 }
261 }
262 }
263 finish:
264 return false;
265 }
266
267 //!
268 //! \brief Check if all surfaces format order in pcRenderParams is suitable to enable multiple avs rendering (YUV is prior than RGB)
269 //! \details In VpHal_RenderWithAvsForMultiStreams() we group YUV surfaces in phase one and the others in phase two.
270 //! However, if there are 2+ overlapped source surfaces, e.g., pSrc[0]=B8G8R8A8 and pSrc[1]=NV12.
271 //! We don't enable multiple avs rendering for such case since we expect pSrc[1] is above pSrc[0] on target.
272 //! If multiple avs rendering is enabled, the compositing order is reverse and turns out pSrc[1] is below pSrc[0],
273 //! which is the case need to prevent.
274 //! \param pcRenderParams
275 //! [in] Pointer to const VPHAL_RENDER_PARAMS
276 //! \return bool
277 //! Allow to enable multiple avs rendering
278 //!
IsYuvPriorRgbInCompositeOrder(PCVPHAL_RENDER_PARAMS pcRenderParams)279 static bool IsYuvPriorRgbInCompositeOrder(
280 PCVPHAL_RENDER_PARAMS pcRenderParams)
281 {
282 bool bHasRgbSurface = false;
283 uint32_t uiLastYuvIdx = 0;
284 uint32_t uiFirstRgbIdx = 0;
285 uint32_t iSourceIdx;
286
287 VPHAL_PUBLIC_CHK_NULL_NO_STATUS(pcRenderParams);
288
289 for (iSourceIdx = 0; iSourceIdx < pcRenderParams->uSrcCount; iSourceIdx++)
290 {
291 PVPHAL_SURFACE pSurf = pcRenderParams->pSrc[iSourceIdx];
292 if (IsSurfNeedAvs(pSurf))
293 {
294 uiLastYuvIdx = iSourceIdx;
295 }
296 else if (!bHasRgbSurface)
297 {
298 bHasRgbSurface = true;
299 uiFirstRgbIdx = iSourceIdx;
300 }
301 }
302
303 finish:
304 if (!bHasRgbSurface)
305 { // return true if not contain any RGB surface
306 return true;
307 }
308 return (uiLastYuvIdx < uiFirstRgbIdx);
309 }
310
311 //!
312 //! \brief Check if need to apply AVS scaling for multiple surfaces
313 //! \details Check if need to apply AVS scaling for multiple surfaces
314 //! \param pcRenderParams
315 //! [in] Pointer to const VPHAL_RENDER_PARAMS
316 //! \return bool
317 //! Return true if neeeded to enable AVS for all primary surfaces.
318 //!
VpHal_IsAvsSampleForMultiStreamsEnabled(PCVPHAL_RENDER_PARAMS pcRenderParams)319 static bool VpHal_IsAvsSampleForMultiStreamsEnabled(
320 PCVPHAL_RENDER_PARAMS pcRenderParams)
321 {
322 uint32_t uSourceIdx;
323 uint32_t uSourceBIdx;
324 uint32_t uAvsSurfaceCnt = 0;
325 bool bEnableAvsForMultiSurface = false;
326
327 VPHAL_PUBLIC_CHK_NULL_NO_STATUS(pcRenderParams);
328
329 //disable if only one, zero or invalid number source
330 if (pcRenderParams->uSrcCount <= 1 ||
331 pcRenderParams->uSrcCount > VPHAL_MAX_SOURCES)
332 {
333 goto finish;
334 }
335
336 for (uSourceIdx = 0; uSourceIdx < pcRenderParams->uSrcCount; uSourceIdx++)
337 {
338 PVPHAL_SURFACE pSrcSurf = pcRenderParams->pSrc[uSourceIdx];
339 if (pSrcSurf && pSrcSurf->SurfType == SURF_IN_PRIMARY)
340 {
341 // VPHAL_SCALING_PREFER_SFC_FOR_VEBOX means scaling mode is FastMode, don't apply AVS for multiples
342 if (pSrcSurf->ScalingPreference == VPHAL_SCALING_PREFER_SFC_FOR_VEBOX)
343 {
344 goto finish;
345 }
346
347 if (!IS_YUV_FORMAT(pSrcSurf->Format))
348 {
349 goto finish;
350 }
351
352 // disabled if need denoise or deinterlace
353 if (pSrcSurf->pDenoiseParams || pSrcSurf->pDeinterlaceParams)
354 {
355 goto finish;
356 }
357
358 if (0 < pSrcSurf->uFwdRefCount || 0 < pSrcSurf->uBwdRefCount)
359 {
360 goto finish;
361 }
362 }
363 if (pSrcSurf && IsSurfNeedAvs(pSrcSurf))
364 {
365 uAvsSurfaceCnt++;
366 }
367 }
368
369 if (uAvsSurfaceCnt <= 1)
370 {
371 goto finish;
372 }
373
374 if (!IsYuvPriorRgbInCompositeOrder(pcRenderParams))
375 {
376 goto finish;
377 }
378
379 // disable if any AVS surface overlay to other AVS surface.
380 for (uSourceIdx = 0; uSourceIdx < pcRenderParams->uSrcCount; uSourceIdx++)
381 {
382 PVPHAL_SURFACE pSrcSurfA = pcRenderParams->pSrc[uSourceIdx];
383 if (pSrcSurfA && IsSurfNeedAvs(pSrcSurfA))
384 {
385 for (uSourceBIdx = uSourceIdx + 1; uSourceBIdx < pcRenderParams->uSrcCount; uSourceBIdx++)
386 {
387 PVPHAL_SURFACE pSrcSurfB = pcRenderParams->pSrc[uSourceBIdx];
388 if (pSrcSurfB && IsSurfNeedAvs(pSrcSurfB) &&
389 !RECT1_OUTSIDE_RECT2(pSrcSurfA->rcDst, pSrcSurfB->rcDst)) // not outside means overlay
390 {
391 goto finish;
392 }
393 }
394 }
395 }
396
397 bEnableAvsForMultiSurface = true;
398 finish:
399 return bEnableAvsForMultiSurface;
400 }
401
402 //!
403 //! \brief Rendering with AVS scaling for multiple surfaces
404 //! \details Rendering with AVS scaling for multiple surfaces
405 //! Currently composition kernel only allows first primary surface with AVS.
406 //! To apply AVS for multiple surfaces, this function do the following steps:
407 //! (1) separating each AVS surface into different phases containing only one primary
408 //! (2) rendering with individual primary, and let first pass with color filler
409 //! (3) rendering remaining non-AVS substreams, if any, with intermediate surface in one phase to allow alpha blending.
410 //! \param pRenderer
411 //! [in] Pointer to VphalRenderer
412 //! \param pcRenderParams
413 //! [in] Pointer to const VPHAL_RENDER_PARAMS
414 //! \return MOS_STATUS
415 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
416 //!
VpHal_RenderWithAvsForMultiStreams(VphalRenderer * pRenderer,PCVPHAL_RENDER_PARAMS pcRenderParams)417 static MOS_STATUS VpHal_RenderWithAvsForMultiStreams(
418 VphalRenderer *pRenderer,
419 PCVPHAL_RENDER_PARAMS pcRenderParams)
420 {
421 uint32_t uSourceIdx;
422 VPHAL_RENDER_PARAMS RenderParams;
423 VPHAL_COLORFILL_PARAMS colorFillForFirstRenderPass;
424 bool bColorFillForFirstRender;
425 bool bHasNonAvsSubstream;
426 MOS_STATUS eStatusSingleRender;
427 PVPHAL_SURFACE pIntermediateSurface;
428 PVPHAL_SURFACE pBackGroundSurface;
429 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
430 VPHAL_SCALING_PREFERENCE ePrimaryScalingPreference = VPHAL_SCALING_PREFER_SFC;
431 VPHAL_RENDER_PARAMS *pRenderParams;
432
433 VPHAL_PUBLIC_CHK_NULL(pRenderer);
434 VPHAL_PUBLIC_CHK_NULL(pRenderer->GetOsInterface());
435 VPHAL_PUBLIC_CHK_NULL(pcRenderParams);
436 VPHAL_PUBLIC_CHK_NULL(pcRenderParams->pTarget[0]);
437
438 pRenderParams =
439 (VPHAL_RENDER_PARAMS*)pcRenderParams;
440
441 if (pcRenderParams->pColorFillParams)
442 {
443 colorFillForFirstRenderPass = *pcRenderParams->pColorFillParams;
444 }
445 else
446 {
447 colorFillForFirstRenderPass.bYCbCr = false;
448 colorFillForFirstRenderPass.Color = 0;
449 colorFillForFirstRenderPass.CSpace = CSpace_sRGB;
450 }
451
452 pIntermediateSurface = &pRenderer->IntermediateSurface;
453
454 // check if having non-AVS substream
455 bHasNonAvsSubstream = false;
456 pBackGroundSurface = nullptr;
457 for (uSourceIdx = 0; uSourceIdx < pcRenderParams->uSrcCount; uSourceIdx++)
458 {
459 PVPHAL_SURFACE pSurf = (PVPHAL_SURFACE)pcRenderParams->pSrc[uSourceIdx];
460 if (pSurf && pSurf->SurfType == SURF_IN_SUBSTREAM)
461 {
462 if (!IS_YUV_FORMAT(pSurf->Format))
463 {
464 bHasNonAvsSubstream = true;
465 }
466 }
467
468 if (pSurf && pSurf->SurfType == SURF_IN_BACKGROUND)
469 {
470 pBackGroundSurface = pSurf;
471 }
472
473 // keep scaling preference of primary for later usage
474 if (pSurf && pSurf->SurfType == SURF_IN_PRIMARY)
475 {
476 ePrimaryScalingPreference = pSurf->ScalingPreference;
477 }
478 }
479
480 // create an intermediate surface if having non-AVS substream, as phase 1 output and phase 2 input.
481 if (bHasNonAvsSubstream)
482 {
483 bool bAllocated;
484 uint32_t dwTempWidth = pcRenderParams->pTarget[0]->dwWidth;
485 uint32_t dwTempHeight = pcRenderParams->pTarget[0]->dwHeight;
486
487 // Allocate/Reallocate temporary output
488 if (dwTempWidth > pRenderer->IntermediateSurface.dwWidth ||
489 dwTempHeight > pRenderer->IntermediateSurface.dwHeight)
490 {
491 dwTempWidth = MOS_MAX(dwTempWidth , pRenderer->IntermediateSurface.dwWidth);
492 dwTempHeight = MOS_MAX(dwTempHeight, pRenderer->IntermediateSurface.dwHeight);
493 dwTempWidth = MOS_ALIGN_CEIL(dwTempWidth , VPHAL_BUFFER_SIZE_INCREMENT);
494 dwTempHeight = MOS_ALIGN_CEIL(dwTempHeight, VPHAL_BUFFER_SIZE_INCREMENT);
495
496 eStatusSingleRender = VpHal_ReAllocateSurface(
497 pRenderer->GetOsInterface(),
498 &pRenderer->IntermediateSurface,
499 "RenderIntermediateSurface",
500 pcRenderParams->pTarget[0]->Format,
501 MOS_GFXRES_2D,
502 pcRenderParams->pTarget[0]->TileType,
503 dwTempWidth,
504 dwTempHeight,
505 false,
506 MOS_MMC_DISABLED,
507 &bAllocated);
508
509 if (MOS_SUCCEEDED(eStatusSingleRender))
510 {
511 pIntermediateSurface->SurfType = SURF_IN_PRIMARY;
512 pIntermediateSurface->SampleType = SAMPLE_PROGRESSIVE;
513 pIntermediateSurface->ColorSpace = pcRenderParams->pTarget[0]->ColorSpace;
514 pIntermediateSurface->ExtendedGamut = pcRenderParams->pTarget[0]->ExtendedGamut;
515 pIntermediateSurface->rcSrc = pcRenderParams->pTarget[0]->rcSrc;
516 pIntermediateSurface->rcDst = pcRenderParams->pTarget[0]->rcDst;
517 pIntermediateSurface->ScalingMode = VPHAL_SCALING_AVS;
518 pIntermediateSurface->bIEF = false;
519 }
520 else
521 {
522 eStatus = eStatusSingleRender;
523 bHasNonAvsSubstream = false;
524 VPHAL_PUBLIC_ASSERTMESSAGE("Failed to create intermediate surface, eStatus: %d.\n", eStatus);
525 MT_ERR1(MT_VP_HAL_REALLOC_SURF, MT_CODE_LINE, __LINE__);
526 }
527 }
528 }
529
530 // phase 1: render each AVS surface in separated pass
531 bColorFillForFirstRender = true;
532 RenderParams = *pRenderParams;
533 RenderParams.uDstCount = 1;
534 MOS_ZeroMemory(RenderParams.pSrc, sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
535
536 for (uSourceIdx = 0; uSourceIdx < pcRenderParams->uSrcCount; uSourceIdx++)
537 {
538 VPHAL_SURFACE SinglePassSource;
539 PVPHAL_SURFACE pSurf = (PVPHAL_SURFACE)pcRenderParams->pSrc[uSourceIdx];
540 RenderParams.uSrcCount = 0;
541
542 if (pSurf && IsSurfNeedAvs(pSurf))
543 {
544 SinglePassSource = *(pSurf);
545 SinglePassSource.SurfType = SURF_IN_PRIMARY;
546 SinglePassSource.ScalingMode = VPHAL_SCALING_AVS;
547 SinglePassSource.ScalingPreference = ePrimaryScalingPreference;
548
549 RenderParams.pTarget[0] = (bHasNonAvsSubstream ? pIntermediateSurface : pcRenderParams->pTarget[0]);
550
551 if (bColorFillForFirstRender) // apply color-fill for the first rendering
552 {
553 bColorFillForFirstRender = false;
554 RenderParams.pColorFillParams = &colorFillForFirstRenderPass;
555
556 if (pBackGroundSurface)
557 {
558 RenderParams.pSrc[RenderParams.uSrcCount] = pBackGroundSurface;
559 RenderParams.uSrcCount++;
560 }
561 }
562 else if (!bColorFillForFirstRender && SinglePassSource.pLumaKeyParams) // colorfill is needed if lumakey enabled on a single pass
563 {
564 RenderParams.pColorFillParams = &colorFillForFirstRenderPass;
565 RenderParams.pTarget[0]->rcDst = SinglePassSource.rcDst;
566 }
567 else
568 {
569 RenderParams.pTarget[0]->rcDst = SinglePassSource.rcDst;
570 RenderParams.pColorFillParams = nullptr;
571 }
572
573 RenderParams.pSrc[RenderParams.uSrcCount] = &SinglePassSource;
574 RenderParams.uSrcCount++;
575
576 // continue the next pfnRender even if single pass failed, but return eStatus failed.
577 eStatusSingleRender = pRenderer->Render((PCVPHAL_RENDER_PARAMS)(&RenderParams));
578 if (MOS_FAILED(eStatusSingleRender))
579 {
580 eStatus = eStatusSingleRender;
581 VPHAL_PUBLIC_ASSERTMESSAGE("Failed to redner for primary streams, eStatus: %d.\n", eStatus);
582 MT_ERR2(MT_VP_HAL_RENDER, MT_ERROR_CODE, eStatus, MT_CODE_LINE, __LINE__);
583 }
584 }
585 }
586
587 // phase 2: if having non-AVS substream, render them with previous output in one pass.
588 if (bHasNonAvsSubstream)
589 {
590 RenderParams = *pRenderParams;
591 MOS_ZeroMemory(RenderParams.pSrc, sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
592
593 pIntermediateSurface->rcSrc = pcRenderParams->pTarget[0]->rcSrc;
594 pIntermediateSurface->rcDst = pcRenderParams->pTarget[0]->rcDst;
595 RenderParams.pSrc[0] = pIntermediateSurface;
596 RenderParams.uSrcCount = 1;
597 RenderParams.uDstCount = 1;
598
599 for (uSourceIdx = 0; uSourceIdx < pcRenderParams->uSrcCount; uSourceIdx++)
600 {
601 PVPHAL_SURFACE pSurf = pcRenderParams->pSrc[uSourceIdx];
602 bool bIsSurfForPhase2 = (pSurf &&
603 (!IsSurfNeedAvs(pSurf)) &&
604 (pSurf->SurfType != SURF_IN_BACKGROUND));
605 if (bIsSurfForPhase2)
606 {
607 RenderParams.pSrc[RenderParams.uSrcCount] = pSurf;
608 RenderParams.uSrcCount++;
609 }
610 }
611
612 eStatusSingleRender = pRenderer->Render((PCVPHAL_RENDER_PARAMS)(&RenderParams));
613 if (MOS_FAILED(eStatusSingleRender))
614 {
615 eStatus = eStatusSingleRender;
616 VPHAL_PUBLIC_ASSERTMESSAGE("Failed to redner for substreams, eStatus: %d.\n", eStatus);
617 MT_ERR2(MT_VP_HAL_RENDER, MT_ERROR_CODE, eStatus, MT_CODE_LINE, __LINE__);
618 }
619 }
620
621 finish:
622 return eStatus;
623 }
624
625 //!
626 //! \brief Performs VP Rendering
627 //! \details Performs VP Rendering
628 //! - call default render of video
629 //! \param [in] pcRenderParams
630 //! Pointer to Render Params
631 //! \return MOS_STATUS
632 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
633 //!
Render(PCVPHAL_RENDER_PARAMS pcRenderParams)634 MOS_STATUS VphalState::Render(
635 PCVPHAL_RENDER_PARAMS pcRenderParams)
636 {
637 MOS_STATUS eStatus;
638 VPHAL_RENDER_PARAMS RenderParams;
639
640 VPHAL_PUBLIC_CHK_NULL(pcRenderParams);
641 RenderParams = *pcRenderParams;
642
643 // Explicitly initialize the maxSrcRect of VphalRenderer
644 // so that the maxSrcRect for the last set of surfaces does not get
645 // re-used for the current set of surfaces.
646 m_renderer->InitMaxSrcRect();
647
648 if (VpHal_IsAvsSampleForMultiStreamsEnabled(pcRenderParams))
649 {
650 eStatus = VpHal_RenderWithAvsForMultiStreams(m_renderer, pcRenderParams);
651 goto finish;
652 }
653
654 // default render of video
655 RenderParams.bIsDefaultStream = true;
656 eStatus = m_renderer->Render((PCVPHAL_RENDER_PARAMS)(&RenderParams));
657
658 finish:
659 return eStatus;
660 }
661
662 //!
663 //! \brief Get feature reporting from renderer
664 //! \details Get feature reporting from renderer
665 //! \return VphalFeatureReport*
666 //! Pointer to VphalFeatureReport: rendering features reported
667 //!
GetRenderFeatureReport()668 VphalFeatureReport* VphalState::GetRenderFeatureReport()
669 {
670 VPHAL_PUBLIC_ASSERT(m_renderer);
671
672 return m_renderer->GetReport();
673 }
674
675 //!
676 //! \brief VphalState Constructor
677 //! \details Creates instance of VphalState
678 //! - Return pointer to initialized VPHAL state, but not yet fully allocated
679 //! - Caller must call pfnAllocate to allocate all VPHAL states and objects.
680 //! \param [in] pOsInterface
681 //! OS interface, if provided externally - may be nullptr
682 //! \param [in,out] peStatus
683 //! Pointer to the MOS_STATUS flag.
684 //! Will assign this flag to MOS_STATUS_SUCCESS if successful, otherwise failed
685 //!
VphalState(PMOS_INTERFACE pOsInterface,MOS_STATUS * peStatus)686 VphalState::VphalState(
687 PMOS_INTERFACE pOsInterface,
688 MOS_STATUS *peStatus) :
689 m_platform(),
690 m_skuTable(nullptr),
691 m_waTable(nullptr),
692 m_osInterface(pOsInterface),
693 m_renderHal(nullptr),
694 m_veboxInterface(nullptr),
695 m_cpInterface(nullptr),
696 m_sfcInterface(nullptr),
697 m_renderer(nullptr),
698 m_renderGpuNode(MOS_GPU_NODE_3D),
699 m_renderGpuContext(MOS_GPU_CONTEXT_RENDER)
700 {
701 MOS_STATUS eStatus;
702
703 eStatus = MOS_STATUS_UNKNOWN;
704
705 VPHAL_PUBLIC_CHK_NULL(m_osInterface);
706
707 // Initialize platform, sku, wa tables
708 m_osInterface->pfnGetPlatform(m_osInterface, &m_platform);
709 m_skuTable = m_osInterface->pfnGetSkuTable(m_osInterface);
710 m_waTable = m_osInterface->pfnGetWaTable (m_osInterface);
711
712 m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
713 VpUserSetting::InitVpUserSetting(m_userSettingPtr);
714
715 m_renderHal = (PRENDERHAL_INTERFACE_LEGACY)MOS_AllocAndZeroMemory(sizeof(RENDERHAL_INTERFACE_LEGACY));
716 VPHAL_PUBLIC_CHK_NULL(m_renderHal);
717 VPHAL_PUBLIC_CHK_STATUS(RenderHal_InitInterface_Legacy(
718 m_renderHal,
719 &m_cpInterface,
720 m_osInterface));
721
722 finish:
723 if(peStatus)
724 {
725 *peStatus = eStatus;
726 }
727 }
728
729 //!
730 //! \brief Vphal Destructor
731 //! \details Destroys VPHAL and all internal states and objects
732 //! \return void
733 //!
~VphalState()734 VphalState::~VphalState()
735 {
736 MOS_STATUS eStatus;
737
738 // Wait for all cmd before destroy gpu resource
739 if (m_osInterface && m_osInterface->pfnWaitAllCmdCompletion && m_osInterface->bDeallocateOnExit)
740 {
741 VP_PUBLIC_NORMALMESSAGE("WaitAllCmdCompletion in VphalState::~VphalState");
742 m_osInterface->pfnWaitAllCmdCompletion(m_osInterface);
743 }
744
745 // Destroy rendering objects (intermediate surfaces, BBs, etc)
746 if (m_renderer)
747 {
748 MOS_Delete(m_renderer);
749 m_renderer = nullptr;
750 }
751
752 if (m_renderHal)
753 {
754 if (m_renderHal->pfnDestroy)
755 {
756 eStatus = m_renderHal->pfnDestroy(m_renderHal);
757 if (eStatus != MOS_STATUS_SUCCESS)
758 {
759 VPHAL_PUBLIC_ASSERTMESSAGE("Failed to destroy RenderHal, eStatus:%d.\n", eStatus);
760 MT_ERR1(MT_VP_HAL_DESTROY, MT_CODE_LINE, __LINE__);
761 }
762 }
763 MOS_FreeMemory(m_renderHal);
764 }
765
766 if (m_cpInterface)
767 {
768 if (m_osInterface)
769 {
770 m_osInterface->pfnDeleteMhwCpInterface(m_cpInterface);
771 m_cpInterface = nullptr;
772 }
773 else
774 {
775 VPHAL_PUBLIC_ASSERTMESSAGE("Failed to destroy cpInterface.");
776 }
777 }
778
779 if (m_sfcInterface)
780 {
781 MOS_Delete(m_sfcInterface);
782 m_sfcInterface = nullptr;
783 }
784
785 if (m_veboxInterface)
786 {
787 if (m_veboxItf)
788 {
789 eStatus = m_veboxItf->DestroyHeap();
790 if (eStatus != MOS_STATUS_SUCCESS)
791 {
792 VPHAL_PUBLIC_ASSERTMESSAGE("Failed to destroy Vebox Interface, eStatus:%d.\n", eStatus);
793 MT_ERR1(MT_VP_HAL_DESTROY, MT_CODE_LINE, __LINE__);
794 }
795 }
796
797 eStatus = m_veboxInterface->DestroyHeap();
798 MOS_Delete(m_veboxInterface);
799 m_veboxInterface = nullptr;
800 m_veboxItf = nullptr;
801 if (eStatus != MOS_STATUS_SUCCESS)
802 {
803 VPHAL_PUBLIC_ASSERTMESSAGE("Failed to destroy Vebox Interface, eStatus:%d.\n", eStatus);
804 MT_ERR1(MT_VP_HAL_DESTROY, MT_CODE_LINE, __LINE__);
805 }
806 }
807
808 // Destroy OS interface objects (CBs, etc)
809 if (m_osInterface)
810 {
811 if (m_osInterface->bDeallocateOnExit)
812 {
813 //Clear some overwriten gpucontext resources
814 if (!m_gpuContextCheckList.empty())
815 {
816 DestroyGpuContextWithInvalidHandle();
817 m_gpuContextCheckList.clear();
818 }
819
820 m_osInterface->pfnDestroy(m_osInterface, true);
821
822 // Deallocate OS interface structure (except if externally provided)
823 MOS_FreeMemory(m_osInterface);
824 }
825 }
826 }
827
VphalStateFactory(PMOS_INTERFACE pOsInterface,PMOS_CONTEXT pOsDriverContext,MOS_STATUS * peStatus)828 VphalState* VphalState::VphalStateFactory(
829 PMOS_INTERFACE pOsInterface,
830 PMOS_CONTEXT pOsDriverContext,
831 MOS_STATUS *peStatus)
832 {
833 VphalState* vphalState = dynamic_cast<VphalState*>(VphalDevice::CreateFactory(pOsInterface, pOsDriverContext, peStatus));
834 if(nullptr == vphalState)
835 {
836 VPHAL_PUBLIC_ASSERTMESSAGE("vphal state pointer is nullptr");
837 *peStatus = MOS_STATUS_NULL_POINTER;
838 }
839 return vphalState;
840 }
841
842 //!
843 //! \brief Get Status Report
844 //! \details Get Status Report, will return back to app indicating if related frame id is done by gpu
845 //! \param [out] pQueryReport
846 //! Pointer to pQueryReport, the status query report array.
847 //! \param [in] wStatusNum
848 //! The size of array pQueryReport.
849 //! \return MOS_STATUS
850 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
GetStatusReport(PQUERY_STATUS_REPORT_APP pQueryReport,uint16_t wStatusNum)851 MOS_STATUS VphalState::GetStatusReport(
852 PQUERY_STATUS_REPORT_APP pQueryReport,
853 uint16_t wStatusNum)
854 {
855 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
856
857 #if (!EMUL) // this function is dummy for emul
858 uint32_t i;
859 uint32_t uiTableLen;
860 PVPHAL_STATUS_TABLE pStatusTable;
861 PMOS_CONTEXT pOsContext;
862 uint32_t uiIndex;
863 uint32_t uiNewHead;
864 PVPHAL_STATUS_ENTRY pStatusEntry;
865 bool bMarkNotReadyForRemains = false;
866
867 VPHAL_PUBLIC_CHK_NULL(pQueryReport);
868 VPHAL_PUBLIC_CHK_NULL(m_osInterface);
869 VPHAL_PUBLIC_CHK_NULL(m_osInterface->pOsContext);
870
871 // it should be ok if we don't consider the null render
872 // eNullRender = m_pOsInterface->pfnGetNullHWRenderFlags(m_pOsInterface);
873
874 pOsContext = m_osInterface->pOsContext;
875 pStatusTable = &m_statusTable;
876 uiNewHead = pStatusTable->uiHead; // uiNewHead start from previous head value
877 // entry length from head to tail
878 if (pStatusTable->uiCurrent < pStatusTable->uiHead)
879 {
880 uiTableLen = pStatusTable->uiCurrent + VPHAL_STATUS_TABLE_MAX_SIZE - pStatusTable->uiHead;
881 }
882 else
883 {
884 uiTableLen = pStatusTable->uiCurrent - pStatusTable->uiHead;
885 }
886
887 // step 1 - update pStatusEntry from driver if command associated with the dwTag is done by gpu
888 for (i = 0; i < wStatusNum && i < uiTableLen; i++)
889 {
890 uint32_t dwGpuTag; // hardware tag updated by gpu command pipectl
891 bool bDoneByGpu;
892 bool bFailedOnSubmitCmd;
893
894 uiIndex = (pStatusTable->uiHead + i) & (VPHAL_STATUS_TABLE_MAX_SIZE - 1);
895 pStatusEntry = &pStatusTable->aTableEntries[uiIndex];
896
897 // for tasks using CM, different streamIndexes may be used
898 uint32_t oldStreamIndex = m_osInterface->streamIndex;
899 if (pStatusEntry->isStreamIndexSet)
900 {
901 m_osInterface->streamIndex = pStatusEntry->streamIndex;
902 }
903
904 if (bMarkNotReadyForRemains)
905 {
906 // the status is set as VPREP_NOTREADY while submitting commands
907 pQueryReport[i].dwStatus = pStatusEntry->dwStatus;
908 pQueryReport[i].StatusFeedBackID = pStatusEntry->StatusFeedBackID;
909 continue;
910 }
911
912 dwGpuTag = m_osInterface->pfnGetGpuStatusSyncTag(m_osInterface, pStatusEntry->GpuContextOrdinal);
913 bDoneByGpu = (dwGpuTag >= pStatusEntry->dwTag);
914 bFailedOnSubmitCmd = (pStatusEntry->dwStatus == VPREP_ERROR);
915
916 #if (_DEBUG || _RELEASE_INTERNAL)
917 MOS_NULL_RENDERING_FLAGS NullRender = m_osInterface->pfnGetNullHWRenderFlags(m_osInterface);
918 if (NullRender.Value != 0)
919 {
920 bDoneByGpu = true;
921 }
922 #endif
923
924 if (bFailedOnSubmitCmd)
925 {
926 uiNewHead = (uiIndex + 1) & (VPHAL_STATUS_TABLE_MAX_SIZE - 1);
927 }
928 else if (bDoneByGpu)
929 {
930 pStatusEntry->dwStatus = VPREP_OK;
931 uiNewHead = (uiIndex + 1) & (VPHAL_STATUS_TABLE_MAX_SIZE - 1);
932 }
933 else
934 { // here we have the first not ready entry.
935 #if (LINUX || ANDROID)
936 uiNewHead = (uiIndex + 1) & (VPHAL_STATUS_TABLE_MAX_SIZE - 1);
937 #else
938 uiNewHead = uiIndex;
939 #endif
940
941 bMarkNotReadyForRemains = true;
942 }
943
944 if (m_osInterface->pfnIsGPUHung(m_osInterface))
945 {
946 pStatusEntry->dwStatus = VPREP_NOTREADY;
947 }
948
949 pQueryReport[i].dwStatus = pStatusEntry->dwStatus;
950 pQueryReport[i].StatusFeedBackID = pStatusEntry->StatusFeedBackID;
951
952 if (pStatusEntry->isStreamIndexSet)
953 {
954 m_osInterface->streamIndex = oldStreamIndex;
955 }
956 }
957 pStatusTable->uiHead = uiNewHead;
958 // step 2 - mark VPREP_NOTAVAILABLE for unused entry
959 for (/* continue from previous i */; i < wStatusNum; i++)
960 {
961 pQueryReport[i].dwStatus = VPREP_NOTAVAILABLE;
962 pQueryReport[i].StatusFeedBackID = 0;
963 }
964
965 finish:
966 #else
967 MOS_UNUSED(pQueryReport);
968 MOS_UNUSED(wStatusNum);
969 #endif // end (!EMUL && !ANDROID)
970 return eStatus;
971 }
972
973 //!
974 //! \brief Get Status Report's entry length from head to tail
975 //! \details Get Status Report's entry length from head to tail
976 //! \param [out] puiLength
977 //! Pointer to the entry length
978 //! \return MOS_STATUS
979 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
980 //!
GetStatusReportEntryLength(uint32_t * puiLength)981 MOS_STATUS VphalState::GetStatusReportEntryLength(
982 uint32_t* puiLength)
983 {
984 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
985 #if(!EMUL) // this function is dummy for emul
986 PVPHAL_STATUS_TABLE pStatusTable;
987
988 VPHAL_PUBLIC_CHK_NULL(puiLength);
989
990 pStatusTable = &m_statusTable;
991
992 // entry length from head to tail
993 if (pStatusTable->uiCurrent < pStatusTable->uiHead)
994 {
995 *puiLength = pStatusTable->uiCurrent + VPHAL_STATUS_TABLE_MAX_SIZE - pStatusTable->uiHead;
996 }
997 else
998 {
999 *puiLength = pStatusTable->uiCurrent - pStatusTable->uiHead;
1000 }
1001 finish:
1002 #else
1003 MOS_UNUSED(puiLength);
1004 #endif
1005 return eStatus;
1006 }
1007
GetVpMhwInterface(VP_MHWINTERFACE & vpMhwinterface)1008 MOS_STATUS VphalState::GetVpMhwInterface(
1009 VP_MHWINTERFACE &vpMhwinterface)
1010 {
1011 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1012
1013 vpMhwinterface.m_platform = m_platform;
1014 vpMhwinterface.m_waTable = m_waTable;
1015 vpMhwinterface.m_skuTable = m_skuTable;
1016 vpMhwinterface.m_osInterface = m_osInterface;
1017 vpMhwinterface.m_renderHal = m_renderHal;
1018 vpMhwinterface.m_veboxInterface = m_veboxInterface;
1019 vpMhwinterface.m_sfcInterface = m_sfcInterface;
1020 vpMhwinterface.m_cpInterface = m_cpInterface;
1021 vpMhwinterface.m_mhwMiInterface = m_renderHal->pMhwMiInterface;
1022 vpMhwinterface.m_statusTable = &m_statusTable;
1023
1024 return eStatus;
1025 }
1026
1027 //!
1028 //! \brief Put GPU context entry
1029 //! \details Put GPU context entry in the m_gpuContextCheckList
1030 //! \param MOS_GPU_CONTEXT mosGpuConext
1031 //! [in] Mos GPU context
1032 //! \return MOS_STATUS
1033 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1034 //!
AddGpuContextToCheckList(MOS_GPU_CONTEXT mosGpuConext)1035 MOS_STATUS VphalState::AddGpuContextToCheckList(
1036 MOS_GPU_CONTEXT mosGpuConext)
1037 {
1038 #if !EMUL
1039 MOS_GPU_CONTEXT originalGpuCtxOrdinal = m_osInterface->CurrentGpuContextOrdinal;
1040 if (mosGpuConext != originalGpuCtxOrdinal)
1041 {
1042 // Set GPU context temporarily
1043 VPHAL_PUBLIC_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
1044 m_osInterface,
1045 mosGpuConext));
1046 }
1047 VPHAL_GPU_CONTEXT_ENTRY tmpEntry;
1048 tmpEntry.gpuCtxForMos = mosGpuConext;
1049 tmpEntry.gpuContextHandle = m_osInterface->CurrentGpuContextHandle;
1050 tmpEntry.pGpuContext = m_osInterface->pfnGetGpuContextbyHandle(m_osInterface, m_osInterface->CurrentGpuContextHandle);
1051 m_gpuContextCheckList.push_back(tmpEntry);
1052
1053 if (mosGpuConext != originalGpuCtxOrdinal)
1054 {
1055 //Recover original settings
1056 VPHAL_PUBLIC_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
1057 m_osInterface,
1058 originalGpuCtxOrdinal));
1059 }
1060 #endif
1061
1062 return MOS_STATUS_SUCCESS;
1063 }
1064
1065 //!
1066 //! \brief Destroy GPU context entry with invalid handle
1067 //! \details Release these GPU context overwritten by MediaContext
1068 //! \return MOS_STATUS
1069 //! Return MOS_STATUS_SUCCESS if successful, otherwise failed
1070 //!
DestroyGpuContextWithInvalidHandle()1071 MOS_STATUS VphalState::DestroyGpuContextWithInvalidHandle()
1072 {
1073 #if !EMUL
1074 MOS_GPU_CONTEXT originalGpuCtxOrdinal = m_osInterface->CurrentGpuContextOrdinal;
1075 for (auto &curGpuEntry : m_gpuContextCheckList)
1076 {
1077 //Failure in switching GPU Context indicates that we can't find and release gpu context in normal flow later
1078 //So if failed to switch GPU Context, just need to check GPU context, and release it here
1079 //If switch GPU Context successfully, need to check both handle and GPU context
1080 if ((MOS_FAILED(m_osInterface->pfnSetGpuContext(m_osInterface, curGpuEntry.gpuCtxForMos)) ||
1081 m_osInterface->CurrentGpuContextHandle != curGpuEntry.gpuContextHandle) &&
1082 m_osInterface->pfnGetGpuContextbyHandle(m_osInterface, curGpuEntry.gpuContextHandle) == curGpuEntry.pGpuContext)
1083 {
1084 m_osInterface->pfnWaitForCmdCompletion(m_osInterface->osStreamState, curGpuEntry.gpuContextHandle);
1085
1086 m_osInterface->pfnDestroyGpuContextByHandle(m_osInterface, curGpuEntry.gpuContextHandle);
1087 }
1088 }
1089 if (m_osInterface->CurrentGpuContextOrdinal != originalGpuCtxOrdinal)
1090 {
1091 //Recover original settings
1092 if (m_osInterface->pfnSetGpuContext(m_osInterface, originalGpuCtxOrdinal) != MOS_STATUS_SUCCESS)
1093 {
1094 VPHAL_PUBLIC_NORMALMESSAGE("Have not recovered original GPU Context settings in m_osInterface");
1095 }
1096 }
1097 #endif
1098
1099 return MOS_STATUS_SUCCESS;
1100 }
1101
1102 //!
1103 //! \brief Check whether GPU context is reused or not
1104 //! \details Check whether GPU context is reused or not
1105 //! \param MOS_GPU_CONTEXT mosGpuConext
1106 //! [in] Mos GPU context
1107 //! \return bool
1108 //! Return true if is reused, otherwise false
1109 //!
IsGpuContextReused(MOS_GPU_CONTEXT mosGpuContext)1110 bool VphalState::IsGpuContextReused(
1111 MOS_GPU_CONTEXT mosGpuContext)
1112 {
1113 bool reuseContextFlag = false;
1114 #if !EMUL
1115 MOS_GPU_CONTEXT originalGpuCtxOrdinal = m_osInterface->CurrentGpuContextOrdinal;
1116 if (MOS_SUCCEEDED(m_osInterface->pfnSetGpuContext(m_osInterface, mosGpuContext)))
1117 {
1118 VPHAL_PUBLIC_NORMALMESSAGE("Reuse mos GPU context %d. GPU handle %d", (uint32_t)mosGpuContext, m_osInterface->CurrentGpuContextHandle);
1119 reuseContextFlag = true;
1120 }
1121
1122 if (originalGpuCtxOrdinal < MOS_GPU_CONTEXT_MAX &&
1123 m_osInterface->CurrentGpuContextOrdinal != originalGpuCtxOrdinal)
1124 {
1125 //Recover original settings
1126 if (m_osInterface->pfnSetGpuContext(m_osInterface, originalGpuCtxOrdinal) != MOS_STATUS_SUCCESS)
1127 {
1128 VPHAL_PUBLIC_NORMALMESSAGE("Have not recovered original GPU Context settings in m_osInterface");
1129 }
1130 }
1131 #endif
1132 return reuseContextFlag;
1133 }
1134