1 /*
2 * Copyright (c) 2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     media_render_common.c
24 //! \brief    The file of common utilities definitions shared by low level renderers
25 //! \details  Common utilities for different renderers
26 //!
27 #include "media_render_common.h"
28 #include "hal_oca_interface_next.h"
29 #include "renderhal_platform_interface.h"
30 //!
31 //! \brief    Determine if the Batch Buffer End is needed to add in the end
32 //! \details  Detect platform OS and return the flag whether the Batch Buffer End is needed to add in the end
33 //! \param    [in] pOsInterface
34 //!           Pointer to MOS_INTERFACE
35 //! \return   bool
36 //!           The flag of adding Batch Buffer End
37 //!
IsMiBBEndNeeded(PMOS_INTERFACE pOsInterface)38 static bool IsMiBBEndNeeded(
39     PMOS_INTERFACE           pOsInterface)
40 {
41     bool needed = true;
42     return needed;
43 }
44 
45 //!
46 //! \brief    init render hal surface.
47 //! \details  fill render hal surface's paramters
48 //! \param    [in] pSurface
49 //!           Pointer to PMOS_SURFACE
50 //! \param    [in] pRenderHalSurface
51 //!           Pointer to PRENDERHAL_SURFACE
52 //! \return   MOS_STATUS
53 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
54 //!
InitRenderHalSurface(PMOS_INTERFACE pOsInterface,PMOS_SURFACE pSurface,PRENDERHAL_SURFACE pRenderHalSurface)55 static MOS_STATUS InitRenderHalSurface(
56     PMOS_INTERFACE          pOsInterface,
57     PMOS_SURFACE            pSurface,
58     PRENDERHAL_SURFACE      pRenderHalSurface)
59 {
60     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
61 
62     if (nullptr == pSurface || nullptr == pOsInterface || nullptr == pRenderHalSurface)
63     {
64         return MOS_STATUS_NULL_POINTER;
65     }
66 
67     MOS_ZeroMemory(pRenderHalSurface, sizeof(*pRenderHalSurface));
68 
69     pRenderHalSurface->OsSurface.OsResource = pSurface->OsResource;
70     pRenderHalSurface->OsSurface.dwWidth = pSurface->dwWidth;
71     pRenderHalSurface->OsSurface.dwHeight = pSurface->dwHeight;
72     pRenderHalSurface->OsSurface.dwPitch = pSurface->dwPitch;
73     pRenderHalSurface->OsSurface.Format = pSurface->Format;
74     pRenderHalSurface->OsSurface.TileType = pSurface->TileType;
75     pRenderHalSurface->OsSurface.TileModeGMM = pSurface->TileModeGMM;
76     pRenderHalSurface->OsSurface.bGMMTileEnabled = pSurface->bGMMTileEnabled;
77     pRenderHalSurface->OsSurface.dwOffset = pSurface->dwOffset;
78     pRenderHalSurface->OsSurface.bIsCompressed = pSurface->bIsCompressed;
79     pRenderHalSurface->OsSurface.bCompressible = pSurface->bCompressible;
80     pRenderHalSurface->OsSurface.CompressionMode = pSurface->CompressionMode;
81     pRenderHalSurface->OsSurface.dwDepth = pSurface->dwDepth;
82     pRenderHalSurface->OsSurface.dwQPitch = pSurface->dwHeight;
83     pRenderHalSurface->OsSurface.MmcState = (MOS_MEMCOMP_STATE)pSurface->CompressionMode;
84     pRenderHalSurface->OsSurface.CompressionFormat = pSurface->CompressionFormat;
85 
86     pRenderHalSurface->OsSurface.YPlaneOffset = pSurface->YPlaneOffset;
87     pRenderHalSurface->OsSurface.UPlaneOffset = pSurface->UPlaneOffset;
88     pRenderHalSurface->OsSurface.VPlaneOffset = pSurface->VPlaneOffset;
89     pRenderHalSurface->SurfType = RENDERHAL_SURF_OUT_RENDERTARGET;
90 
91     MOS_SURFACE    ResDetails = {0};
92     MHW_RENDERHAL_ASSERT(!Mos_ResourceIsNull(&pSurface->OsResource));
93     ResDetails.Format = pSurface->Format;
94     MHW_CHK_STATUS_RETURN(pOsInterface->pfnGetResourceInfo(pOsInterface, &pSurface->OsResource, &ResDetails));
95 
96     pRenderHalSurface->rcSrc.bottom = pSurface->dwHeight;
97     pRenderHalSurface->rcSrc.right = ResDetails.dwWidth;
98     pRenderHalSurface->rcDst.bottom = pSurface->dwHeight;
99     pRenderHalSurface->rcDst.right = ResDetails.dwWidth;
100     pRenderHalSurface->rcMaxSrc.bottom = pSurface->dwHeight;
101     pRenderHalSurface->rcMaxSrc.right = ResDetails.dwWidth;
102     pRenderHalSurface->OsSurface.dwQPitch = pSurface->dwHeight;
103 
104     return MOS_STATUS_SUCCESS;
105 }
106 //!
107 //! \brief    Set 2D Surface for HW Access
108 //! \details  Common Function for setting up buffer surface state, need to use this function
109 //! \param    [in] pRenderHal
110 //!           Pointer to RenderHal Interface Structure
111 //! \param    [in] pSurface
112 //!           Pointer to Surface
113 //! \param    [in] pRenderSurface
114 //!           Pointer to Render Surface
115 //! \param    [in] pSurfaceParams
116 //!           Pointer to RenderHal Surface Params
117 //! \param    [in] iBindingTable
118 //!           Binding Table to bind surface
119 //! \param    [in] iBTEntry
120 //!           Binding Table Entry index
121 //! \param    [in] bWrite
122 //!           Write mode flag
123 //! \return   MOS_STATUS
124 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
125 //!
Set2DSurfaceForHwAccess(PRENDERHAL_INTERFACE pRenderHal,PMOS_SURFACE pSurface,PRENDERHAL_SURFACE pRenderSurface,PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams,int32_t iBindingTable,int32_t iBTEntry,bool bWrite)126 MOS_STATUS MediaRenderCommon::Set2DSurfaceForHwAccess(
127     PRENDERHAL_INTERFACE                pRenderHal,
128     PMOS_SURFACE                        pSurface,
129     PRENDERHAL_SURFACE                  pRenderSurface,
130     PRENDERHAL_SURFACE_STATE_PARAMS     pSurfaceParams,
131     int32_t                             iBindingTable,
132     int32_t                             iBTEntry,
133     bool                                bWrite)
134 {
135 
136     PMOS_INTERFACE                  pOsInterface;
137     PRENDERHAL_SURFACE_STATE_ENTRY  pSurfaceEntries[MHW_MAX_SURFACE_PLANES] = {0};
138     int32_t                         iSurfaceEntries = 0;
139     int32_t                         i = 0;
140     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
141 
142     if (nullptr == pRenderHal || nullptr == pRenderHal->pOsInterface || nullptr == pRenderSurface || nullptr == pSurface)
143     {
144         return MOS_STATUS_NULL_POINTER;
145     }
146 
147     // Initialize Variables
148     pOsInterface = pRenderHal->pOsInterface;
149 
150     // Register surfaces for rendering (GfxAddress/Allocation index)
151     // Register resource
152     pOsInterface->pfnRegisterResource(
153         pOsInterface,
154         &pSurface->OsResource,
155         bWrite,
156         true);
157 
158     RENDERHAL_GET_SURFACE_INFO info;
159     MOS_ZeroMemory(&info, sizeof(info));
160     MHW_CHK_STATUS_RETURN(RenderHal_GetSurfaceInfo(
161         pRenderHal->pOsInterface,
162         &info,
163         pSurface));
164 
165     pRenderSurface->OsSurface = *pSurface;
166     pRenderSurface->rcSrc.bottom       = pSurface->dwHeight;
167     pRenderSurface->rcSrc.right        = pSurface->dwWidth;
168     pRenderSurface->rcDst.bottom       = pSurface->dwHeight;
169     pRenderSurface->rcDst.right        = pSurface->dwWidth;
170     pRenderSurface->rcMaxSrc.bottom    = pSurface->dwHeight;
171     pRenderSurface->rcMaxSrc.right     = pSurface->dwWidth;
172     pRenderSurface->OsSurface.dwQPitch = pSurface->dwHeight;
173 
174     if (bWrite)
175     {
176         pRenderSurface->SurfType = RENDERHAL_SURF_OUT_RENDERTARGET;
177 
178         // Widthscalar is 2 for RENDERHAL_PLANES_Y210_RT (Plane definition) layout
179         if (pRenderSurface->OsSurface.Format == Format_Y210 || pRenderSurface->OsSurface.Format == Format_Y216)
180         {
181             pRenderSurface->rcDst.right       = pSurface->dwWidth * 2;
182             pRenderSurface->OsSurface.dwWidth = pSurface->dwWidth * 2;
183         }
184     }
185 
186     // Setup surface states-----------------------------------------------------
187     MHW_CHK_STATUS_RETURN(pRenderHal->pfnSetupSurfaceState(
188         pRenderHal,
189         pRenderSurface,
190         pSurfaceParams,
191         &iSurfaceEntries,
192         pSurfaceEntries,
193         nullptr));
194 
195     // Bind surface states------------------------------------------------------
196     for (i = 0; i < iSurfaceEntries; i++, iBTEntry++)
197     {
198         MHW_CHK_STATUS_RETURN(pRenderHal->pfnBindSurfaceState(
199             pRenderHal,
200             iBindingTable,
201             iBTEntry,
202             pSurfaceEntries[i]));
203     }
204 
205     return eStatus;
206 }
207 
208 //!
209 //! \brief    Set 1D Surface for HW Access
210 //! \details  Common Function for setting up buffer surface state, need to use this function
211 //! \param    [in] pRenderHal
212 //!           Pointer to RenderHal Interface Structure
213 //! \param    [in] pSurface
214 //!           Pointer to Surface
215 //! \param    [in] pRenderSurface
216 //!           Pointer to Render Surface
217 //! \param    [in,out] pSurfaceParams
218 //!           Pointer to RenderHal Surface Params
219 //! \param    [in] iBindingTable
220 //!           Binding Table to Bind Surface
221 //! \param    [in] iBTEntry
222 //!           Binding Table Entry index
223 //! \param    [in] bWrite
224 //!           Write mode flag
225 //! \return   MOS_STATUS
226 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
227 //!
Set1DSurfaceForHwAccess(PRENDERHAL_INTERFACE pRenderHal,PMOS_SURFACE pSurface,PRENDERHAL_SURFACE pRenderSurface,PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams,int32_t iBindingTable,int32_t iBTEntry,bool bWrite)228 MOS_STATUS MediaRenderCommon::Set1DSurfaceForHwAccess(
229     PRENDERHAL_INTERFACE                pRenderHal,
230     PMOS_SURFACE                        pSurface,
231     PRENDERHAL_SURFACE                  pRenderSurface,
232     PRENDERHAL_SURFACE_STATE_PARAMS     pSurfaceParams,
233     int32_t                             iBindingTable,
234     int32_t                             iBTEntry,
235     bool                                bWrite)
236 {
237     PMOS_INTERFACE                      pOsInterface;
238     RENDERHAL_SURFACE_STATE_PARAMS      SurfaceParam;
239     PRENDERHAL_SURFACE_STATE_ENTRY      pSurfaceEntry;
240     MOS_FORMAT                          tempformat = Format_Any;
241     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
242 
243     if (nullptr == pRenderHal || nullptr == pRenderHal->pOsInterface || nullptr == pRenderSurface || nullptr == pSurface)
244     {
245         return MOS_STATUS_NULL_POINTER;
246     }
247 
248     // Initialize Variables
249     eStatus = MOS_STATUS_SUCCESS;
250     pOsInterface = pRenderHal->pOsInterface;
251 
252     // Register surfaces for rendering (GfxAddress/Allocation index)
253     // Register resource
254     MHW_CHK_STATUS_RETURN(pOsInterface->pfnRegisterResource(
255         pOsInterface,
256         &pSurface->OsResource,
257         bWrite,
258         true));
259 
260     // Setup Buffer surface-----------------------------------------------------
261     if (pSurfaceParams == nullptr)
262     {
263         MOS_ZeroMemory(&SurfaceParam, sizeof(SurfaceParam));
264 
265         //set mem object control for cache
266         SurfaceParam.MemObjCtl = (pRenderHal->pOsInterface->pfnCachePolicyGetMemoryObject(
267             MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_RENDER,
268             pRenderHal->pOsInterface->pfnGetGmmClientContext(pRenderHal->pOsInterface))).DwordValue;
269 
270         pSurfaceParams = &SurfaceParam;
271     }
272 
273     MHW_CHK_STATUS_RETURN(InitRenderHalSurface(pOsInterface, pSurface, pRenderSurface));
274     MHW_CHK_STATUS_RETURN(pRenderHal->pfnSetupBufferSurfaceState(
275         pRenderHal,
276         pRenderSurface,
277         pSurfaceParams,
278         &pSurfaceEntry));
279 
280     // Bind surface state-------------------------------------------------------
281     MHW_CHK_STATUS_RETURN(pRenderHal->pfnBindSurfaceState(
282         pRenderHal,
283         iBindingTable,
284         iBTEntry,
285         pSurfaceEntry));
286 
287     return eStatus;
288 }
289 
SetPowerMode(PRENDERHAL_INTERFACE pRenderHal,uint32_t KernelID)290 MOS_STATUS MediaRenderCommon::SetPowerMode(
291     PRENDERHAL_INTERFACE              pRenderHal,
292     uint32_t                          KernelID)
293 {
294     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
295     uint16_t                            wNumRequestedEUSlices = 1;    // Default to 1 slice
296     uint16_t                            wNumRequestedSubSlices = 3;    // Default to 3 subslice
297     uint16_t                            wNumRequestedEUs = 8;    // Default to 8 EUs
298     RENDERHAL_POWEROPTION               PowerOption;
299     bool                                bSetRequestedSlices = false;
300     const euSetting                    *pcSSEUTable = nullptr;
301     MediaUserSettingSharedPtr           userSettingPtr = nullptr;
302     uint32_t                            value = 0;
303 
304     MHW_CHK_NULL_RETURN(pRenderHal);
305 
306     if ((pRenderHal->bRequestSingleSlice) || (pRenderHal->bEUSaturationNoSSD))
307     {
308         bSetRequestedSlices = true;
309         // bEUSaturationNoSSD: No slice shutdown, must request 2 slices [CM EU saturation on].
310         // bRequestSingleSlice: Always single slice.
311         wNumRequestedEUSlices = (pRenderHal->bEUSaturationNoSSD) ? 2 : 1;
312     }
313     else
314     {
315         bSetRequestedSlices = false;
316     }
317 
318     if (pRenderHal->sseuTable)
319     {
320         pcSSEUTable = (const euSetting*)pRenderHal->sseuTable;
321     }
322     else
323     {
324         MHW_ASSERTMESSAGE("SSEU Table not valid.");
325         eStatus = MOS_STATUS_UNKNOWN;
326         return eStatus;
327     }
328 
329     MHW_CHK_NULL_RETURN(pcSSEUTable);
330     pcSSEUTable += KernelID;
331     if (!bSetRequestedSlices)                        // If num Slices is already programmed, then don't change it
332     {
333         if (wNumRequestedEUSlices < pcSSEUTable->numSlices)
334         {
335             wNumRequestedEUSlices = pcSSEUTable->numSlices;
336         }
337     }
338 
339     wNumRequestedSubSlices = pcSSEUTable->numSubSlices;
340     wNumRequestedEUs = pcSSEUTable->numEUs;
341 
342 #if (_DEBUG || _RELEASE_INTERNAL)
343     // User feature key reads
344     userSettingPtr = pRenderHal->pOsInterface->pfnGetUserSettingInstance(pRenderHal->pOsInterface);
345     ReadUserSettingForDebug(
346         userSettingPtr,
347         value,
348         __MEDIA_USER_FEATURE_VALUE_SSEU_SETTING_OVERRIDE,
349         MediaUserSetting::Group::Device);
350     if (value != 0xDEADC0DE)
351     {
352         wNumRequestedEUSlices = value & 0xFF;               // Bits 0-7
353         wNumRequestedSubSlices = (value >> 8) & 0xFF;        // Bits 8-15
354         wNumRequestedEUs = (value >> 16) & 0xFFFF;     // Bits 16-31
355     }
356 #endif
357 
358     PowerOption.nSlice = wNumRequestedEUSlices;
359     PowerOption.nSubSlice = wNumRequestedSubSlices;
360     PowerOption.nEU = wNumRequestedEUs;
361     pRenderHal->pfnSetPowerOptionMode(pRenderHal, &PowerOption);
362 
363     return eStatus;
364 }
365 
366 //!
367 //! \brief      Submit commands for rendering
368 //! \details    Submit commands for rendering. The KMD related fields in pGenericPrologParam might be modified by this
369 //!             function in order to maintain the synchronization mechanism for resource.
370 //! \param      [in] pRenderHal
371 //!             Pointer to RenderHal Interface Structure
372 //! \param      [in] pBatchBuffer
373 //!             Pointer to batch buffer
374 //! \param      [in] bNullRendering
375 //!             Indicate whether is Null rendering
376 //! \param      [in] pWalkerParams
377 //!             Pointer to walker parameters
378 //! \param      [in] pGpGpuWalkerParams
379 //!             Pointer to GPGPU walker parameters
380 //! \param      [in] KernelID
381 //!             VP Kernel ID
382 //! \param      [in] bLastSubmission
383 //!             Is last submission
384 //! \return     MOS_STATUS
385 //!
EukernelSubmitCommands(PRENDERHAL_INTERFACE pRenderHal,PMHW_BATCH_BUFFER pBatchBuffer,bool bNullRendering,PMHW_WALKER_PARAMS pWalkerParams,PMHW_GPGPU_WALKER_PARAMS pGpGpuWalkerParams,uint32_t KernelID,bool bLastSubmission)386 MOS_STATUS MediaRenderCommon::EukernelSubmitCommands(
387     PRENDERHAL_INTERFACE                pRenderHal,
388     PMHW_BATCH_BUFFER                   pBatchBuffer,
389     bool                                bNullRendering,
390     PMHW_WALKER_PARAMS                  pWalkerParams,
391     PMHW_GPGPU_WALKER_PARAMS            pGpGpuWalkerParams,
392     uint32_t                            KernelID,
393     bool                                bLastSubmission)
394 {
395     PMOS_INTERFACE                      pOsInterface = nullptr;
396     MOS_COMMAND_BUFFER                  CmdBuffer = {};
397     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
398     uint32_t                            dwSyncTag = 0;
399     int32_t                             i = 0, iRemaining = 0;
400     std::shared_ptr<mhw::render::Itf>   renderItf = nullptr;
401 
402     MHW_MEDIA_STATE_FLUSH_PARAM         FlushParam = {};
403     bool                                bEnableSLM = false;
404     RENDERHAL_GENERIC_PROLOG_PARAMS     GenericPrologParams = {};
405     MOS_RESOURCE                       *pgpuStatusBuffer= nullptr;
406     MOS_CONTEXT                        *pOsContext = nullptr;
407     PMHW_MI_MMIOREGISTERS               pMmioRegisters = nullptr;
408     MHW_FUNCTION_ENTER;
409 
410     MHW_CHK_NULL_RETURN(pRenderHal);
411     MHW_CHK_NULL_RETURN(pRenderHal->pRenderHalPltInterface);
412     MHW_CHK_NULL_RETURN(pRenderHal->pOsInterface);
413     MHW_CHK_NULL_RETURN(pRenderHal->pOsInterface->pOsContext);
414 
415     pOsInterface = pRenderHal->pOsInterface;
416 
417     iRemaining = 0;
418     FlushParam = g_cRenderHal_InitMediaStateFlushParams;
419     MOS_ZeroMemory(&CmdBuffer, sizeof(CmdBuffer));
420     pOsContext = pOsInterface->pOsContext;
421     pMmioRegisters = pRenderHal->pRenderHalPltInterface->GetMmioRegisters(pRenderHal);
422     MHW_CHK_NULL_RETURN(pMmioRegisters);
423     // Allocate all available space, unused buffer will be returned later
424     MHW_CHK_STATUS_RETURN(pOsInterface->pfnGetCommandBuffer(pOsInterface, &CmdBuffer, 0));
425 
426     // Set initial state
427     iRemaining = CmdBuffer.iRemaining;
428 
429     MHW_CHK_STATUS_RETURN(SetPowerMode(pRenderHal,KernelID));
430     pRenderHal->pRenderHalPltInterface->On1stLevelBBStart(pRenderHal, &CmdBuffer, pOsContext, pOsInterface->CurrentGpuContextHandle, pMmioRegisters);
431 
432 #ifndef EMUL
433     if (bLastSubmission && pOsInterface->bEnableKmdMediaFrameTracking)
434     {
435         // Get GPU Status buffer
436         pOsInterface->pfnGetGpuStatusBufferResource(pOsInterface, pgpuStatusBuffer);
437         // Register the buffer
438         pOsInterface->pfnRegisterResource(pOsInterface, pgpuStatusBuffer, true, true);
439 
440         GenericPrologParams.bEnableMediaFrameTracking = true;
441         GenericPrologParams.presMediaFrameTrackingSurface = pgpuStatusBuffer;
442         GenericPrologParams.dwMediaFrameTrackingTag = pOsInterface->pfnGetGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
443         GenericPrologParams.dwMediaFrameTrackingAddrOffset = pOsInterface->pfnGetGpuStatusTagOffset(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
444 
445         // Increment GPU Status Tag
446         pOsInterface->pfnIncrementGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
447     }
448 #endif
449 
450     // Initialize command buffer and insert prolog
451     MHW_CHK_STATUS_RETURN(pRenderHal->pfnInitCommandBuffer(pRenderHal, &CmdBuffer, &GenericPrologParams));
452 
453     // Write timing data for 3P budget
454     MHW_CHK_STATUS_RETURN(pRenderHal->pfnSendTimingData(pRenderHal, &CmdBuffer, true));
455 
456     MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddPerfCollectStartCmd(pRenderHal, pOsInterface, &CmdBuffer));
457 
458     MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->StartPredicate(pRenderHal, &CmdBuffer));
459 
460     bEnableSLM = (pGpGpuWalkerParams && pGpGpuWalkerParams->SLMSize > 0) ? true : false;
461     MHW_CHK_STATUS_RETURN(pRenderHal->pfnSetCacheOverrideParams(
462         pRenderHal,
463         &pRenderHal->L3CacheSettings,
464         bEnableSLM));
465 
466     // Flush media states
467     MHW_CHK_STATUS_RETURN(pRenderHal->pfnSendMediaStates(
468         pRenderHal,
469         &CmdBuffer,
470         pWalkerParams,
471         pGpGpuWalkerParams));
472 
473 
474     // Write back GPU Status tag
475     if (!pOsInterface->bEnableKmdMediaFrameTracking)
476     {
477         MHW_CHK_STATUS_RETURN(pRenderHal->pfnSendRcsStatusTag(pRenderHal, &CmdBuffer));
478     }
479 
480     pRenderHal->pRenderHalPltInterface->StopPredicate(pRenderHal, &CmdBuffer);
481 
482     MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddPerfCollectEndCmd(pRenderHal, pOsInterface, &CmdBuffer));
483 
484 
485     // Write timing data for 3P budget
486     MHW_CHK_STATUS_RETURN(pRenderHal->pfnSendTimingData(pRenderHal, &CmdBuffer, false));
487 
488 
489     MHW_PIPE_CONTROL_PARAMS PipeControlParams;
490 
491     MOS_ZeroMemory(&PipeControlParams, sizeof(PipeControlParams));
492     PipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
493     PipeControlParams.bGenericMediaStateClear = true;
494     PipeControlParams.bIndirectStatePointersDisable = true;
495     PipeControlParams.bDisableCSStall = false;
496 
497     MHW_CHK_NULL_RETURN(pOsInterface->pfnGetSkuTable);
498     auto* skuTable = pOsInterface->pfnGetSkuTable(pOsInterface);
499     if (skuTable && MEDIA_IS_SKU(skuTable, FtrEnablePPCFlush))
500     {
501         // Add PPC fulsh
502         PipeControlParams.bPPCFlush = true;
503     }
504     MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddMiPipeControl(pRenderHal, &CmdBuffer, &PipeControlParams));
505 
506     if (MEDIA_IS_WA(pRenderHal->pWaTable, WaSendDummyVFEafterPipelineSelect))
507     {
508         MHW_VFE_PARAMS VfeStateParams = {};
509         VfeStateParams.dwNumberofURBEntries = 1;
510         MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddMediaVfeCmd(pRenderHal, &CmdBuffer, &VfeStateParams));
511     }
512 
513     // Add media flush command in case HW not cleaning the media state
514     if (MEDIA_IS_WA(pRenderHal->pWaTable, WaMSFWithNoWatermarkTSGHang))
515     {
516         FlushParam.bFlushToGo = true;
517         if (pWalkerParams)
518         {
519             FlushParam.ui8InterfaceDescriptorOffset = pWalkerParams->InterfaceDescriptorOffset;
520         }
521         else
522         {
523             MHW_ASSERTMESSAGE("ERROR, pWalkerParams is nullptr and cannot get InterfaceDescriptorOffset.");
524         }
525 
526         MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddMediaStateFlush(pRenderHal, &CmdBuffer, &FlushParam));
527     }
528     else if (MEDIA_IS_WA(pRenderHal->pWaTable, WaAddMediaStateFlushCmd))
529     {
530         MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddMediaStateFlush(pRenderHal, &CmdBuffer, &FlushParam));
531     }
532 
533 
534     HalOcaInterfaceNext::On1stLevelBBEnd(CmdBuffer, *pOsInterface);
535 
536     if (pBatchBuffer)
537     {
538         // Send Batch Buffer end command (HW/OS dependent)
539         MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddMiBatchBufferEnd(pRenderHal, &CmdBuffer, nullptr));
540     }
541     else if (IsMiBBEndNeeded(pOsInterface))
542     {
543         // Send Batch Buffer end command for 1st level Batch Buffer
544         MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddMiBatchBufferEnd(pRenderHal, &CmdBuffer, nullptr));
545     }
546     else if (pRenderHal->pOsInterface->bNoParsingAssistanceInKmd)
547     {
548         MHW_CHK_STATUS_RETURN(pRenderHal->pRenderHalPltInterface->AddMiBatchBufferEnd(pRenderHal, &CmdBuffer, nullptr));
549     }
550 
551     // Return unused command buffer space to OS
552     pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
553 
554 
555 
556     // Submit command buffer
557     MHW_CHK_STATUS_RETURN(pOsInterface->pfnSubmitCommandBuffer(pOsInterface, &CmdBuffer, bNullRendering));
558 
559     if (bNullRendering == false)
560     {
561         dwSyncTag = pRenderHal->pStateHeap->dwNextTag++;
562 
563         // Set media state and batch buffer as busy
564         pRenderHal->pStateHeap->pCurMediaState->bBusy = true;
565         if (pBatchBuffer)
566         {
567             pBatchBuffer->bBusy = true;
568             pBatchBuffer->dwSyncTag = dwSyncTag;
569         }
570     }
571 
572     return eStatus;
573 }
574