1 /*
2 * Copyright (c) 2015-2020, 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_common.c
24 //! \brief    The file of common utilities definitions shared by low level renderers
25 //! \details  Common utilities for different renderers, e.g. DNDI or Comp
26 //!
27 #include "vphal_render_common.h"
28 #include "vphal_render_composite.h"
29 #include "mos_os.h"
30 #include "mos_solo_generic.h"
31 #include "hal_oca_interface.h"
32 
33 extern const MEDIA_OBJECT_KA2_INLINE_DATA g_cInit_MEDIA_OBJECT_KA2_INLINE_DATA =
34 {
35     // DWORD 0
36     {
37         0,                                      // DestinationBlockHorizontalOrigin
38         0                                       // DestinationBlockVerticalOrigin
39     },
40 
41     // DWORD 1
42     {
43         0,                                      // HorizontalBlockCompositeMaskLayer0
44         0                                       // VerticalBlockCompositeMaskLayer0
45     },
46 
47     // DWORD 2
48     {
49         0,                                      // HorizontalBlockCompositeMaskLayer1
50         0                                       // VerticalBlockCompositeMaskLayer1
51     },
52 
53     // DWORD 3
54     {
55         0,                                      // HorizontalBlockCompositeMaskLayer2
56         0                                       // VerticalBlockCompositeMaskLayer2
57     },
58 
59     // DWORD 4
60     0.0F,                                       // VideoXScalingStep
61 
62     // DWORD 5
63     0.0F,                                       // VideoStepDelta
64 
65     // DWORD 6
66     {
67         0,                                      // VerticalBlockNumber
68         0                                       // AreaOfInterest
69     },
70 
71     // DWORD 7
72     {
73         0,                                      // GroupIDNumber
74     },
75 
76     // DWORD 8
77     {
78         0,                                      // HorizontalBlockCompositeMaskLayer3
79         0                                       // VerticalBlockCompositeMaskLayer3
80     },
81 
82     // DWORD 9
83     {
84         0,                                      // HorizontalBlockCompositeMaskLayer4
85         0                                       // VerticalBlockCompositeMaskLayer4
86     },
87 
88     // DWORD 10
89     {
90         0,                                      // HorizontalBlockCompositeMaskLayer5
91         0                                       // VerticalBlockCompositeMaskLayer5
92     },
93 
94     // DWORD 11
95     {
96         0,                                      // HorizontalBlockCompositeMaskLayer6
97         0                                       // VerticalBlockCompositeMaskLayer6
98     },
99 
100     // DWORD 12
101     {
102         0,                                      // HorizontalBlockCompositeMaskLayer7
103         0                                       // VerticalBlockCompositeMaskLayer7
104     },
105 
106     // DWORD 13
107     0,                                          // Reserved
108 
109     // DWORD 14
110     0,                                          // Reserved
111 
112     // DWORD 15
113     0                                           // Reserved
114 };
115 
116 //!
117 //! \brief    Initialized RenderHal Surface Type
118 //! \details  Initialized RenderHal Surface Type according to input VPHAL Surface Type
119 //! \param    [in] vpSurfType
120 //!           VPHAL surface type
121 //! \return   RENDERHAL_SURFACE_TYPE
122 //!
VpHal_RndrInitRenderHalSurfType(VPHAL_SURFACE_TYPE vpSurfType)123 static inline RENDERHAL_SURFACE_TYPE VpHal_RndrInitRenderHalSurfType(VPHAL_SURFACE_TYPE vpSurfType)
124 {
125     switch (vpSurfType)
126     {
127         case SURF_IN_BACKGROUND:
128             return RENDERHAL_SURF_IN_BACKGROUND;
129 
130         case SURF_IN_PRIMARY:
131             return RENDERHAL_SURF_IN_PRIMARY;
132 
133         case SURF_IN_SUBSTREAM:
134             return RENDERHAL_SURF_IN_SUBSTREAM;
135 
136         case SURF_IN_REFERENCE:
137             return RENDERHAL_SURF_IN_REFERENCE;
138 
139         case SURF_OUT_RENDERTARGET:
140             return RENDERHAL_SURF_OUT_RENDERTARGET;
141 
142         case SURF_NONE:
143         default:
144             return RENDERHAL_SURF_NONE;
145     }
146 }
147 
148 //!
149 //! \brief    Initialized RenderHal Scaling Mode
150 //! \details  Initialized RenderHal Scaling Mode according to input VPHAL Scaling Mode
151 //! \param    [in] vpScalingMode
152 //!           VPHAL Scaling Mode
153 //! \return   RENDERHAL_SCALING_MODE
154 //!
VpHal_RndrInitRenderHalScalingMode(VPHAL_SCALING_MODE vpScalingMode)155 static inline RENDERHAL_SCALING_MODE VpHal_RndrInitRenderHalScalingMode(VPHAL_SCALING_MODE vpScalingMode)
156 {
157     switch (vpScalingMode)
158     {
159         case VPHAL_SCALING_NEAREST:
160             return RENDERHAL_SCALING_NEAREST;
161 
162         case VPHAL_SCALING_BILINEAR:
163             return RENDERHAL_SCALING_BILINEAR;
164 
165         case VPHAL_SCALING_AVS:
166             return RENDERHAL_SCALING_AVS;
167 
168         default:
169             VPHAL_RENDER_ASSERTMESSAGE("Invalid VPHAL_SCALING_MODE %d, force to nearest mode.", vpScalingMode);
170             return RENDERHAL_SCALING_NEAREST;
171     }
172 }
173 
174 //!
175 //! \brief    Get VpHal Scaling Mode
176 //! \details  Get VpHal Scaling Mode according to RenderHal Scaling Mode
177 //! \param    [in] RenderHalScalingMode
178 //!           RENDERHAL Scaling Mode
179 //! \return   VPHAL_SCALING_MODE
180 //!
VpHal_RndrGetVpHalScalingMode(RENDERHAL_SCALING_MODE RenderHalScalingMode)181 static inline VPHAL_SCALING_MODE VpHal_RndrGetVpHalScalingMode(RENDERHAL_SCALING_MODE RenderHalScalingMode)
182 {
183     switch (RenderHalScalingMode)
184     {
185         case RENDERHAL_SCALING_NEAREST:
186             return VPHAL_SCALING_NEAREST;
187 
188         case RENDERHAL_SCALING_BILINEAR:
189             return VPHAL_SCALING_BILINEAR;
190 
191         case RENDERHAL_SCALING_AVS:
192             return VPHAL_SCALING_AVS;
193 
194         default:
195             VPHAL_RENDER_ASSERTMESSAGE("Invalid RENDERHAL_SCALING_MODE %d, force to nearest mode.", RenderHalScalingMode);
196             return VPHAL_SCALING_NEAREST;
197     }
198 }
199 
200 //!
201 //! \brief    Initialized RenderHal Sample Type
202 //! \details  Initialized RenderHal Sample Type according to input VPHAL Sample Type
203 //! \param    [in] SampleType
204 //!           VPHAL Sample Type
205 //! \return   RENDERHAL_SAMPLE_TYPE
206 //!
VpHal_RndrInitRenderHalSampleType(VPHAL_SAMPLE_TYPE SampleType)207 static inline RENDERHAL_SAMPLE_TYPE VpHal_RndrInitRenderHalSampleType(VPHAL_SAMPLE_TYPE SampleType)
208 {
209     switch (SampleType)
210     {
211         case SAMPLE_PROGRESSIVE:
212             return RENDERHAL_SAMPLE_PROGRESSIVE;
213 
214         case SAMPLE_SINGLE_TOP_FIELD:
215             return RENDERHAL_SAMPLE_SINGLE_TOP_FIELD;
216 
217         case SAMPLE_SINGLE_BOTTOM_FIELD:
218             return RENDERHAL_SAMPLE_SINGLE_BOTTOM_FIELD;
219 
220         case SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD:
221             return RENDERHAL_SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
222 
223         case SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD:
224             return RENDERHAL_SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD;
225 
226         case SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD:
227             return RENDERHAL_SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD;
228 
229         case SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD:
230             return RENDERHAL_SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD;
231 
232         case SAMPLE_INVALID:
233         default:
234             VPHAL_RENDER_ASSERTMESSAGE("Invalid VPHAL_SAMPLE_TYPE %d.\n", SampleType);
235             return RENDERHAL_SAMPLE_INVALID;
236     }
237 }
238 
VpHal_RndrInitPlaneOffset(PMOS_PLANE_OFFSET pMosPlaneOffset,PVPHAL_PLANE_OFFSET pVpPlaneOffset)239 static inline void VpHal_RndrInitPlaneOffset(
240     PMOS_PLANE_OFFSET pMosPlaneOffset,
241     PVPHAL_PLANE_OFFSET pVpPlaneOffset)
242 {
243     pMosPlaneOffset->iSurfaceOffset     = pVpPlaneOffset->iSurfaceOffset;
244     pMosPlaneOffset->iXOffset           = pVpPlaneOffset->iXOffset;
245     pMosPlaneOffset->iYOffset           = pVpPlaneOffset->iYOffset;
246     pMosPlaneOffset->iLockSurfaceOffset = pVpPlaneOffset->iLockSurfaceOffset;
247 
248 }
249 
250 //!
251 //! \brief    Initialized MHW Rotation mode
252 //! \details  Initialized MHW Rotation mode according to input VPHAL Rotation Type
253 //! \param    [in] Rotation
254 //!           VPHAL Rotation mode
255 //! \return   MHW_ROTATION
256 //!
VpHal_RndrInitRotationMode(VPHAL_ROTATION Rotation)257 static inline MHW_ROTATION VpHal_RndrInitRotationMode(VPHAL_ROTATION Rotation)
258 {
259     MHW_ROTATION    Mode = MHW_ROTATION_IDENTITY;
260 
261     switch (Rotation)
262     {
263         case VPHAL_ROTATION_IDENTITY:
264             Mode = MHW_ROTATION_IDENTITY;
265             break;
266 
267         case VPHAL_ROTATION_90:
268             Mode = MHW_ROTATION_90;
269             break;
270 
271         case VPHAL_ROTATION_180:
272             Mode = MHW_ROTATION_180;
273             break;
274 
275         case VPHAL_ROTATION_270:
276             Mode = MHW_ROTATION_270;
277             break;
278 
279         case VPHAL_MIRROR_HORIZONTAL:
280             Mode = MHW_MIRROR_HORIZONTAL;
281             break;
282 
283         case VPHAL_MIRROR_VERTICAL:
284             Mode = MHW_MIRROR_VERTICAL;
285             break;
286 
287         case VPHAL_ROTATE_90_MIRROR_VERTICAL:
288             Mode = MHW_ROTATE_90_MIRROR_VERTICAL;
289             break;
290 
291         case VPHAL_ROTATE_90_MIRROR_HORIZONTAL:
292             Mode = MHW_ROTATE_90_MIRROR_HORIZONTAL;
293             break;
294 
295         default:
296             VPHAL_RENDER_ASSERTMESSAGE("Invalid Rotation Angle.");
297             break;
298     }
299 
300     return Mode;
301 }
302 
303 //!
304 //! \brief    Set the numbers of Slice, Sub-slice, EUs for power mode
305 //! \details  Set the numbers of Slice, Sub-slice, EUs recommended for
306 //!           the given kernel type for power mode
307 //! \param    [in] pRenderHal
308 //!           Pointer to RenderHal Interface Structure
309 //! \param    [in] KernelID
310 //!           VP render Kernel ID
311 //! \return   MOS_STATUS
312 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
313 //!
VpHal_RndrCommonSetPowerMode(PRENDERHAL_INTERFACE pRenderHal,VpKernelID KernelID)314 MOS_STATUS VpHal_RndrCommonSetPowerMode(
315     PRENDERHAL_INTERFACE                pRenderHal,
316     VpKernelID                          KernelID)
317 {
318     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
319     uint16_t                            wNumRequestedEUSlices   = 1;    // Default to 1 slice
320     uint16_t                            wNumRequestedSubSlices  = 3;    // Default to 3 subslice
321     uint16_t                            wNumRequestedEUs        = 8;    // Default to 8 EUs
322     RENDERHAL_POWEROPTION               PowerOption;
323     bool                                bSetRequestedSlices     = false;
324     const VphalSseuSetting              *pcSSEUTable            = nullptr;
325 
326     VPHAL_RENDER_CHK_NULL(pRenderHal);
327 
328     if ((pRenderHal->bRequestSingleSlice) || (pRenderHal->bEUSaturationNoSSD))
329     {
330         bSetRequestedSlices     = true;
331         // bEUSaturationNoSSD: No slice shutdown, must request 2 slices [CM EU saturation on].
332         // bRequestSingleSlice: Always single slice.
333         wNumRequestedEUSlices   = (pRenderHal->bEUSaturationNoSSD) ? 2 : 1;
334     }
335     else
336     {
337         bSetRequestedSlices = false;
338     }
339 
340     if (pRenderHal->sseuTable)
341     {
342         pcSSEUTable = (const VphalSseuSetting*)pRenderHal->sseuTable;
343     }
344     else
345     {
346         VPHAL_RENDER_ASSERTMESSAGE("SSEU Table not valid.");
347         eStatus = MOS_STATUS_UNKNOWN;
348         goto finish;
349     }
350 
351     VPHAL_RENDER_CHK_NULL(pcSSEUTable);
352     pcSSEUTable += KernelID;
353     if (!bSetRequestedSlices)                        // If num Slices is already programmed, then don't change it
354     {
355         if (wNumRequestedEUSlices < pcSSEUTable->numSlices)
356         {
357             wNumRequestedEUSlices = pcSSEUTable->numSlices;
358         }
359     }
360 
361     wNumRequestedSubSlices  = pcSSEUTable->numSubSlices;
362     wNumRequestedEUs        = pcSSEUTable->numEUs;
363 
364 #if (_DEBUG || _RELEASE_INTERNAL)
365     // User feature key reads
366     MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
367     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
368     MOS_UserFeature_ReadValue_ID(
369         nullptr,
370         __MEDIA_USER_FEATURE_VALUE_SSEU_SETTING_OVERRIDE_ID,
371         &UserFeatureData,
372         pRenderHal->pOsInterface->pOsContext);
373 
374     if (UserFeatureData.u32Data != 0xDEADC0DE)
375     {
376         wNumRequestedEUSlices  = UserFeatureData.u32Data & 0xFF;               // Bits 0-7
377         wNumRequestedSubSlices = (UserFeatureData.u32Data >> 8) & 0xFF;        // Bits 8-15
378         wNumRequestedEUs       = (UserFeatureData.u32Data >> 16) & 0xFFFF;     // Bits 16-31
379     }
380 #endif
381 
382     PowerOption.nSlice          = wNumRequestedEUSlices;
383     PowerOption.nSubSlice       = wNumRequestedSubSlices;
384     PowerOption.nEU             = wNumRequestedEUs;
385     pRenderHal->pfnSetPowerOptionMode(pRenderHal, &PowerOption);
386 
387 finish:
388     return eStatus;
389 }
390 
391 //       so will enable other renderers like frc and istab support status report.
392 //!
393 //! \brief      Submit commands for rendering
394 //! \details    Submit commands for rendering. The KMD related fields in pGenericPrologParam might be modified by this
395 //!             function in order to maintain the synchronization mechanism for resource.
396 //! \param      [in] pRenderHal
397 //!             Pointer to RenderHal Interface Structure
398 //! \param      [in] pBatchBuffer
399 //!             Pointer to batch buffer
400 //! \param      [in] bNullRendering
401 //!             Indicate whether is Null rendering
402 //! \param      [in] pWalkerParams
403 //!             Pointer to walker parameters
404 //! \param      [in] pGpGpuWalkerParams
405 //!             Pointer to GPGPU walker parameters
406 //! \param      [in] KernelID
407 //!             VP Kernel ID
408 //! \param      [in] bLastSubmission
409 //!             Is last submission
410 //! \return     MOS_STATUS
411 //!
VpHal_RndrCommonSubmitCommands(PRENDERHAL_INTERFACE pRenderHal,PMHW_BATCH_BUFFER pBatchBuffer,bool bNullRendering,PMHW_WALKER_PARAMS pWalkerParams,PMHW_GPGPU_WALKER_PARAMS pGpGpuWalkerParams,VpKernelID KernelID,bool bLastSubmission)412 MOS_STATUS VpHal_RndrCommonSubmitCommands(
413     PRENDERHAL_INTERFACE                pRenderHal,
414     PMHW_BATCH_BUFFER                   pBatchBuffer,
415     bool                                bNullRendering,
416     PMHW_WALKER_PARAMS                  pWalkerParams,
417     PMHW_GPGPU_WALKER_PARAMS            pGpGpuWalkerParams,
418     VpKernelID                          KernelID,
419     bool                                bLastSubmission)
420 {
421     PMOS_INTERFACE                      pOsInterface = nullptr;
422     MOS_COMMAND_BUFFER                  CmdBuffer = {};
423     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
424     uint32_t                            dwSyncTag = 0;
425     int32_t                             i = 0, iRemaining = 0;
426     PMHW_MI_INTERFACE                   pMhwMiInterface = nullptr;
427     MhwRenderInterface                  *pMhwRender = nullptr;
428     MHW_MEDIA_STATE_FLUSH_PARAM         FlushParam = {};
429     bool                                bEnableSLM = false;
430     RENDERHAL_GENERIC_PROLOG_PARAMS     GenericPrologParams = {};
431     PMOS_RESOURCE                       gpuStatusBuffer = nullptr;
432     MediaPerfProfiler                   *pPerfProfiler = nullptr;
433     MOS_CONTEXT                         *pOsContext = nullptr;
434     PMHW_MI_MMIOREGISTERS               pMmioRegisters = nullptr;
435 
436     MHW_RENDERHAL_CHK_NULL(pRenderHal);
437     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwRenderInterface);
438     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwMiInterface);
439     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwRenderInterface->GetMmioRegisters());
440     MHW_RENDERHAL_CHK_NULL(pRenderHal->pOsInterface);
441     MHW_RENDERHAL_CHK_NULL(pRenderHal->pOsInterface->pOsContext);
442 
443     eStatus             = MOS_STATUS_UNKNOWN;
444     pOsInterface        = pRenderHal->pOsInterface;
445     pMhwMiInterface     = pRenderHal->pMhwMiInterface;
446     pMhwRender          = pRenderHal->pMhwRenderInterface;
447     iRemaining          = 0;
448     FlushParam          = g_cRenderHal_InitMediaStateFlushParams;
449     MOS_ZeroMemory(&CmdBuffer, sizeof(CmdBuffer));
450     pPerfProfiler       = pRenderHal->pPerfProfiler;
451     pOsContext          = pOsInterface->pOsContext;
452     pMmioRegisters      = pMhwRender->GetMmioRegisters();
453 
454     // Allocate all available space, unused buffer will be returned later
455     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetCommandBuffer(pOsInterface, &CmdBuffer, 0));
456 
457     // Set initial state
458     iRemaining = CmdBuffer.iRemaining;
459 
460     VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonSetPowerMode(
461         pRenderHal,
462         KernelID));
463 
464 #ifndef EMUL
465     if (bLastSubmission && pOsInterface->bEnableKmdMediaFrameTracking)
466     {
467         // Get GPU Status buffer
468         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetGpuStatusBufferResource(pOsInterface, gpuStatusBuffer));
469         VPHAL_RENDER_CHK_NULL(gpuStatusBuffer);
470         // Register the buffer
471         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(pOsInterface, gpuStatusBuffer, true, true));
472 
473         GenericPrologParams.bEnableMediaFrameTracking = true;
474         GenericPrologParams.presMediaFrameTrackingSurface  = gpuStatusBuffer;
475         GenericPrologParams.dwMediaFrameTrackingTag = pOsInterface->pfnGetGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
476         GenericPrologParams.dwMediaFrameTrackingAddrOffset = pOsInterface->pfnGetGpuStatusTagOffset(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
477 
478         // Increment GPU Status Tag
479         pOsInterface->pfnIncrementGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
480     }
481 #endif
482 
483     HalOcaInterface::On1stLevelBBStart(CmdBuffer, *pOsContext, pOsInterface->CurrentGpuContextHandle,
484         *pRenderHal->pMhwMiInterface, *pMmioRegisters);
485 
486     // Add kernel info to log.
487     HalOcaInterface::DumpVpKernelInfo(CmdBuffer, *pOsContext, KernelID, 0, nullptr);
488     // Add vphal param to log.
489     HalOcaInterface::DumpVphalParam(CmdBuffer, *pOsContext, pRenderHal->pVphalOcaDumper);
490 
491     // Initialize command buffer and insert prolog
492     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnInitCommandBuffer(pRenderHal, &CmdBuffer, &GenericPrologParams));
493 
494     // Write timing data for 3P budget
495     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendTimingData(pRenderHal, &CmdBuffer, true));
496     VPHAL_RENDER_CHK_STATUS(pPerfProfiler->AddPerfCollectStartCmd((void*)pRenderHal, pOsInterface, pMhwMiInterface, &CmdBuffer));
497 
498     VPHAL_RENDER_CHK_STATUS(NullHW::StartPredicate(pRenderHal->pMhwMiInterface, &CmdBuffer));
499 
500     bEnableSLM = (pGpGpuWalkerParams && pGpGpuWalkerParams->SLMSize > 0)? true : false;
501     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetCacheOverrideParams(
502         pRenderHal,
503         &pRenderHal->L3CacheSettings,
504         bEnableSLM));
505 
506     // Flush media states
507     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendMediaStates(
508         pRenderHal,
509         &CmdBuffer,
510         pWalkerParams,
511         pGpGpuWalkerParams));
512 
513     if (pBatchBuffer)
514     {
515         // Register batch buffer for rendering
516         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(
517             pOsInterface,
518             &pBatchBuffer->OsResource,
519             false,
520             true));
521 
522         HalOcaInterface::OnSubLevelBBStart(CmdBuffer, *pOsContext, &pBatchBuffer->OsResource, 0, true, 0);
523 
524         // Send Start 2nd level batch buffer command (HW/OS dependent)
525         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferStartCmd(
526             &CmdBuffer,
527             pBatchBuffer));
528     }
529 
530     // Write back GPU Status tag
531     if (!pOsInterface->bEnableKmdMediaFrameTracking)
532     {
533         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendRcsStatusTag(pRenderHal, &CmdBuffer));
534     }
535 
536     VPHAL_RENDER_CHK_STATUS(NullHW::StopPredicate(pRenderHal->pMhwMiInterface, &CmdBuffer));
537 
538     VPHAL_RENDER_CHK_STATUS(pPerfProfiler->AddPerfCollectEndCmd((void*)pRenderHal, pOsInterface, pMhwMiInterface, &CmdBuffer));
539 
540     // Write timing data for 3P budget
541     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendTimingData(pRenderHal, &CmdBuffer, false));
542 
543     if (GFX_IS_GEN_9_OR_LATER(pRenderHal->Platform))
544     {
545         MHW_PIPE_CONTROL_PARAMS PipeControlParams;
546 
547         MOS_ZeroMemory(&PipeControlParams, sizeof(PipeControlParams));
548         PipeControlParams.dwFlushMode                   = MHW_FLUSH_WRITE_CACHE;
549         PipeControlParams.bGenericMediaStateClear       = true;
550         PipeControlParams.bIndirectStatePointersDisable = true;
551         PipeControlParams.bDisableCSStall               = false;
552         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddPipeControl(&CmdBuffer, nullptr, &PipeControlParams));
553 
554         if (MEDIA_IS_WA(pRenderHal->pWaTable, WaSendDummyVFEafterPipelineSelect))
555         {
556             MHW_VFE_PARAMS VfeStateParams = {};
557             VfeStateParams.dwNumberofURBEntries = 1;
558             VPHAL_RENDER_CHK_STATUS(pMhwRender->AddMediaVfeCmd(&CmdBuffer, &VfeStateParams));
559         }
560     }
561 
562     if (GFX_IS_GEN_8_OR_LATER(pRenderHal->Platform))
563     {
564         // Add media flush command in case HW not cleaning the media state
565         if (MEDIA_IS_WA(pRenderHal->pWaTable, WaMSFWithNoWatermarkTSGHang))
566         {
567             FlushParam.bFlushToGo = true;
568             if (pWalkerParams)
569             {
570                 FlushParam.ui8InterfaceDescriptorOffset = pWalkerParams->InterfaceDescriptorOffset;
571             }
572             else
573             {
574                 VPHAL_RENDER_ASSERTMESSAGE("ERROR, pWalkerParams is nullptr and cannot get InterfaceDescriptorOffset.");
575             }
576             VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMediaStateFlush(&CmdBuffer, nullptr, &FlushParam));
577         }
578         else if (MEDIA_IS_WA(pRenderHal->pWaTable, WaAddMediaStateFlushCmd))
579         {
580             VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMediaStateFlush(&CmdBuffer, nullptr, &FlushParam));
581         }
582     }
583 
584     HalOcaInterface::On1stLevelBBEnd(CmdBuffer, *pOsInterface);
585 
586     if (pBatchBuffer)
587     {
588         // Send Batch Buffer end command (HW/OS dependent)
589         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(&CmdBuffer, nullptr));
590     }
591     else if (VpHal_RndrCommonIsMiBBEndNeeded(pOsInterface))
592     {
593         // Send Batch Buffer end command for 1st level Batch Buffer
594         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(&CmdBuffer, nullptr));
595     }
596     else if (GFX_IS_GEN_8_OR_LATER(pRenderHal->Platform) &&
597                 Mos_Solo_IsInUse(pOsInterface) &&
598                 pRenderHal->pOsInterface->bNoParsingAssistanceInKmd)
599     {
600         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(&CmdBuffer, nullptr));
601     }
602 
603     // Return unused command buffer space to OS
604     pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
605 
606 //    VPHAL_DBG_STATE_DUMPPER_DUMP_COMMAND_BUFFER(pRenderHal, &CmdBuffer);
607 
608     // Submit command buffer
609     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnSubmitCommandBuffer(pOsInterface, &CmdBuffer, bNullRendering));
610 
611     if (bNullRendering == false)
612     {
613         dwSyncTag = pRenderHal->pStateHeap->dwNextTag++;
614 
615         // Set media state and batch buffer as busy
616         pRenderHal->pStateHeap->pCurMediaState->bBusy = true;
617         if (pBatchBuffer)
618         {
619             pBatchBuffer->bBusy     = true;
620             pBatchBuffer->dwSyncTag = dwSyncTag;
621         }
622     }
623 
624     eStatus = MOS_STATUS_SUCCESS;
625 
626 finish:
627     // Failed -> discard all changes in Command Buffer
628     if (eStatus != MOS_STATUS_SUCCESS)
629     {
630         // Buffer overflow - display overflow size
631         if (CmdBuffer.iRemaining < 0)
632         {
633             VPHAL_RENDER_ASSERTMESSAGE("Command Buffer overflow by %d bytes", -CmdBuffer.iRemaining);
634         }
635 
636         // Move command buffer back to beginning
637         i = iRemaining - CmdBuffer.iRemaining;
638         CmdBuffer.iRemaining  = iRemaining;
639         CmdBuffer.iOffset    -= i;
640         CmdBuffer.pCmdPtr     =
641             CmdBuffer.pCmdBase + CmdBuffer.iOffset / sizeof(uint32_t);
642 
643         // Return unused command buffer space to OS
644         if (pOsInterface)
645         {
646             pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
647         }
648     }
649 
650     return eStatus;
651 }
652 
653 //!
654 //! \brief      Submit commands for rendering
655 //! \details    Submit commands for rendering with status table update enabling
656 //! \param      [in] pRenderHal
657 //!             Pointer to RenderHal Interface Structure
658 //! \param      [in] pBatchBuffer
659 //!             Pointer to batch buffer
660 //! \param      [in] bNullRendering
661 //!             Indicate whether is Null rendering
662 //! \param      [in] pWalkerParams
663 //!             Pointer to walker parameters
664 //! \param      [in] pGpGpuWalkerParams
665 //!             Pointer to GPGPU walker parameters
666 //! \param      [in] pStatusTableUpdateParams
667 //!             Pointer to pStatusTableUpdateParams
668 //! \param      [in] KernelID
669 //!             VP Kernel ID
670 //! \param      [in] FcKernelCount
671 //!             VP FC Kernel Count
672 //! \param      [in] FcKernelList
673 //!             VP FC Kernel List
674 //! \param      [in] bLastSubmission
675 //!             Is last submission
676 //! \return     MOS_STATUS
677 //!
VpHal_RndrSubmitCommands(PRENDERHAL_INTERFACE pRenderHal,PMHW_BATCH_BUFFER pBatchBuffer,bool bNullRendering,PMHW_WALKER_PARAMS pWalkerParams,PMHW_GPGPU_WALKER_PARAMS pGpGpuWalkerParams,PSTATUS_TABLE_UPDATE_PARAMS pStatusTableUpdateParams,VpKernelID KernelID,int FcKernelCount,int * FcKernelList,bool bLastSubmission)678 MOS_STATUS VpHal_RndrSubmitCommands(
679     PRENDERHAL_INTERFACE                pRenderHal,
680     PMHW_BATCH_BUFFER                   pBatchBuffer,
681     bool                                bNullRendering,
682     PMHW_WALKER_PARAMS                  pWalkerParams,
683     PMHW_GPGPU_WALKER_PARAMS            pGpGpuWalkerParams,
684     PSTATUS_TABLE_UPDATE_PARAMS         pStatusTableUpdateParams,
685     VpKernelID                          KernelID,
686     int                                 FcKernelCount,
687     int                                 *FcKernelList,
688     bool                                bLastSubmission)
689 {
690     PMOS_INTERFACE                      pOsInterface = nullptr;
691     MOS_COMMAND_BUFFER                  CmdBuffer = {};
692     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
693     uint32_t                            dwSyncTag = 0;
694     int32_t                             i = 0, iRemaining = 0;
695     PMHW_MI_INTERFACE                   pMhwMiInterface = nullptr;
696     MhwRenderInterface                  *pMhwRender = nullptr;
697     MHW_MEDIA_STATE_FLUSH_PARAM         FlushParam = {};
698     bool                                bEnableSLM = false;
699     RENDERHAL_GENERIC_PROLOG_PARAMS     GenericPrologParams = {};
700     PMOS_RESOURCE                       gpuStatusBuffer = nullptr;
701     MediaPerfProfiler                   *pPerfProfiler = nullptr;
702     MOS_CONTEXT                         *pOsContext = nullptr;
703     PMHW_MI_MMIOREGISTERS               pMmioRegisters = nullptr;
704 
705     MHW_RENDERHAL_CHK_NULL(pRenderHal);
706     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwRenderInterface);
707     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwMiInterface);
708     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwRenderInterface->GetMmioRegisters());
709     MHW_RENDERHAL_CHK_NULL(pRenderHal->pOsInterface);
710     MHW_RENDERHAL_CHK_NULL(pRenderHal->pOsInterface->pOsContext);
711 
712     eStatus              = MOS_STATUS_UNKNOWN;
713     pOsInterface         = pRenderHal->pOsInterface;
714     pMhwMiInterface      = pRenderHal->pMhwMiInterface;
715     pMhwRender           = pRenderHal->pMhwRenderInterface;
716     iRemaining           = 0;
717     FlushParam           = g_cRenderHal_InitMediaStateFlushParams;
718     MOS_ZeroMemory(&CmdBuffer, sizeof(CmdBuffer));
719     pPerfProfiler       = pRenderHal->pPerfProfiler;
720     pOsContext          = pOsInterface->pOsContext;
721     pMmioRegisters      = pMhwRender->GetMmioRegisters();
722 
723     // Allocate all available space, unused buffer will be returned later
724     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetCommandBuffer(pOsInterface, &CmdBuffer, 0));
725 
726     // Set initial state
727     iRemaining = CmdBuffer.iRemaining;
728 
729     VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonSetPowerMode(
730         pRenderHal,
731         KernelID));
732 
733 #ifndef EMUL
734     if (bLastSubmission && pOsInterface->bEnableKmdMediaFrameTracking)
735     {
736         // Get GPU Status buffer
737         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnGetGpuStatusBufferResource(pOsInterface, gpuStatusBuffer));
738         VPHAL_RENDER_CHK_NULL(gpuStatusBuffer);
739 
740         // Register the buffer
741         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(pOsInterface, gpuStatusBuffer, true, true));
742 
743         GenericPrologParams.bEnableMediaFrameTracking = true;
744         GenericPrologParams.presMediaFrameTrackingSurface = gpuStatusBuffer;
745         GenericPrologParams.dwMediaFrameTrackingTag = pOsInterface->pfnGetGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
746         GenericPrologParams.dwMediaFrameTrackingAddrOffset = pOsInterface->pfnGetGpuStatusTagOffset(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
747 
748         // Increment GPU Status Tag
749         pOsInterface->pfnIncrementGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
750     }
751 #endif
752 
753     HalOcaInterface::On1stLevelBBStart(CmdBuffer, *pOsContext, pOsInterface->CurrentGpuContextHandle,
754         *pRenderHal->pMhwMiInterface, *pMmioRegisters);
755 
756     // Add kernel info to log.
757     HalOcaInterface::DumpVpKernelInfo(CmdBuffer, *pOsContext, KernelID, FcKernelCount, FcKernelList);
758     // Add vphal param to log.
759     HalOcaInterface::DumpVphalParam(CmdBuffer, *pOsContext, pRenderHal->pVphalOcaDumper);
760 
761     // Initialize command buffer and insert prolog
762     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnInitCommandBuffer(pRenderHal, &CmdBuffer, &GenericPrologParams));
763 
764     VPHAL_RENDER_CHK_STATUS(pPerfProfiler->AddPerfCollectStartCmd((void*)pRenderHal, pOsInterface, pMhwMiInterface, &CmdBuffer));
765 
766     VPHAL_RENDER_CHK_STATUS(NullHW::StartPredicate(pRenderHal->pMhwMiInterface, &CmdBuffer));
767 
768     // Write timing data for 3P budget
769     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendTimingData(pRenderHal, &CmdBuffer, true));
770 
771     bEnableSLM = (pGpGpuWalkerParams && pGpGpuWalkerParams->SLMSize > 0)? true : false;
772     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetCacheOverrideParams(
773         pRenderHal,
774         &pRenderHal->L3CacheSettings,
775         bEnableSLM));
776 
777     if (pRenderHal->bCmfcCoeffUpdate)
778     {
779         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendCscCoeffSurface(pRenderHal,
780             &CmdBuffer,
781             pRenderHal->pCmfcCoeffSurface,
782             pRenderHal->pStateHeap->pKernelAllocation[pRenderHal->iKernelAllocationID].pKernelEntry));
783     }
784 
785     // Flush media states
786     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendMediaStates(
787         pRenderHal,
788         &CmdBuffer,
789         pWalkerParams,
790         pGpGpuWalkerParams));
791 
792     if (pBatchBuffer)
793     {
794         // Register batch buffer for rendering
795         VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(
796             pOsInterface,
797             &pBatchBuffer->OsResource,
798             false,
799             true));
800 
801         HalOcaInterface::OnSubLevelBBStart(CmdBuffer, *pOsContext, &pBatchBuffer->OsResource, 0, true, 0);
802 
803         // Send Start 2nd level batch buffer command (HW/OS dependent)
804         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferStartCmd(
805             &CmdBuffer,
806             pBatchBuffer));
807     }
808 
809     // Write back GPU Status tag
810     if (!pOsInterface->bEnableKmdMediaFrameTracking)
811     {
812         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendRcsStatusTag(pRenderHal, &CmdBuffer));
813     }
814 
815     VPHAL_RENDER_CHK_STATUS(NullHW::StopPredicate(pRenderHal->pMhwMiInterface, &CmdBuffer));
816 
817     VPHAL_RENDER_CHK_STATUS(pPerfProfiler->AddPerfCollectEndCmd((void*)pRenderHal, pOsInterface, pMhwMiInterface, &CmdBuffer));
818 
819     // Write timing data for 3P budget
820     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSendTimingData(pRenderHal, &CmdBuffer, false));
821 
822     if (GFX_IS_GEN_9_OR_LATER(pRenderHal->Platform))
823     {
824         MHW_PIPE_CONTROL_PARAMS PipeControlParams;
825 
826         MOS_ZeroMemory(&PipeControlParams, sizeof(PipeControlParams));
827         PipeControlParams.dwFlushMode                   = MHW_FLUSH_WRITE_CACHE;
828         PipeControlParams.bGenericMediaStateClear       = true;
829         PipeControlParams.bIndirectStatePointersDisable = true;
830         PipeControlParams.bDisableCSStall               = false;
831         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddPipeControl(&CmdBuffer, nullptr, &PipeControlParams));
832 
833         if (MEDIA_IS_WA(pRenderHal->pWaTable, WaSendDummyVFEafterPipelineSelect))
834         {
835             MHW_VFE_PARAMS VfeStateParams = {};
836             VfeStateParams.dwNumberofURBEntries = 1;
837             VPHAL_RENDER_CHK_STATUS(pMhwRender->AddMediaVfeCmd(&CmdBuffer, &VfeStateParams));
838         }
839     }
840 
841     if (GFX_IS_GEN_8_OR_LATER(pRenderHal->Platform))
842     {
843         // Add media flush command in case HW not cleaning the media state
844         if (MEDIA_IS_WA(pRenderHal->pWaTable, WaMSFWithNoWatermarkTSGHang))
845         {
846             FlushParam.bFlushToGo = true;
847             if (pWalkerParams)
848             {
849                 FlushParam.ui8InterfaceDescriptorOffset = pWalkerParams->InterfaceDescriptorOffset;
850             }
851             else
852             {
853                 VPHAL_RENDER_ASSERTMESSAGE("ERROR, pWalkerParams is nullptr and cannot get InterfaceDescriptorOffset.");
854             }
855             VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMediaStateFlush(&CmdBuffer, nullptr, &FlushParam));
856         }
857         else if (MEDIA_IS_WA(pRenderHal->pWaTable, WaAddMediaStateFlushCmd))
858         {
859             VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMediaStateFlush(&CmdBuffer, nullptr, &FlushParam));
860         }
861     }
862 
863     HalOcaInterface::On1stLevelBBEnd(CmdBuffer, *pOsInterface);
864 
865     if (pBatchBuffer)
866     {
867         // Send Batch Buffer end command (HW/OS dependent)
868         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(&CmdBuffer, nullptr));
869     }
870     else if (VpHal_RndrCommonIsMiBBEndNeeded(pOsInterface))
871     {
872         // Send Batch Buffer end command for 1st level Batch Buffer
873         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(&CmdBuffer, nullptr));
874     }
875     else if (GFX_IS_GEN_8_OR_LATER(pRenderHal->Platform) &&
876                 Mos_Solo_IsInUse(pOsInterface)  &&
877                 pRenderHal->pOsInterface->bNoParsingAssistanceInKmd)
878     {
879         VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(&CmdBuffer, nullptr));
880     }
881 
882     // Return unused command buffer space to OS
883     pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
884 
885 //    VPHAL_DBG_STATE_DUMPPER_DUMP_COMMAND_BUFFER(pRenderHal, &CmdBuffer);
886 
887 #if (_DEBUG || _RELEASE_INTERNAL)
888     if (pStatusTableUpdateParams->bTriggerGPUHang == true)
889     {
890         // Set the GPU HANG Trigger flag here
891         pOsInterface->bTriggerVPHang              = true;
892         pStatusTableUpdateParams->bTriggerGPUHang = false;
893     }
894 #endif
895 
896     // Submit command buffer
897     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnSubmitCommandBuffer(pOsInterface, &CmdBuffer, bNullRendering));
898 
899     if (bNullRendering == false)
900     {
901         dwSyncTag = pRenderHal->pStateHeap->dwNextTag++;
902 
903         // Set media state and batch buffer as busy
904         pRenderHal->pStateHeap->pCurMediaState->bBusy = true;
905         if (pBatchBuffer)
906         {
907             pBatchBuffer->bBusy     = true;
908             pBatchBuffer->dwSyncTag = dwSyncTag;
909         }
910     }
911 
912     eStatus = MOS_STATUS_SUCCESS;
913 
914 finish:
915 
916     if (pStatusTableUpdateParams && pOsInterface)
917     {
918         VpHal_RndrUpdateStatusTableAfterSubmit(pOsInterface, pStatusTableUpdateParams, pOsInterface->CurrentGpuContextOrdinal, eStatus);
919     }
920 
921     // Failed -> discard all changes in Command Buffer
922     if (eStatus != MOS_STATUS_SUCCESS)
923     {
924         // Buffer overflow - display overflow size
925         if (CmdBuffer.iRemaining < 0)
926         {
927             VPHAL_RENDER_ASSERTMESSAGE("Command Buffer overflow by %d bytes", -CmdBuffer.iRemaining);
928         }
929 
930         // Move command buffer back to beginning
931         i = iRemaining - CmdBuffer.iRemaining;
932         CmdBuffer.iRemaining  = iRemaining;
933         CmdBuffer.iOffset    -= i;
934         CmdBuffer.pCmdPtr     =
935             CmdBuffer.pCmdBase + CmdBuffer.iOffset / sizeof(uint32_t);
936 
937         // Return unused command buffer space to OS
938         if (pOsInterface)
939         {
940             pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
941         }
942     }
943 
944     return eStatus;
945 }
946 
947 //!
948 //! \brief    Initialized RenderHal Surface according to incoming VPHAL Surface
949 //! \param    [in] pVpSurface
950 //!           Pointer to the VPHAL surface
951 //! \param    [out] pRenderHalSurface
952 //!           Pointer to the RenderHal surface
953 //! \return   MOS_STATUS
954 //!
VpHal_RndrCommonInitRenderHalSurface(PVPHAL_SURFACE pVpSurface,PRENDERHAL_SURFACE pRenderHalSurface)955 MOS_STATUS VpHal_RndrCommonInitRenderHalSurface(
956     PVPHAL_SURFACE          pVpSurface,
957     PRENDERHAL_SURFACE      pRenderHalSurface)
958 {
959     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
960 
961     //---------------------------------------
962     VPHAL_RENDER_CHK_NULL(pVpSurface);
963     VPHAL_RENDER_CHK_NULL(pRenderHalSurface);
964     //---------------------------------------
965 
966     MOS_ZeroMemory(pRenderHalSurface, sizeof(*pRenderHalSurface));
967 
968     pRenderHalSurface->OsSurface.OsResource         = pVpSurface->OsResource;
969     pRenderHalSurface->OsSurface.dwWidth            = pVpSurface->dwWidth;
970     pRenderHalSurface->OsSurface.dwHeight           = pVpSurface->dwHeight;
971     pRenderHalSurface->OsSurface.dwPitch            = pVpSurface->dwPitch;
972     pRenderHalSurface->OsSurface.Format             = pVpSurface->Format;
973     pRenderHalSurface->OsSurface.TileType           = pVpSurface->TileType;
974     pRenderHalSurface->OsSurface.TileModeGMM        = pVpSurface->TileModeGMM;
975     pRenderHalSurface->OsSurface.bGMMTileEnabled    = pVpSurface->bGMMTileEnabled;
976     pRenderHalSurface->OsSurface.dwOffset           = pVpSurface->dwOffset;
977     pRenderHalSurface->OsSurface.bIsCompressed      = pVpSurface->bIsCompressed;
978     pRenderHalSurface->OsSurface.bCompressible      = pVpSurface->bCompressible;
979     pRenderHalSurface->OsSurface.CompressionMode    = pVpSurface->CompressionMode;
980     pRenderHalSurface->OsSurface.dwDepth            = pVpSurface->dwDepth;
981     pRenderHalSurface->OsSurface.dwQPitch           = pVpSurface->dwHeight;
982     pRenderHalSurface->OsSurface.MmcState           = (MOS_MEMCOMP_STATE)pVpSurface->CompressionMode;
983     pRenderHalSurface->OsSurface.CompressionFormat  = pVpSurface->CompressionFormat;
984 
985     VpHal_RndrInitPlaneOffset(
986         &pRenderHalSurface->OsSurface.YPlaneOffset,
987         &pVpSurface->YPlaneOffset);
988     VpHal_RndrInitPlaneOffset(
989         &pRenderHalSurface->OsSurface.UPlaneOffset,
990         &pVpSurface->UPlaneOffset);
991     VpHal_RndrInitPlaneOffset(
992         &pRenderHalSurface->OsSurface.VPlaneOffset,
993         &pVpSurface->VPlaneOffset);
994 
995     pRenderHalSurface->rcSrc                        = pVpSurface->rcSrc;
996     pRenderHalSurface->rcDst                        = pVpSurface->rcDst;
997     pRenderHalSurface->rcMaxSrc                     = pVpSurface->rcMaxSrc;
998     pRenderHalSurface->SurfType                     =
999                     VpHal_RndrInitRenderHalSurfType(pVpSurface->SurfType);
1000     pRenderHalSurface->ScalingMode                  =
1001                     VpHal_RndrInitRenderHalScalingMode(pVpSurface->ScalingMode);
1002     pRenderHalSurface->ChromaSiting                 = pVpSurface->ChromaSiting;
1003 
1004     if (pVpSurface->pDeinterlaceParams != nullptr)
1005     {
1006         pRenderHalSurface->bDeinterlaceEnable       = true;
1007     }
1008     else
1009     {
1010         pRenderHalSurface->bDeinterlaceEnable       = false;
1011     }
1012 
1013     pRenderHalSurface->iPaletteID                   = pVpSurface->iPalette;
1014 
1015     pRenderHalSurface->bQueryVariance               = pVpSurface->bQueryVariance;
1016     pRenderHalSurface->bInterlacedScaling           = pVpSurface->bInterlacedScaling;
1017     pRenderHalSurface->pDeinterlaceParams           = (void *)pVpSurface->pDeinterlaceParams;
1018     pRenderHalSurface->SampleType                   =
1019                     VpHal_RndrInitRenderHalSampleType(pVpSurface->SampleType);
1020 
1021     pRenderHalSurface->Rotation                     =
1022                     VpHal_RndrInitRotationMode(pVpSurface->Rotation);
1023 
1024 finish:
1025     return eStatus;
1026 }
1027 
1028 //!
1029 //! \brief    Get output RenderHal Surface parameters back to VPHAL Surface
1030 //! \param    [in] pRenderHalSurface
1031 //!           Pointer to the RenderHal surface
1032 //! \param    [in,out] pVpSurface
1033 //!           Pointer to the VPHAL surface
1034 //! \return   MOS_STATUS
1035 //!
VpHal_RndrCommonGetBackVpSurfaceParams(PRENDERHAL_SURFACE pRenderHalSurface,PVPHAL_SURFACE pVpSurface)1036 MOS_STATUS VpHal_RndrCommonGetBackVpSurfaceParams(
1037     PRENDERHAL_SURFACE      pRenderHalSurface,
1038     PVPHAL_SURFACE          pVpSurface)
1039 {
1040     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
1041 
1042     //---------------------------------------
1043     VPHAL_RENDER_CHK_NULL(pVpSurface);
1044     VPHAL_RENDER_CHK_NULL(pRenderHalSurface);
1045     //---------------------------------------
1046 
1047     // The following params are mostly for b32MWColorFillKern on Gen75/Gen8 only
1048     pVpSurface->dwHeight                            = pRenderHalSurface->OsSurface.dwHeight;
1049     pVpSurface->dwPitch                             = pRenderHalSurface->OsSurface.dwPitch;
1050     pVpSurface->Format                              = pRenderHalSurface->OsSurface.Format;
1051     pVpSurface->dwOffset                            = pRenderHalSurface->OsSurface.dwOffset;
1052     pVpSurface->YPlaneOffset.iXOffset               = pRenderHalSurface->OsSurface.YPlaneOffset.iXOffset;
1053     pVpSurface->YPlaneOffset.iYOffset               = pRenderHalSurface->OsSurface.YPlaneOffset.iYOffset;
1054     pVpSurface->UPlaneOffset.iSurfaceOffset         = pRenderHalSurface->OsSurface.UPlaneOffset.iSurfaceOffset;
1055     pVpSurface->VPlaneOffset.iSurfaceOffset         = pRenderHalSurface->OsSurface.VPlaneOffset.iSurfaceOffset;
1056     pVpSurface->rcDst                               = pRenderHalSurface->rcDst;
1057 
1058     pVpSurface->dwWidth                             = pRenderHalSurface->OsSurface.dwWidth;
1059     pVpSurface->ScalingMode                         =
1060                     VpHal_RndrGetVpHalScalingMode(pRenderHalSurface->ScalingMode);
1061 
1062 finish:
1063     return eStatus;
1064 }
1065 
1066 //!
1067 //! \brief    Set Surface for HW Access
1068 //! \details  Common Function for setting up surface state, if render would
1069 //!           use CP HM, need use VpHal_CommonSetSurfaceForHwAccess instead
1070 //! \param    [in] pRenderHal
1071 //!           Pointer to RenderHal Interface Structure
1072 //! \param    [in] pSurface
1073 //!           Pointer to Surface
1074 //! \param    [in] pSurfaceParams
1075 //!           Pointer to RenderHal Surface Params
1076 //! \param    [in] iBindingTable
1077 //!           Binding Table to bind surface
1078 //! \param    [in] iBTEntry
1079 //!           Binding Table Entry index
1080 //! \param    [in] bWrite
1081 //!           Write mode flag
1082 //! \return   MOS_STATUS
1083 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
1084 //!
VpHal_RndrCommonSetSurfaceForHwAccess(PRENDERHAL_INTERFACE pRenderHal,PVPHAL_SURFACE pSurface,PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams,int32_t iBindingTable,int32_t iBTEntry,bool bWrite)1085 MOS_STATUS VpHal_RndrCommonSetSurfaceForHwAccess(
1086     PRENDERHAL_INTERFACE                pRenderHal,
1087     PVPHAL_SURFACE                      pSurface,
1088     PRENDERHAL_SURFACE_STATE_PARAMS     pSurfaceParams,
1089     int32_t                             iBindingTable,
1090     int32_t                             iBTEntry,
1091     bool                                bWrite)
1092 {
1093 
1094     PMOS_INTERFACE                  pOsInterface;
1095     PRENDERHAL_SURFACE_STATE_ENTRY  pSurfaceEntries[MHW_MAX_SURFACE_PLANES];
1096     int32_t                         iSurfaceEntries;
1097     RENDERHAL_SURFACE               RenderHalSurface;
1098     int32_t                         i;
1099     MOS_STATUS                      eStatus;
1100 
1101     // Initialize Variables
1102     eStatus                         = MOS_STATUS_SUCCESS;
1103     pOsInterface                    = pRenderHal->pOsInterface;
1104 
1105     if (pOsInterface->osCpInterface->IsHMEnabled())
1106     {
1107         VPHAL_RENDER_ASSERTMESSAGE("ERROR, need to use VpHal_CommonSetSurfaceForHwAccess if under CP HM.");
1108     }
1109 
1110     // Register surfaces for rendering (GfxAddress/Allocation index)
1111     // Register resource
1112     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(
1113         pOsInterface,
1114         &pSurface->OsResource,
1115         bWrite,
1116         true));
1117 
1118     VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonInitRenderHalSurface(
1119         pSurface,
1120         &RenderHalSurface));
1121 
1122     // Setup surface states-----------------------------------------------------
1123     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetupSurfaceState(
1124         pRenderHal,
1125         &RenderHalSurface,
1126         pSurfaceParams,
1127         &iSurfaceEntries,
1128         pSurfaceEntries,
1129         nullptr));
1130 
1131     VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonGetBackVpSurfaceParams(
1132         &RenderHalSurface,
1133         pSurface));
1134 
1135     // Bind surface states------------------------------------------------------
1136     for (i = 0; i < iSurfaceEntries; i++, iBTEntry++)
1137     {
1138         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnBindSurfaceState(
1139             pRenderHal,
1140             iBindingTable,
1141             iBTEntry,
1142             pSurfaceEntries[i]));
1143     }
1144 
1145 finish:
1146     return eStatus;
1147 }
1148 
1149 //!
1150 //! \brief    Set Buffer Surface for HW Access
1151 //! \details  Common Function for setting up buffer surface state, if render would
1152 //!           use CP HM, need use VpHal_CommonSetBufferSurfaceForHwAccess instead
1153 //! \param    [in] pRenderHal
1154 //!           Pointer to RenderHal Interface Structure
1155 //! \param    [in] pSurface
1156 //!           Pointer to Surface
1157 //! \param    [in,out] pSurfaceParams
1158 //!           Pointer to RenderHal Surface Params
1159 //! \param    [in] iBindingTable
1160 //!           Binding Table to Bind Surface
1161 //! \param    [in] iBTEntry
1162 //!           Binding Table Entry index
1163 //! \param    [in] bWrite
1164 //!           Write mode flag
1165 //! \return   MOS_STATUS
1166 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
1167 //!
VpHal_RndrCommonSetBufferSurfaceForHwAccess(PRENDERHAL_INTERFACE pRenderHal,PVPHAL_SURFACE pSurface,PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams,int32_t iBindingTable,int32_t iBTEntry,bool bWrite)1168 MOS_STATUS VpHal_RndrCommonSetBufferSurfaceForHwAccess(
1169     PRENDERHAL_INTERFACE                pRenderHal,
1170     PVPHAL_SURFACE                      pSurface,
1171     PRENDERHAL_SURFACE_STATE_PARAMS     pSurfaceParams,
1172     int32_t                             iBindingTable,
1173     int32_t                             iBTEntry,
1174     bool                                bWrite)
1175 {
1176     PMOS_INTERFACE                      pOsInterface;
1177     RENDERHAL_SURFACE                   RenderHalSurface;
1178     RENDERHAL_SURFACE_STATE_PARAMS      SurfaceParam;
1179     PRENDERHAL_SURFACE_STATE_ENTRY      pSurfaceEntry;
1180     MOS_STATUS                          eStatus;
1181 
1182     VPHAL_RENDER_CHK_NULL(pRenderHal);
1183     VPHAL_RENDER_CHK_NULL(pRenderHal->pOsInterface);
1184 
1185     // Initialize Variables
1186     eStatus                         = MOS_STATUS_SUCCESS;
1187     pOsInterface                    = pRenderHal->pOsInterface;
1188 
1189     if (pOsInterface->osCpInterface->IsHMEnabled())
1190     {
1191         VPHAL_RENDER_ASSERTMESSAGE("ERROR, need to use VpHal_CommonSetBufferSurfaceForHwAccess if under CP HM.");
1192     }
1193 
1194     // Register surfaces for rendering (GfxAddress/Allocation index)
1195     // Register resource
1196     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(
1197         pOsInterface,
1198         &pSurface->OsResource,
1199         bWrite,
1200         true));
1201 
1202     // Setup Buffer surface-----------------------------------------------------
1203     if (pSurfaceParams == nullptr)
1204     {
1205         MOS_ZeroMemory(&SurfaceParam, sizeof(SurfaceParam));
1206 
1207         //set mem object control for cache
1208         SurfaceParam.MemObjCtl = (pRenderHal->pOsInterface->pfnCachePolicyGetMemoryObject(
1209             MOS_MP_RESOURCE_USAGE_DEFAULT,
1210             pRenderHal->pOsInterface->pfnGetGmmClientContext(pRenderHal->pOsInterface))).DwordValue;
1211 
1212         pSurfaceParams = &SurfaceParam;
1213     }
1214 
1215     VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonInitRenderHalSurface(
1216         pSurface,
1217         &RenderHalSurface));
1218 
1219     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetupBufferSurfaceState(
1220         pRenderHal,
1221         &RenderHalSurface,
1222         pSurfaceParams,
1223         &pSurfaceEntry));
1224 
1225     // Bind surface state-------------------------------------------------------
1226     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnBindSurfaceState(
1227         pRenderHal,
1228         iBindingTable,
1229         iBTEntry,
1230         pSurfaceEntry));
1231 
1232 finish:
1233     return eStatus;
1234 }
1235 
1236 //!
1237 //! \brief    Set Surface for HW Access for CP HM
1238 //! \details  Common Function for setting up surface state, need to use this function
1239 //!           if render would use CP HM
1240 //! \param    [in] pRenderHal
1241 //!           Pointer to RenderHal Interface Structure
1242 //! \param    [in] pSurface
1243 //!           Pointer to Surface
1244 //! \param    [in] pRenderSurface
1245 //!           Pointer to Render Surface
1246 //! \param    [in] pSurfaceParams
1247 //!           Pointer to RenderHal Surface Params
1248 //! \param    [in] iBindingTable
1249 //!           Binding Table to bind surface
1250 //! \param    [in] iBTEntry
1251 //!           Binding Table Entry index
1252 //! \param    [in] bWrite
1253 //!           Write mode flag
1254 //! \return   MOS_STATUS
1255 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
1256 //!
VpHal_CommonSetSurfaceForHwAccess(PRENDERHAL_INTERFACE pRenderHal,PVPHAL_SURFACE pSurface,PRENDERHAL_SURFACE pRenderSurface,PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams,int32_t iBindingTable,int32_t iBTEntry,bool bWrite)1257 MOS_STATUS VpHal_CommonSetSurfaceForHwAccess(
1258     PRENDERHAL_INTERFACE                pRenderHal,
1259     PVPHAL_SURFACE                      pSurface,
1260     PRENDERHAL_SURFACE                  pRenderSurface,
1261     PRENDERHAL_SURFACE_STATE_PARAMS     pSurfaceParams,
1262     int32_t                             iBindingTable,
1263     int32_t                             iBTEntry,
1264     bool                                bWrite)
1265 {
1266 
1267     PMOS_INTERFACE                  pOsInterface;
1268     PRENDERHAL_SURFACE_STATE_ENTRY  pSurfaceEntries[MHW_MAX_SURFACE_PLANES];
1269     int32_t                         iSurfaceEntries;
1270     int32_t                         i;
1271     MOS_STATUS                      eStatus;
1272 
1273     // Initialize Variables
1274     eStatus                         = MOS_STATUS_SUCCESS;
1275     pOsInterface                    = pRenderHal->pOsInterface;
1276 
1277     // Register surfaces for rendering (GfxAddress/Allocation index)
1278     // Register resource
1279     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(
1280         pOsInterface,
1281         &pSurface->OsResource,
1282         bWrite,
1283         true));
1284 
1285     VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonInitRenderHalSurface(
1286         pSurface,
1287         pRenderSurface));
1288 
1289     // Setup surface states-----------------------------------------------------
1290     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetupSurfaceState(
1291         pRenderHal,
1292         pRenderSurface,
1293         pSurfaceParams,
1294         &iSurfaceEntries,
1295         pSurfaceEntries,
1296         nullptr));
1297 
1298     VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonGetBackVpSurfaceParams(
1299         pRenderSurface,
1300         pSurface));
1301 
1302     // Bind surface states------------------------------------------------------
1303     for (i = 0; i < iSurfaceEntries; i++, iBTEntry++)
1304     {
1305         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnBindSurfaceState(
1306             pRenderHal,
1307             iBindingTable,
1308             iBTEntry,
1309             pSurfaceEntries[i]));
1310     }
1311 
1312 finish:
1313     return eStatus;
1314 }
1315 
1316 //!
1317 //! \brief    Set Buffer Surface for HW Access for CP HM
1318 //! \details  Common Function for setting up buffer surface state, need to use this function
1319 //!           if render would use CP HM
1320 //! \param    [in] pRenderHal
1321 //!           Pointer to RenderHal Interface Structure
1322 //! \param    [in] pSurface
1323 //!           Pointer to Surface
1324 //! \param    [in] pRenderSurface
1325 //!           Pointer to Render Surface
1326 //! \param    [in,out] pSurfaceParams
1327 //!           Pointer to RenderHal Surface Params
1328 //! \param    [in] iBindingTable
1329 //!           Binding Table to Bind Surface
1330 //! \param    [in] iBTEntry
1331 //!           Binding Table Entry index
1332 //! \param    [in] bWrite
1333 //!           Write mode flag
1334 //! \return   MOS_STATUS
1335 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
1336 //!
VpHal_CommonSetBufferSurfaceForHwAccess(PRENDERHAL_INTERFACE pRenderHal,PVPHAL_SURFACE pSurface,PRENDERHAL_SURFACE pRenderSurface,PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams,int32_t iBindingTable,int32_t iBTEntry,bool bWrite)1337 MOS_STATUS VpHal_CommonSetBufferSurfaceForHwAccess(
1338     PRENDERHAL_INTERFACE                pRenderHal,
1339     PVPHAL_SURFACE                      pSurface,
1340     PRENDERHAL_SURFACE                  pRenderSurface,
1341     PRENDERHAL_SURFACE_STATE_PARAMS     pSurfaceParams,
1342     int32_t                             iBindingTable,
1343     int32_t                             iBTEntry,
1344     bool                                bWrite)
1345 {
1346     PMOS_INTERFACE                      pOsInterface;
1347     RENDERHAL_SURFACE_STATE_PARAMS      SurfaceParam;
1348     PRENDERHAL_SURFACE_STATE_ENTRY      pSurfaceEntry;
1349     MOS_STATUS                          eStatus;
1350 
1351     VPHAL_RENDER_CHK_NULL(pRenderHal);
1352     VPHAL_RENDER_CHK_NULL(pRenderHal->pOsInterface);
1353 
1354     // Initialize Variables
1355     eStatus                         = MOS_STATUS_SUCCESS;
1356     pOsInterface                    = pRenderHal->pOsInterface;
1357 
1358     // Register surfaces for rendering (GfxAddress/Allocation index)
1359     // Register resource
1360     VPHAL_RENDER_CHK_STATUS(pOsInterface->pfnRegisterResource(
1361         pOsInterface,
1362         &pSurface->OsResource,
1363         bWrite,
1364         true));
1365 
1366     // Setup Buffer surface-----------------------------------------------------
1367     if (pSurfaceParams == nullptr)
1368     {
1369         MOS_ZeroMemory(&SurfaceParam, sizeof(SurfaceParam));
1370 
1371         //set mem object control for cache
1372         SurfaceParam.MemObjCtl = (pRenderHal->pOsInterface->pfnCachePolicyGetMemoryObject(
1373             MOS_MP_RESOURCE_USAGE_DEFAULT,
1374             pRenderHal->pOsInterface->pfnGetGmmClientContext(pRenderHal->pOsInterface))).DwordValue;
1375 
1376         pSurfaceParams = &SurfaceParam;
1377     }
1378 
1379     VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonInitRenderHalSurface(
1380         pSurface,
1381         pRenderSurface));
1382 
1383     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetupBufferSurfaceState(
1384         pRenderHal,
1385         pRenderSurface,
1386         pSurfaceParams,
1387         &pSurfaceEntry));
1388 
1389     // Bind surface state-------------------------------------------------------
1390     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnBindSurfaceState(
1391         pRenderHal,
1392         iBindingTable,
1393         iBTEntry,
1394         pSurfaceEntry));
1395 
1396 finish:
1397     return eStatus;
1398 }
1399 
1400 //!
1401 //! \brief      Is Alignment WA needed
1402 //! \details    Decide WA is needed for VEBOX/Render engine
1403 //!             RENDER limitation with composition BOB:
1404 //!             Height should be a multiple of 4, otherwise disable DI in Comp
1405 //!             VEBOX limitation with TiledY NV12 input(Gen75):
1406 //!             Height should be a multiple of 4, otherwise bypass adv render
1407 //!             VEBOX limitation with TiledY NV12 input(Gen8/9):
1408 //!             3D/GMM regresses to allocate linear surface when height is not
1409 //!             a multiple of 4, no need to bypass adv render
1410 //! \param      [in] pSurface
1411 //!             Input surface
1412 //! \param      [in] GpuContext
1413 //!             GpuContext to indicate Render/Vebox
1414 //! \return     bool
1415 //!             true - Solution is needed; false - Solution is not needed
1416 //!
VpHal_RndrCommonIsAlignmentWANeeded(PVPHAL_SURFACE pSurface,MOS_GPU_CONTEXT GpuContext)1417 bool VpHal_RndrCommonIsAlignmentWANeeded(
1418     PVPHAL_SURFACE             pSurface,
1419     MOS_GPU_CONTEXT            GpuContext)
1420 {
1421     bool bRetVal;
1422 
1423     switch (GpuContext)
1424     {
1425         case MOS_GPU_CONTEXT_RENDER:
1426         case MOS_GPU_CONTEXT_VEBOX:
1427         case MOS_GPU_CONTEXT_RENDER3:
1428         case MOS_GPU_CONTEXT_RENDER4:
1429         case MOS_GPU_CONTEXT_COMPUTE:
1430         case MOS_GPU_CONTEXT_COMPUTE_RA:
1431         case MOS_GPU_CONTEXT_RENDER_RA:
1432             if (!(MOS_IS_ALIGNED(MOS_MIN((uint32_t)pSurface->dwHeight, (uint32_t)pSurface->rcMaxSrc.bottom), 4)) &&
1433                 (pSurface->Format == Format_NV12))
1434             {
1435                 bRetVal = true;
1436             }
1437             else
1438             {
1439                 bRetVal = false;
1440             }
1441             break;
1442 
1443         default:
1444             VPHAL_RENDER_ASSERTMESSAGE("Incorrect GPU context: %d.", GpuContext);
1445             bRetVal = false;
1446             break;
1447     }
1448 
1449     return bRetVal;
1450 }
1451 
1452 //!
1453 //! \brief      Sets AVS table
1454 //! \details    Set 4-tap or 8-tap filtering AVS table
1455 //! \param      [in] pAvsParams
1456 //!             Pointer to avs parameter
1457 //! \param      [in,out] pMhwSamplerAvsTableParam
1458 //!             Pointer to avs table parameter
1459 //! \return     MOS_STATUS
1460 //!
VpHal_RenderCommonSetAVSTableParam(PMHW_AVS_PARAMS pAvsParams,PMHW_SAMPLER_AVS_TABLE_PARAM pMhwSamplerAvsTableParam)1461 MOS_STATUS VpHal_RenderCommonSetAVSTableParam(
1462     PMHW_AVS_PARAMS              pAvsParams,
1463     PMHW_SAMPLER_AVS_TABLE_PARAM pMhwSamplerAvsTableParam)
1464 {
1465     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1466     int32_t        iCoeffTableIdx;
1467     int32_t        iFilterCoeffIdx;
1468     int32_t*       piYCoefsX;
1469     int32_t*       piYCoefsY;
1470     int32_t*       piUVCoefsX;
1471     int32_t*       piUVCoefsY;
1472 
1473     VPHAL_RENDER_CHK_NULL(pAvsParams);
1474     VPHAL_RENDER_CHK_NULL(pMhwSamplerAvsTableParam);
1475     VPHAL_RENDER_CHK_NULL(pAvsParams->piYCoefsX);
1476     VPHAL_RENDER_CHK_NULL(pAvsParams->piYCoefsY);
1477     VPHAL_RENDER_CHK_NULL(pAvsParams->piUVCoefsX);
1478     VPHAL_RENDER_CHK_NULL(pAvsParams->piUVCoefsY);
1479 
1480     piYCoefsX  = pAvsParams->piYCoefsX;
1481     piYCoefsY  = pAvsParams->piYCoefsY;
1482     piUVCoefsX = pAvsParams->piUVCoefsX;
1483     piUVCoefsY = pAvsParams->piUVCoefsY;
1484 
1485     for (iCoeffTableIdx = 0; iCoeffTableIdx < MHW_NUM_HW_POLYPHASE_TABLES; iCoeffTableIdx++)
1486     {
1487         PMHW_AVS_COEFFICIENT_PARAM pCoeffTable = &pMhwSamplerAvsTableParam->paMhwAvsCoeffParam[iCoeffTableIdx];
1488         // 4-tap filtering for G-channel, update only center 4 coeffs.
1489         if (pMhwSamplerAvsTableParam->b4TapGY)
1490         {
1491             pCoeffTable->ZeroXFilterCoefficient[0] = 0;
1492             pCoeffTable->ZeroXFilterCoefficient[1] = 0;
1493             pCoeffTable->ZeroXFilterCoefficient[2] = (int8_t)*(piYCoefsX++);
1494             pCoeffTable->ZeroXFilterCoefficient[3] = (int8_t)*(piYCoefsX++);
1495             pCoeffTable->ZeroXFilterCoefficient[4] = (int8_t)*(piYCoefsX++);
1496             pCoeffTable->ZeroXFilterCoefficient[5] = (int8_t)*(piYCoefsX++);
1497             pCoeffTable->ZeroXFilterCoefficient[6] = 0;
1498             pCoeffTable->ZeroXFilterCoefficient[7] = 0;
1499 
1500             pCoeffTable->ZeroYFilterCoefficient[0] = 0;
1501             pCoeffTable->ZeroYFilterCoefficient[1] = 0;
1502             pCoeffTable->ZeroYFilterCoefficient[2] = (int8_t)*(piYCoefsY++);
1503             pCoeffTable->ZeroYFilterCoefficient[3] = (int8_t)*(piYCoefsY++);
1504             pCoeffTable->ZeroYFilterCoefficient[4] = (int8_t)*(piYCoefsY++);
1505             pCoeffTable->ZeroYFilterCoefficient[5] = (int8_t)*(piYCoefsY++);
1506             pCoeffTable->ZeroYFilterCoefficient[6] = 0;
1507             pCoeffTable->ZeroYFilterCoefficient[7] = 0;
1508         }
1509         else // for gen8+, using 8-tap filter
1510         {
1511             for (iFilterCoeffIdx = 0; iFilterCoeffIdx < 8; iFilterCoeffIdx++)
1512             {
1513                 pCoeffTable->ZeroXFilterCoefficient[iFilterCoeffIdx] = (int8_t)*(piYCoefsX++);
1514                 pCoeffTable->ZeroYFilterCoefficient[iFilterCoeffIdx] = (int8_t)*(piYCoefsY++);
1515             }
1516         }
1517 
1518         // If 8-tap adaptive filter is enabled, then UV/RB will share the same coefficients with Y/G
1519         if (pMhwSamplerAvsTableParam->b4TapRBUV)
1520         {
1521             // [0..3] maps to filter coefficients [2..5], in actual table [0..1] are reserved
1522             for (iFilterCoeffIdx = 0; iFilterCoeffIdx < 4; iFilterCoeffIdx++)
1523             {
1524                 pCoeffTable->OneXFilterCoefficient[iFilterCoeffIdx] = (int8_t)*(piUVCoefsX++);
1525                 pCoeffTable->OneYFilterCoefficient[iFilterCoeffIdx] = (int8_t)*(piUVCoefsY++);
1526             }
1527         }
1528     }
1529 
1530     if (pMhwSamplerAvsTableParam->bIsCoeffExtraEnabled)
1531     {
1532         for (iCoeffTableIdx = 0; iCoeffTableIdx < MHW_NUM_HW_POLYPHASE_EXTRA_TABLES_G9; iCoeffTableIdx++)
1533         {
1534             PMHW_AVS_COEFFICIENT_PARAM pCoeffTable = &pMhwSamplerAvsTableParam->paMhwAvsCoeffParamExtra[iCoeffTableIdx];
1535             // 4-tap filtering for G-channel, update only center 4 coeffs.
1536             if (pMhwSamplerAvsTableParam->b4TapGY)
1537             {
1538                 pCoeffTable->ZeroXFilterCoefficient[0] = 0;
1539                 pCoeffTable->ZeroXFilterCoefficient[1] = 0;
1540                 pCoeffTable->ZeroXFilterCoefficient[2] = (int8_t)*(piYCoefsX++);
1541                 pCoeffTable->ZeroXFilterCoefficient[3] = (int8_t)*(piYCoefsX++);
1542                 pCoeffTable->ZeroXFilterCoefficient[4] = (int8_t)*(piYCoefsX++);
1543                 pCoeffTable->ZeroXFilterCoefficient[5] = (int8_t)*(piYCoefsX++);
1544                 pCoeffTable->ZeroXFilterCoefficient[6] = 0;
1545                 pCoeffTable->ZeroXFilterCoefficient[7] = 0;
1546 
1547                 pCoeffTable->ZeroYFilterCoefficient[0] = 0;
1548                 pCoeffTable->ZeroYFilterCoefficient[1] = 0;
1549                 pCoeffTable->ZeroYFilterCoefficient[2] = (int8_t)*(piYCoefsY++);
1550                 pCoeffTable->ZeroYFilterCoefficient[3] = (int8_t)*(piYCoefsY++);
1551                 pCoeffTable->ZeroYFilterCoefficient[4] = (int8_t)*(piYCoefsY++);
1552                 pCoeffTable->ZeroYFilterCoefficient[5] = (int8_t)*(piYCoefsY++);
1553                 pCoeffTable->ZeroYFilterCoefficient[6] = 0;
1554                 pCoeffTable->ZeroYFilterCoefficient[7] = 0;
1555             }
1556             else
1557             {
1558                 for (iFilterCoeffIdx = 0; iFilterCoeffIdx < 8; iFilterCoeffIdx++)
1559                 {
1560                     pCoeffTable->ZeroXFilterCoefficient[iFilterCoeffIdx] = (int8_t)*(piYCoefsX++);
1561                     pCoeffTable->ZeroYFilterCoefficient[iFilterCoeffIdx] = (int8_t)*(piYCoefsY++);
1562                 }
1563             }
1564 
1565             // If 8-tap adaptive filter is enabled, then UV/RB will share the same coefficients with Y/G
1566             if (pMhwSamplerAvsTableParam->b4TapRBUV)
1567             {
1568                 for (iFilterCoeffIdx = 0; iFilterCoeffIdx < 4; iFilterCoeffIdx++)
1569                 {
1570                     // [0..3] maps to filter coefficients [2..5], in actual table [0..1] are reserved
1571                     pCoeffTable->OneXFilterCoefficient[iFilterCoeffIdx] = (int8_t)*(piUVCoefsX++);
1572                     pCoeffTable->OneYFilterCoefficient[iFilterCoeffIdx] = (int8_t)*(piUVCoefsY++);
1573                 }
1574             }
1575         }
1576     }
1577 
1578 finish:
1579     return eStatus;
1580 }
1581 
1582 //!
1583 //! \brief    Initialize AVS parameters shared by Renderers
1584 //! \details  Initialize the members of the AVS parameter and allocate memory for its coefficient tables
1585 //! \param    [in,out] pAVS_Params
1586 //!           Pointer to MHW AVS parameter
1587 //! \param    [in] uiYCoeffTableSize
1588 //!           Size of the Y coefficient table
1589 //! \param    [in] uiUVCoeffTableSize
1590 //!           Size of the UV coefficient table
1591 //! \return   MOS_STATUS
1592 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1593 //!
VpHal_RndrCommonInitAVSParams(PMHW_AVS_PARAMS pAVS_Params,uint32_t uiYCoeffTableSize,uint32_t uiUVCoeffTableSize)1594 MOS_STATUS VpHal_RndrCommonInitAVSParams(
1595     PMHW_AVS_PARAMS     pAVS_Params,
1596     uint32_t            uiYCoeffTableSize,
1597     uint32_t            uiUVCoeffTableSize)
1598 {
1599     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
1600     int32_t     size;
1601     char*       ptr;
1602 
1603     VPHAL_RENDER_CHK_NULL(pAVS_Params);
1604     VPHAL_RENDER_CHK_NULL((void*)(uiYCoeffTableSize > 0));
1605     VPHAL_RENDER_CHK_NULL((void*)(uiUVCoeffTableSize > 0));
1606 
1607     // Init AVS parameters
1608     pAVS_Params->Format    = Format_None;
1609     pAVS_Params->fScaleX   = 0.0F;
1610     pAVS_Params->fScaleY   = 0.0F;
1611     pAVS_Params->piYCoefsX = nullptr;
1612 
1613     // Allocate AVS coefficients, One set each for X and Y
1614     size = (uiYCoeffTableSize + uiUVCoeffTableSize) * 2;
1615 
1616     ptr = (char*)MOS_AllocAndZeroMemory(size);
1617     if (ptr == nullptr)
1618     {
1619         VPHAL_RENDER_ASSERTMESSAGE("No memory to allocate AVS coefficient tables.");
1620         eStatus = MOS_STATUS_NO_SPACE;
1621         goto finish;
1622     }
1623 
1624     pAVS_Params->piYCoefsX = (int32_t*)ptr;
1625 
1626     ptr += uiYCoeffTableSize;
1627     pAVS_Params->piUVCoefsX = (int32_t*)ptr;
1628 
1629     ptr += uiUVCoeffTableSize;
1630     pAVS_Params->piYCoefsY  = (int32_t*)ptr;
1631 
1632     ptr += uiYCoeffTableSize;
1633     pAVS_Params->piUVCoefsY = (int32_t*)ptr;
1634 
1635 finish:
1636     return eStatus;
1637 }
1638 
1639 //!
1640 //! \brief    Destroy AVS parameters shared by Renderers
1641 //! \details  Free the memory of AVS parameter's coefficient tables
1642 //! \param    [in,out] pAVS_Params
1643 //!           Pointer to VPHAL AVS parameter
1644 //! \return   void
1645 //!
VpHal_RndrCommonDestroyAVSParams(PMHW_AVS_PARAMS pAVS_Params)1646 void VpHal_RndrCommonDestroyAVSParams(
1647     PMHW_AVS_PARAMS   pAVS_Params)
1648 {
1649     VPHAL_RENDER_ASSERT(pAVS_Params);
1650     MOS_SafeFreeMemory(pAVS_Params->piYCoefsX);
1651     pAVS_Params->piYCoefsX = nullptr;
1652 }
1653 
1654 //!
1655 //! \brief    update status report rely on command buffer sync tag
1656 //! \param    [in] pOsInterface
1657 //!           pointer to os interface
1658 //! \param    [in,out] pStatusTableUpdateParams
1659 //!           pointer to STATUS_TABLE_UPDATE_PARAMS for updating status table
1660 //! \param    [in] eMosGpuContext
1661 //!           current mos contexnt enum
1662 //! \param    [in] eLastStatus
1663 //!           indicating last submition is successful or not
1664 //! \return   MOS_STATUS
1665 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1666 //!
VpHal_RndrUpdateStatusTableAfterSubmit(PMOS_INTERFACE pOsInterface,PSTATUS_TABLE_UPDATE_PARAMS pStatusTableUpdateParams,MOS_GPU_CONTEXT eMosGpuContext,MOS_STATUS eLastStatus)1667 MOS_STATUS VpHal_RndrUpdateStatusTableAfterSubmit(
1668     PMOS_INTERFACE                  pOsInterface,
1669     PSTATUS_TABLE_UPDATE_PARAMS     pStatusTableUpdateParams,
1670     MOS_GPU_CONTEXT                 eMosGpuContext,
1671     MOS_STATUS                      eLastStatus)
1672 {
1673     PVPHAL_STATUS_ENTRY             pStatusEntry;
1674     bool                            bEmptyTable;
1675     MOS_STATUS                      eStatus;
1676     uint32_t                        dwLastTag;
1677     PVPHAL_STATUS_TABLE             pStatusTable;
1678     uint32_t                        dwStatusFeedBackID;
1679 
1680     VPHAL_RENDER_CHK_NULL(pStatusTableUpdateParams);
1681     eStatus = MOS_STATUS_SUCCESS;
1682 
1683     if (!pStatusTableUpdateParams->bReportStatus ||
1684         !pStatusTableUpdateParams->bSurfIsRenderTarget)
1685     {
1686         goto finish;
1687     }
1688 
1689     VPHAL_RENDER_CHK_NULL(pStatusTableUpdateParams->pStatusTable);
1690     VPHAL_RENDER_CHK_NULL(pOsInterface);
1691 
1692     pStatusTable       = pStatusTableUpdateParams->pStatusTable;
1693     dwStatusFeedBackID = pStatusTableUpdateParams->StatusFeedBackID;
1694 
1695     VPHAL_RENDER_ASSERT(pStatusTable->uiHead < VPHAL_STATUS_TABLE_MAX_SIZE);
1696     VPHAL_RENDER_ASSERT(pStatusTable->uiCurrent < VPHAL_STATUS_TABLE_MAX_SIZE);
1697 
1698     bEmptyTable = (pStatusTable->uiCurrent == pStatusTable->uiHead);
1699     if (!bEmptyTable)
1700     {
1701         uint32_t uiLast                 = (pStatusTable->uiCurrent - 1) & (VPHAL_STATUS_TABLE_MAX_SIZE - 1);
1702         bool bSameFrameIdWithLastRender = (pStatusTable->aTableEntries[uiLast].StatusFeedBackID == dwStatusFeedBackID);
1703         if (bSameFrameIdWithLastRender)
1704         {
1705             pStatusTable->uiCurrent = uiLast;
1706         }
1707     }
1708 
1709     pStatusEntry                    = &pStatusTable->aTableEntries[pStatusTable->uiCurrent];
1710     pStatusEntry->StatusFeedBackID  = dwStatusFeedBackID;
1711     pStatusEntry->GpuContextOrdinal = eMosGpuContext;
1712     dwLastTag                       = pOsInterface->pfnGetGpuStatusTag(pOsInterface, eMosGpuContext) - 1;
1713     pStatusEntry->dwTag             = dwLastTag;
1714     pStatusEntry->dwStatus          = (eLastStatus == MOS_STATUS_SUCCESS)? VPREP_NOTREADY : VPREP_ERROR;
1715     pStatusTable->uiCurrent         = (pStatusTable->uiCurrent + 1) & (VPHAL_STATUS_TABLE_MAX_SIZE - 1);
1716 
1717     // CM may use a different streamIndex, record it here
1718     if (pStatusTableUpdateParams->bUpdateStreamIndex)
1719     {
1720         pStatusEntry->isStreamIndexSet = true;
1721         pStatusEntry->streamIndex = (uint16_t)pOsInterface->streamIndex;
1722     }
1723     else
1724     {
1725         pStatusEntry->isStreamIndexSet = false;
1726     }
1727 
1728 finish:
1729     return eStatus;
1730 }
1731