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