1 /*
2 * Copyright (c) 2014-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 mhw_utilities.c
24 //! \brief This modules implements utilities which are shared by both the HW interface and the state heap interface.
25 //!
26
27 #include <math.h>
28 #include <set>
29 #include "mhw_utilities_next.h"
30 #include "mhw_state_heap.h"
31 #include "mos_interface.h"
32 #include "hal_oca_interface_next.h"
33 #include "media_skuwa_specific.h"
34 #include "mhw_itf.h"
35 #include "mhw_mi.h"
36 #include "mhw_mi_cmdpar.h"
37 #include "mhw_mi_itf.h"
38
39 #define MHW_NS_PER_TICK_RENDER_ENGINE 80 // 80 nano seconds per tick in render engine
40
41 static const std::set<MOS_HW_COMMAND> s_OCAResourceInfoType = {
42 MOS_MI_BATCH_BUFFER_START,
43 MOS_VEBOX_STATE,
44 MOS_VEBOX_DI_IECP,
45 MOS_VEBOX_TILING_CONVERT,
46 MOS_SFC_STATE,
47 MOS_STATE_BASE_ADDR,
48 MOS_SURFACE_STATE,
49 MOS_SURFACE_STATE_ADV,
50 MOS_MFX_PIPE_BUF_ADDR,
51 MOS_MFX_INDIRECT_OBJ_BASE_ADDR,
52 MOS_MFX_BSP_BUF_BASE_ADDR,
53 MOS_MFX_AVC_DIRECT_MODE,
54 MOS_MFX_VP8_PIC,
55 MOS_HUC_IND_OBJ_BASE_ADDR,
56 MOS_HUC_DMEM,
57 MOS_HUC_VIRTUAL_ADDR,
58 MOS_VDENC_PIPE_BUF_ADDR,
59 };
60
61 //!
62 //! \brief Set mocs index
63 //! \details Set mocs index
64 //! command buffer or indirect state
65 //! \param PMOS_INTERFACE osInterface
66 //! [in] OS interface
67 //! \param PMOS_RESOURCE resource
68 //! [in] resource
69 //! \param MHW_MOCS_PARAMS &mocsParams
70 //! [in] mocsParams
71 //! \return MOS_STATUS
72 //! MOS_STATUS_SUCCESS if success, else fail reason
73 //!
Mhw_SetMocsTableIndex(PMOS_INTERFACE osInterface,PMOS_RESOURCE resource,MHW_MOCS_PARAMS & mocsParams)74 MOS_STATUS Mhw_SetMocsTableIndex(
75 PMOS_INTERFACE osInterface,
76 PMOS_RESOURCE resource,
77 MHW_MOCS_PARAMS &mocsParams)
78 {
79 MHW_CHK_NULL_RETURN(resource);
80 MHW_CHK_NULL_RETURN(osInterface);
81
82 // Index is defined in bit 1:6
83 const uint8_t indexBitFieldLow = 1;
84 const uint8_t indexMask = 0x3F;
85 uint32_t memObjCtrlStateValue = 0;
86
87 uint32_t *data = mocsParams.mocsTableIndex;
88 uint32_t value = 0;
89 uint32_t mask = 0;
90 uint8_t bitFieldLow = mocsParams.bitFieldLow;
91 uint8_t bitFieldHigh = mocsParams.bitFieldHigh;
92
93 if (data == nullptr)
94 {
95 MHW_NORMALMESSAGE("skip to set the mocs");
96 return MOS_STATUS_SUCCESS;
97 }
98
99 if (bitFieldLow > bitFieldHigh || bitFieldHigh > 31)
100 {
101 MOS_OS_ASSERTMESSAGE("invalid bit field");
102 return MOS_STATUS_INVALID_PARAMETER;
103 }
104
105 value = *data;
106
107 auto memObjCtrlState = osInterface->pfnGetResourceCachePolicyMemoryObject(osInterface, resource);
108 memObjCtrlStateValue = (memObjCtrlState.DwordValue >> indexBitFieldLow) & indexMask;
109
110 if (bitFieldHigh == 31)
111 {
112 mask = (1 << bitFieldLow) - 1;
113 }
114 else
115 {
116 mask = (~((1 << (bitFieldHigh + 1)) - 1)) | ((1 << bitFieldLow) - 1);
117 }
118 value = value & mask;
119 *data = value | (memObjCtrlStateValue << bitFieldLow);
120
121 return MOS_STATUS_SUCCESS;
122 }
123
124 //!
125 //! \brief Adds graphics address of a resource to the command buffer or indirect state
126 //! \details Internal MHW function to add the graphics address of resources to the
127 //! command buffer or indirect state
128 //! \param PMOS_INTERFACE pOsInterface
129 //! [in] OS interface
130 //! \param PMOS_COMMAND_BUFFER pCmdBuffer
131 //! [in] Command buffer
132 //! \param PMHW_RESOURCE_PARAMS pParams
133 //! [in] Parameters necessary to insert the graphics address
134 //! \return MOS_STATUS
135 //! MOS_STATUS_SUCCESS if success, else fail reason
136 //!
Mhw_AddResourceToCmd_GfxAddress(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer,PMHW_RESOURCE_PARAMS pParams)137 MOS_STATUS Mhw_AddResourceToCmd_GfxAddress(
138 PMOS_INTERFACE pOsInterface,
139 PMOS_COMMAND_BUFFER pCmdBuffer,
140 PMHW_RESOURCE_PARAMS pParams)
141 {
142 uint32_t dwAlign, dwMask;
143 uint32_t dwGfxAddrBottom, dwGfxAddrTop = 0;
144 uint64_t ui64GfxAddress, ui64GfxAddressUpperBound;
145 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
146 int32_t iAllocationIndex = 0;
147 uint32_t uiPatchOffset = 0;
148 uint8_t *pbCmdBufBase = nullptr;
149
150 MHW_CHK_NULL_RETURN(pOsInterface);
151 MHW_CHK_NULL_RETURN(pParams);
152 MHW_CHK_NULL_RETURN(pParams->presResource);
153 MHW_CHK_NULL_RETURN(pCmdBuffer);
154 MHW_CHK_NULL_RETURN(pCmdBuffer->pCmdBase);
155
156 pbCmdBufBase = (uint8_t*)pCmdBuffer->pCmdBase;
157
158 MHW_CHK_STATUS_RETURN(pOsInterface->pfnRegisterResource(
159 pOsInterface,
160 pParams->presResource,
161 pParams->bIsWritable ? true : false,
162 pParams->bIsWritable ? true : false));
163
164 dwAlign = ( 1 << pParams->dwLsbNum);
165 dwMask = (-1 << pParams->dwLsbNum);
166
167 pParams->dwOffset = MOS_ALIGN_CEIL(pParams->dwOffset, dwAlign);
168 ui64GfxAddress =
169 pOsInterface->pfnGetResourceGfxAddress(pOsInterface, pParams->presResource) + pParams->dwOffset;
170 MHW_CHK_COND(ui64GfxAddress == 0, "Driver can't add resource with ui64GfxAddress == 0. DW location in cmd == %d.", pParams->dwLocationInCmd);
171
172 dwGfxAddrBottom = (uint32_t)(ui64GfxAddress & 0x00000000FFFFFFFF);
173 dwGfxAddrTop = (uint32_t)((ui64GfxAddress & 0xFFFFFFFF00000000) >> 32);
174
175 *pParams->pdwCmd = (*pParams->pdwCmd & ~dwMask) | (dwGfxAddrBottom & dwMask);
176 // this is next DW for top part of the address
177 *(pParams->pdwCmd + 1) = dwGfxAddrTop;
178
179 Mhw_SetMocsTableIndex(pOsInterface, pParams->presResource, pParams->mocsParams);
180
181 #if (_DEBUG || _RELEASE_INTERNAL)
182 {
183 uint32_t evtData[4] ={(uint32_t)pParams->HwCommandType, pParams->dwLocationInCmd, pParams->dwOffset, pParams->dwSize};
184 MOS_TraceEventExt(EVENT_RESOURCE_REGISTER, EVENT_TYPE_INFO2, evtData, sizeof(evtData), &ui64GfxAddress, sizeof(ui64GfxAddress));
185 }
186 #endif
187
188 if (pParams->dwOffsetInSSH > 0)
189 {
190 // Calculate the patch offset to command buffer
191 uiPatchOffset = pParams->dwOffsetInSSH + (pParams->dwLocationInCmd * sizeof(uint32_t));
192 }
193 else
194 {
195 // Calculate the patch offset to command buffer
196 uiPatchOffset = pCmdBuffer->iOffset + (pParams->dwLocationInCmd * sizeof(uint32_t));
197 }
198
199 MOS_PATCH_ENTRY_PARAMS PatchEntryParams;
200
201 iAllocationIndex = pOsInterface->pfnGetResourceAllocationIndex(pOsInterface, pParams->presResource);
202 MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams));
203 PatchEntryParams.uiAllocationIndex = iAllocationIndex;
204 PatchEntryParams.uiResourceOffset = pParams->dwOffset;
205 PatchEntryParams.uiPatchOffset = uiPatchOffset;
206 PatchEntryParams.bWrite = pParams->bIsWritable;
207 PatchEntryParams.HwCommandType = pParams->HwCommandType;
208 PatchEntryParams.forceDwordOffset = pParams->dwSharedMocsOffset;
209 PatchEntryParams.cmdBufBase = pbCmdBufBase;
210 PatchEntryParams.presResource = pParams->presResource;
211
212 // Add patch entry
213 MHW_CHK_STATUS_RETURN(pOsInterface->pfnSetPatchEntry(
214 pOsInterface,
215 &PatchEntryParams));
216
217 if (pParams->dwUpperBoundLocationOffsetFromCmd > 0)
218 {
219 pParams->dwSize = MOS_ALIGN_CEIL(pParams->dwSize, dwAlign);
220
221 ui64GfxAddressUpperBound = ui64GfxAddress + pParams->dwSize;
222 dwGfxAddrBottom = (uint32_t)(ui64GfxAddressUpperBound & 0x00000000FFFFFFFF);
223 dwGfxAddrTop = (uint32_t)((ui64GfxAddressUpperBound & 0xFFFFFFFF00000000) >> 32);
224
225 pParams->pdwCmd += pParams->dwUpperBoundLocationOffsetFromCmd;
226 *pParams->pdwCmd = (*pParams->pdwCmd & ~dwMask) | (dwGfxAddrBottom & dwMask);
227 // this is next DW for top part of the address
228 *(pParams->pdwCmd + 1) = dwGfxAddrTop;
229
230 MOS_PATCH_ENTRY_PARAMS PatchEntryParams;
231
232 // Calculate the patch offset to command buffer
233 uiPatchOffset += pParams->dwUpperBoundLocationOffsetFromCmd * sizeof(uint32_t);
234
235 MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams));
236 PatchEntryParams.uiAllocationIndex = iAllocationIndex;
237 PatchEntryParams.uiResourceOffset = pParams->dwOffset + pParams->dwSize;
238 PatchEntryParams.uiPatchOffset = uiPatchOffset;
239 PatchEntryParams.bUpperBoundPatch = true;
240 PatchEntryParams.presResource = pParams->presResource;
241
242 // Add patch entry (CP won't register this patch point since bUpperBoundPatch = true)
243 MHW_CHK_STATUS_RETURN(pOsInterface->pfnSetPatchEntry(
244 pOsInterface,
245 &PatchEntryParams));
246 }
247
248 if (s_OCAResourceInfoType.count(pParams->HwCommandType))
249 {
250 HalOcaInterfaceNext::DumpResourceInfo(*pCmdBuffer, *pOsInterface, *pParams->presResource, pParams->HwCommandType,
251 pParams->dwLocationInCmd, pParams->dwOffset);
252 }
253
254 return eStatus;
255 }
256
257 //!
258 //! \brief Adds resources to a patch list
259 //! \details Internal MHW function to put resources to be added to the command
260 //! buffer or indirect state into a patch list for patch later
261 //! \param PMOS_INTERFACE pOsInterface
262 //! [in] OS interface
263 //! \param PMOS_COMMAND_BUFFER pCmdBuffer
264 //! [in] Command buffer
265 //! \param PMHW_RESOURCE_PARAMS pParams
266 //! [in] Parameters necessary to add the resource to the patch list
267 //! \return MOS_STATUS
268 //! MOS_STATUS_SUCCESS if success, else fail reason
269 //!
Mhw_AddResourceToCmd_PatchList(PMOS_INTERFACE pOsInterface,PMOS_COMMAND_BUFFER pCmdBuffer,PMHW_RESOURCE_PARAMS pParams)270 MOS_STATUS Mhw_AddResourceToCmd_PatchList(
271 PMOS_INTERFACE pOsInterface,
272 PMOS_COMMAND_BUFFER pCmdBuffer,
273 PMHW_RESOURCE_PARAMS pParams)
274 {
275 MOS_GPU_CONTEXT GpuContext;
276 int32_t iAllocationIndex;
277 uint32_t dwLsbNum, dwUpperBoundOffset;
278 uint32_t dwOffset;
279 uint32_t uiPatchOffset;
280 MOS_PATCH_ENTRY_PARAMS PatchEntryParams;
281 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
282
283 MHW_CHK_NULL_RETURN(pOsInterface);
284 MHW_CHK_NULL_RETURN(pParams);
285 MHW_CHK_NULL_RETURN(pParams->presResource);
286 MHW_CHK_NULL_RETURN(pCmdBuffer);
287
288 MOS_TraceEventExt(EVENT_RESOURCE_REGISTER, EVENT_TYPE_INFO2, &pParams->HwCommandType, sizeof(uint32_t), &pParams->dwLocationInCmd, sizeof(uint32_t));
289
290 MHW_CHK_STATUS_RETURN(pOsInterface->pfnRegisterResource(
291 pOsInterface,
292 pParams->presResource,
293 pParams->bIsWritable ? true : false,
294 pParams->bIsWritable ? true : false));
295
296 GpuContext = pOsInterface->pfnGetGpuContext(pOsInterface);
297 iAllocationIndex = pOsInterface->pfnGetResourceAllocationIndex(pOsInterface, pParams->presResource);
298 dwLsbNum = pParams->dwLsbNum;
299
300 // Offset and command LSB parameters
301 dwOffset = pParams->dwOffset | ((*pParams->pdwCmd) & ((1 << dwLsbNum) - 1));
302
303 Mhw_SetMocsTableIndex(pOsInterface, pParams->presResource, pParams->mocsParams);
304
305 if (pParams->dwOffsetInSSH > 0)
306 {
307 // Calculate the patch offset to command buffer
308 uiPatchOffset = pParams->dwOffsetInSSH + (pParams->dwLocationInCmd * sizeof(uint32_t));
309 }
310 else
311 {
312 // Calculate the patch offset to command buffer
313 uiPatchOffset = pCmdBuffer->iOffset + (pParams->dwLocationInCmd * sizeof(uint32_t));
314 }
315
316 MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams));
317 PatchEntryParams.uiAllocationIndex = iAllocationIndex;
318 if(pParams->patchType == MOS_PATCH_TYPE_UV_Y_OFFSET ||
319 pParams->patchType == MOS_PATCH_TYPE_PITCH ||
320 pParams->patchType == MOS_PATCH_TYPE_V_Y_OFFSET)
321 {
322 PatchEntryParams.uiResourceOffset = *pParams->pdwCmd;
323 }
324 else
325 {
326 PatchEntryParams.uiResourceOffset = dwOffset;
327 }
328 PatchEntryParams.uiPatchOffset = uiPatchOffset;
329 PatchEntryParams.bWrite = pParams->bIsWritable;
330 PatchEntryParams.HwCommandType = pParams->HwCommandType;
331 PatchEntryParams.forceDwordOffset = pParams->dwSharedMocsOffset;
332 PatchEntryParams.cmdBufBase = (uint8_t*)pCmdBuffer->pCmdBase;
333 PatchEntryParams.presResource = pParams->presResource;
334 PatchEntryParams.patchType = pParams->patchType;
335 PatchEntryParams.shiftAmount = pParams->shiftAmount;
336 PatchEntryParams.shiftDirection = pParams->shiftDirection;
337 PatchEntryParams.offsetInSSH = pParams->dwOffsetInSSH;
338 PatchEntryParams.cmdBuffer = pCmdBuffer;
339
340 // Add patch entry to patch the address field for this command
341 MHW_CHK_STATUS_RETURN(pOsInterface->pfnSetPatchEntry(
342 pOsInterface,
343 &PatchEntryParams));
344
345 if (pParams->dwUpperBoundLocationOffsetFromCmd > 0)
346 {
347 pParams->pdwCmd += pParams->dwUpperBoundLocationOffsetFromCmd;
348 dwUpperBoundOffset = pParams->dwUpperBoundLocationOffsetFromCmd;
349
350 // Offset and command LSB parameters
351 dwOffset = MOS_ALIGN_CEIL((pParams->dwOffset + pParams->dwSize), (1 << dwLsbNum));
352 dwOffset = dwOffset | ((*pParams->pdwCmd) & ((1 << dwLsbNum) - 1));
353
354 // Calculate the patch offset to command buffer
355 uiPatchOffset += dwUpperBoundOffset * sizeof(uint32_t);
356
357 MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams));
358 PatchEntryParams.uiAllocationIndex = iAllocationIndex;
359 PatchEntryParams.uiResourceOffset = dwOffset;
360 PatchEntryParams.uiPatchOffset = uiPatchOffset;
361 PatchEntryParams.bUpperBoundPatch = true;
362 PatchEntryParams.presResource = pParams->presResource;
363 PatchEntryParams.patchType = pParams->patchType;
364 PatchEntryParams.shiftAmount = pParams->shiftAmount;
365 PatchEntryParams.shiftDirection = pParams->shiftDirection;
366 PatchEntryParams.offsetInSSH = pParams->dwOffsetInSSH;
367 PatchEntryParams.cmdBuffer = pCmdBuffer;
368
369 if(dwLsbNum)
370 {
371 PatchEntryParams.shiftAmount = dwLsbNum;
372 PatchEntryParams.shiftDirection = 0;
373 }
374
375 // Add patch entry to patch the address field for this command
376 MHW_CHK_STATUS_RETURN(pOsInterface->pfnSetPatchEntry(
377 pOsInterface,
378 &PatchEntryParams));
379 }
380
381 if (s_OCAResourceInfoType.count(pParams->HwCommandType))
382 {
383 HalOcaInterfaceNext::DumpResourceInfo(*pCmdBuffer, *pOsInterface, *pParams->presResource, pParams->HwCommandType,
384 pParams->dwLocationInCmd, pParams->dwOffset);
385 }
386
387 return eStatus;
388 }
389
390 //!
391 //! \brief Derive Surface Type from Surface Format
392 //! \details Internal MHW function to dervie surface type from surface format
393 //! \param uint32_t dwForceSurfaceFormat
394 //! [in] surface format information
395 //! \param PMOS_SURFACE psSurface
396 //! [in] surface which have depth information
397 //! \param uint32_t* pdwSurfaceType
398 //! [out] Surface type
399 //! \return MOS_STATUS
400 //! MOS_STATUS_SUCCESS if success, else fail reason
401 //!
Mhw_SurfaceFormatToType(uint32_t dwForceSurfaceFormat,PMOS_SURFACE psSurface,uint32_t * pdwSurfaceType)402 MOS_STATUS Mhw_SurfaceFormatToType(
403 uint32_t dwForceSurfaceFormat,
404 PMOS_SURFACE psSurface,
405 uint32_t *pdwSurfaceType)
406 {
407 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
408
409 MHW_FUNCTION_ENTER;
410
411 MHW_CHK_NULL_RETURN(psSurface);
412 MHW_CHK_NULL_RETURN(pdwSurfaceType);
413
414 switch ( dwForceSurfaceFormat )
415 {
416 // 1D Surface
417 case MHW_GFX3DSTATE_SURFACEFORMAT_RAW:
418 case MHW_GFX3DSTATE_SURFACEFORMAT_R32_UINT:
419 case MHW_GFX3DSTATE_SURFACEFORMAT_L8_UNORM:
420 *pdwSurfaceType = GFX3DSTATE_SURFACETYPE_BUFFER;
421 break;
422
423 // 2D Surface for Codec: GFX3DSTATE_SURFACEFORMAT_YCRCB_NORMAL, GFX3DSTATE_SURFACEFORMAT_YCRCB_SWAPY
424 // GFX3DSTATE_SURFACEFORMAT_R32_UNORM, GFX3DSTATE_SURFACEFORMAT_R16_UNORM, GFX3DSTATE_SURFACEFORMAT_R8_UNORM
425
426 // 2D & 3D Surface
427 default:
428 (psSurface->dwDepth > 1) ?
429 *pdwSurfaceType = GFX3DSTATE_SURFACETYPE_3D:
430 *pdwSurfaceType = GFX3DSTATE_SURFACETYPE_2D;
431 }
432
433 return eStatus;
434 }
435
436 //!
437 //! \brief Inserts the generic prologue command for a command buffer
438 //! \details Client facing function to add the generic prologue commands:
439 //! - the command buffer header (if necessary)
440 //! - flushes for the read/write caches (MI_FLUSH_DW or PIPE_CONTROL)
441 //! - CP prologue if necessary
442 //! \param PMOS_COMMAND_BUFFER pCmdBuffer
443 //! [in] Command buffer
444 //! \param PMHW_GENERIC_PROLOG_PARAMS pParams
445 //! [in] Parameters necessary to add the generic prologue commands
446 //! \return MOS_STATUS
447 //! MOS_STATUS_SUCCESS if success, else fail reason
448 //!
Mhw_SendGenericPrologCmdNext(PMOS_COMMAND_BUFFER pCmdBuffer,PMHW_GENERIC_PROLOG_PARAMS pParams,std::shared_ptr<void> pMiItf,MHW_MI_MMIOREGISTERS * pMmioReg)449 MOS_STATUS Mhw_SendGenericPrologCmdNext(
450 PMOS_COMMAND_BUFFER pCmdBuffer,
451 PMHW_GENERIC_PROLOG_PARAMS pParams,
452 std::shared_ptr<void> pMiItf,
453 MHW_MI_MMIOREGISTERS *pMmioReg)
454 {
455 PMOS_INTERFACE pOsInterface;
456 MEDIA_FEATURE_TABLE *pSkuTable;
457 MEDIA_WA_TABLE *pWaTable;
458 MOS_GPU_CONTEXT GpuContext;
459 MHW_PIPE_CONTROL_PARAMS PipeControlParams;
460 MHW_MI_FLUSH_DW_PARAMS FlushDwParams;
461 bool bRcsEngineUsed = false;
462 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
463 std::shared_ptr<mhw::mi::Itf> miItf = std::static_pointer_cast<mhw::mi::Itf>(pMiItf);
464 MHW_FUNCTION_ENTER;
465
466 MHW_CHK_NULL_RETURN(pCmdBuffer);
467 MHW_CHK_NULL_RETURN(pParams);
468 MHW_CHK_NULL_RETURN(pParams->pOsInterface);
469 MHW_CHK_NULL_RETURN(miItf);
470
471 pOsInterface = pParams->pOsInterface;
472
473 pSkuTable = pOsInterface->pfnGetSkuTable(pOsInterface);
474 MHW_CHK_NULL_RETURN(pSkuTable);
475 pWaTable = pOsInterface->pfnGetWaTable(pOsInterface);
476 MHW_CHK_NULL_RETURN(pWaTable);
477
478
479 GpuContext = pOsInterface->pfnGetGpuContext(pOsInterface);
480
481 if ( pOsInterface->Component != COMPONENT_CM )
482 {
483 if ( GpuContext == MOS_GPU_CONTEXT_RENDER ||
484 GpuContext == MOS_GPU_CONTEXT_RENDER2 ||
485 GpuContext == MOS_GPU_CONTEXT_RENDER3 ||
486 GpuContext == MOS_GPU_CONTEXT_RENDER4 ||
487 GpuContext == MOS_GPU_CONTEXT_VIDEO ||
488 GpuContext == MOS_GPU_CONTEXT_VIDEO2 ||
489 GpuContext == MOS_GPU_CONTEXT_VIDEO3 ||
490 GpuContext == MOS_GPU_CONTEXT_VIDEO4 ||
491 GpuContext == MOS_GPU_CONTEXT_VDBOX2_VIDEO ||
492 GpuContext == MOS_GPU_CONTEXT_VDBOX2_VIDEO2 ||
493 GpuContext == MOS_GPU_CONTEXT_VDBOX2_VIDEO3 ||
494 GpuContext == MOS_GPU_CONTEXT_VEBOX ||
495 GpuContext == MOS_GPU_CONTEXT_VIDEO5 ||
496 GpuContext == MOS_GPU_CONTEXT_VIDEO6 ||
497 GpuContext == MOS_GPU_CONTEXT_VIDEO7 )
498 {
499 MHW_CHK_STATUS_RETURN(miItf->AddWatchdogTimerStartCmd(pCmdBuffer));
500 }
501 }
502
503 bRcsEngineUsed = MOS_RCS_ENGINE_USED(GpuContext);
504
505 if (bRcsEngineUsed)
506 {
507 auto& par = miItf->MHW_GETPAR_F(PIPE_CONTROL)();
508 par = {};
509 par.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
510 MHW_CHK_STATUS_RETURN(miItf->MHW_ADDCMD_F(PIPE_CONTROL)(pCmdBuffer));
511
512 auto& par1 = miItf->MHW_GETPAR_F(PIPE_CONTROL)();
513 par1 = {};
514 par1.dwFlushMode = MHW_FLUSH_READ_CACHE;
515 par1.presDest = pParams->presStoreData;
516 par1.dwResourceOffset = pParams->dwStoreDataOffset;
517 par1.dwPostSyncOp = MHW_FLUSH_WRITE_IMMEDIATE_DATA;
518 MHW_CHK_STATUS_RETURN(miItf->MHW_ADDCMD_F(PIPE_CONTROL)(pCmdBuffer));
519
520 if(pCmdBuffer->Attributes.bUmdSSEUEnable)
521 {
522 MHW_MI_LOAD_REGISTER_IMM_PARAMS MiLoadRegImmParams;
523 MHW_RENDER_PWR_CLK_STATE_PARAMS params;
524
525 MOS_ZeroMemory(¶ms, sizeof(params));
526 params.PowerClkStateEn = true;
527 params.SCountEn = true;
528 params.SSCountEn = true;
529 params.SliceCount = pCmdBuffer->Attributes.dwNumRequestedEUSlices;
530 params.SubSliceCount = pCmdBuffer->Attributes.dwNumRequestedSubSlices;
531 params.EUmax = pCmdBuffer->Attributes.dwNumRequestedEUs;
532 params.EUmin = pCmdBuffer->Attributes.dwNumRequestedEUs;
533
534 auto& par = miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_IMM)();
535 par = {};
536 par.dwRegister = MHW__PWR_CLK_STATE_REG;
537 par.dwData = params.Data;
538 MHW_CHK_STATUS_RETURN(miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(pCmdBuffer));
539 }
540 }
541 else
542 {
543 // Send MI_FLUSH with protection bit off, which will FORCE exit protected mode for MFX
544 auto& params = miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
545 params = {};
546 params.bVideoPipelineCacheInvalidate = true;
547 params.pOsResource = pParams->presStoreData;
548 params.dwResourceOffset = pParams->dwStoreDataOffset;
549 params.dwDataDW1 = pParams->dwStoreDataValue;
550 MHW_CHK_STATUS_RETURN(miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(pCmdBuffer));
551 }
552
553 MHW_CHK_STATUS_RETURN(miItf->AddProtectedProlog(pCmdBuffer));
554
555 if (pMmioReg)
556 {
557 HalOcaInterfaceNext::On1stLevelBBStart(
558 *pCmdBuffer,
559 (MOS_CONTEXT_HANDLE)pOsInterface->pOsContext,
560 pOsInterface->CurrentGpuContextHandle,
561 miItf,
562 *pMmioReg);
563 }
564
565 return eStatus;
566 }
567
568 //!
569 //! \brief Sets Nearest Mode Table for Gen75/9, across SFC and Render engine to set the sampler states
570 //! \details This function sets Coefficients for Nearest Mode
571 //! \param int32_t* iCoefs
572 //! [out] Polyphase Table to fill
573 //! \param uint32_t dwPlane
574 //! [in] Number of Polyphase tables
575 //! \param bool bBalancedFilter
576 //! [in] If Filter is balanced, set true
577 //! \return MOS_STATUS
578 //! MOS_STATUS_SUCCESS if success, else fail reason
579 //!
Mhw_SetNearestModeTable(int32_t * iCoefs,uint32_t dwPlane,bool bBalancedFilter)580 MOS_STATUS Mhw_SetNearestModeTable(
581 int32_t *iCoefs,
582 uint32_t dwPlane,
583 bool bBalancedFilter)
584 {
585 uint32_t dwNumEntries;
586 uint32_t dwOffset;
587 uint32_t i;
588 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
589
590 MHW_FUNCTION_ENTER;
591
592 MHW_CHK_NULL_RETURN(iCoefs);
593
594 if (dwPlane == MHW_GENERIC_PLANE || dwPlane == MHW_Y_PLANE)
595 {
596 dwNumEntries = NUM_POLYPHASE_Y_ENTRIES;
597 dwOffset = 3;
598 }
599 else // if (dwPlane == MHW_U_PLANE || dwPlane == MHW_V_PLANE)
600 {
601 dwNumEntries = NUM_POLYPHASE_UV_ENTRIES;
602 dwOffset = 1;
603 }
604
605 for (i = 0; i <= NUM_HW_POLYPHASE_TABLES / 2; i++)
606 {
607 iCoefs[i * dwNumEntries + dwOffset] = 0x40;
608 }
609
610 if (bBalancedFilter)
611 {
612 // Fix offset so that filter is balanced
613 for (i = (NUM_HW_POLYPHASE_TABLES / 2 + 1); i < NUM_HW_POLYPHASE_TABLES; i++)
614 {
615 iCoefs[i * dwNumEntries + dwOffset + 1] = 0x40;
616 }
617 }
618
619 return eStatus;
620 }
621
622 //!
623 //! \brief Calculate Polyphase tables for Y , across SFC and Render engine to set the sampler states
624 //! \details Calculate Polyphase tables for Y
625 //! This function uses 17 phases.
626 //! MHW_NUM_HW_POLYPHASE_TABLES reflects the phases to program coefficients in HW, and
627 //! NUM_POLYPHASE_TABLES reflects the number of phases used for internal calculations.
628 //! \param int32_t* iCoefs
629 //! [out] Polyphase Table to fill
630 //! \param float fScaleFactor
631 //! [in] Scaling factor
632 //! \param uint32_t dwPlane
633 //! [in] Plane Info
634 //! \param MOS_FORMAT srcFmt
635 //! [in] Source Format
636 //! \param float fHPStrength
637 //! [in] High Pass Strength
638 //! \param bool bUse8x8Filter
639 //! [in] is 8x8 Filter used
640 //! \param uint32_t dwHwPhase
641 //! [in] Number of phases in HW
642 //! \param float fLanczosT
643 //! [in] Lanczos factor
644 //! \return MOS_STATUS
645 //! MOS_STATUS_SUCCESS if success, else fail reason
646 //!
Mhw_CalcPolyphaseTablesY(int32_t * iCoefs,float fScaleFactor,uint32_t dwPlane,MOS_FORMAT srcFmt,float fHPStrength,bool bUse8x8Filter,uint32_t dwHwPhase,float fLanczosT)647 MOS_STATUS Mhw_CalcPolyphaseTablesY(
648 int32_t *iCoefs,
649 float fScaleFactor,
650 uint32_t dwPlane,
651 MOS_FORMAT srcFmt,
652 float fHPStrength,
653 bool bUse8x8Filter,
654 uint32_t dwHwPhase,
655 float fLanczosT)
656 {
657 uint32_t dwNumEntries;
658 uint32_t dwTableCoefUnit;
659 uint32_t i, j;
660 int32_t k;
661 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
662 float fPhaseCoefs[NUM_POLYPHASE_Y_ENTRIES];
663 float fPhaseCoefsCopy[NUM_POLYPHASE_Y_ENTRIES];
664 float fStartOffset;
665 float fHPFilter[3], fHPSum, fHPHalfPhase; // Only used for Y_PLANE
666 float fBase, fPos, fSumCoefs;
667 int32_t iCenterPixel;
668 int32_t iSumQuantCoefs;
669
670 MHW_FUNCTION_ENTER;
671
672 MHW_CHK_NULL_RETURN(iCoefs);
673 MHW_ASSERT((dwHwPhase == MHW_NUM_HW_POLYPHASE_TABLES) || (dwHwPhase == NUM_HW_POLYPHASE_TABLES));
674
675 if (dwPlane == MHW_GENERIC_PLANE || dwPlane == MHW_Y_PLANE)
676 {
677 dwNumEntries = NUM_POLYPHASE_Y_ENTRIES;
678 }
679 else // if (dwPlane == MHW_U_PLANE || dwPlane == MHW_V_PLANE)
680 {
681 dwNumEntries = NUM_POLYPHASE_UV_ENTRIES;
682 }
683
684 MOS_ZeroMemory(fPhaseCoefs , sizeof(fPhaseCoefs));
685 MOS_ZeroMemory(fPhaseCoefsCopy, sizeof(fPhaseCoefsCopy));
686
687 dwTableCoefUnit = 1 << MHW_AVS_TBL_COEF_PREC;
688 iCenterPixel = dwNumEntries / 2 - 1;
689 fStartOffset = (float)(-iCenterPixel);
690
691 if ((IS_YUV_FORMAT(srcFmt) &&
692 dwPlane != MHW_U_PLANE &&
693 dwPlane != MHW_V_PLANE) ||
694 ((IS_RGB32_FORMAT(srcFmt) ||
695 srcFmt == Format_Y410 ||
696 srcFmt == Format_AYUV) &&
697 dwPlane == MHW_Y_PLANE))
698 {
699 if (fScaleFactor < 1.0F)
700 {
701 fLanczosT = 4.0F;
702 }
703 else
704 {
705 fLanczosT = 8.0F;
706 }
707 }
708 else // if (dwPlane == MHW_U_PLANE || dwPlane == MHW_V_PLANE || (IS_RGB_FORMAT(srcFmt) && dwPlane != MHW_V_PLANE))
709 {
710 fLanczosT = 2.0F;
711 }
712
713 for (i = 0; i < dwHwPhase; i++)
714 {
715 fBase = fStartOffset - (float)i / (float)NUM_POLYPHASE_TABLES;
716 fSumCoefs = 0.0F;
717
718 for (j = 0; j < dwNumEntries; j++)
719 {
720 fPos = fBase + (float)j;
721
722 if (bUse8x8Filter)
723 {
724 fPhaseCoefs[j] = fPhaseCoefsCopy[j] = MosUtilities::MosLanczos(fPos * fScaleFactor, dwNumEntries, fLanczosT);
725 }
726 else
727 {
728 fPhaseCoefs[j] = fPhaseCoefsCopy[j] = MosUtilities::MosLanczosG(fPos * fScaleFactor, NUM_POLYPHASE_5x5_Y_ENTRIES, fLanczosT);
729 }
730
731 fSumCoefs += fPhaseCoefs[j];
732 }
733
734 // Convolve with HP
735 if (dwPlane == MHW_GENERIC_PLANE || dwPlane == MHW_Y_PLANE)
736 {
737 if (i <= NUM_POLYPHASE_TABLES / 2)
738 {
739 fHPHalfPhase = (float)i / (float)NUM_POLYPHASE_TABLES;
740 }
741 else
742 {
743 fHPHalfPhase = (float)(NUM_POLYPHASE_TABLES - i) / (float)NUM_POLYPHASE_TABLES;
744 }
745 fHPFilter[0] = fHPFilter[2] = -fHPStrength * MosUtilities::MosSinc(fHPHalfPhase * MOS_PI);
746 fHPFilter[1] = 1.0F + 2.0F * fHPStrength;
747
748 for (j = 0; j < dwNumEntries; j++)
749 {
750 fHPSum = 0.0F;
751 for (k = -1; k <= 1; k++)
752 {
753 if ((((long)j + k) >= 0) && (j + k < dwNumEntries))
754 {
755 fHPSum += fPhaseCoefsCopy[(int32_t)j+k] * fHPFilter[k+1];
756 }
757 fPhaseCoefs[j] = fHPSum;
758 }
759 }
760 }
761
762 // Normalize coefs and save
763 iSumQuantCoefs = 0;
764 for (j = 0; j < dwNumEntries; j++)
765 {
766 iCoefs[i * dwNumEntries + j] = (int32_t)floor(0.5F + (float)dwTableCoefUnit * fPhaseCoefs[j] / fSumCoefs);
767 iSumQuantCoefs += iCoefs[i * dwNumEntries + j];
768 }
769
770 // Fix center coef so that filter is balanced
771 if (i <= NUM_POLYPHASE_TABLES / 2)
772 {
773 iCoefs[i * dwNumEntries + iCenterPixel] -= iSumQuantCoefs - dwTableCoefUnit;
774 }
775 else
776 {
777 iCoefs[i * dwNumEntries + iCenterPixel + 1] -= iSumQuantCoefs - dwTableCoefUnit;
778 }
779 }
780
781 return eStatus;
782 }
783
784 //!
785 //! \brief Calculate Polyphase tables for UV for Gen9, across SFC and Render engine to set the sampler states
786 //! \details Calculate Polyphase tables for UV
787 //! \param int32_t* piCoefs
788 //! [out] Polyphase Table to fill
789 //! \param float fLanczosT
790 //! [in] Lanczos modifying factor
791 //! \param float fInverseScaleFactor
792 //! [in] Inverse scaling factor
793 //! \return MOS_STATUS
794 //! MOS_STATUS_SUCCESS if success, else fail reason
795 //!
Mhw_CalcPolyphaseTablesUV(int32_t * piCoefs,float fLanczosT,float fInverseScaleFactor)796 MOS_STATUS Mhw_CalcPolyphaseTablesUV(
797 int32_t *piCoefs,
798 float fLanczosT,
799 float fInverseScaleFactor)
800 {
801 int32_t phaseCount, tableCoefUnit, centerPixel, sumQuantCoefs;
802 double phaseCoefs[MHW_SCALER_UV_WIN_SIZE];
803 double startOffset, sf, base, sumCoefs, pos;
804 int32_t minCoef[MHW_SCALER_UV_WIN_SIZE];
805 int32_t maxCoef[MHW_SCALER_UV_WIN_SIZE];
806 int32_t i, j;
807 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
808
809 MHW_FUNCTION_ENTER;
810
811 MHW_CHK_NULL_RETURN(piCoefs);
812
813 phaseCount = MHW_TABLE_PHASE_COUNT;
814 centerPixel = (MHW_SCALER_UV_WIN_SIZE / 2) - 1;
815 startOffset = (double)(-centerPixel);
816 tableCoefUnit = 1 << MHW_TBL_COEF_PREC;
817 sf = MOS_MIN(1.0, fInverseScaleFactor); // Sf isn't used for upscaling
818
819 MOS_ZeroMemory(piCoefs, sizeof(int32_t) * MHW_SCALER_UV_WIN_SIZE * phaseCount);
820 MOS_ZeroMemory(minCoef, sizeof(minCoef));
821 MOS_ZeroMemory(maxCoef, sizeof(maxCoef));
822
823 if (sf < 1.0F)
824 {
825 fLanczosT = 2.0F;
826 }
827
828 for(i = 0; i < phaseCount; ++i, piCoefs += MHW_SCALER_UV_WIN_SIZE)
829 {
830 // Write all
831 // Note - to shift by a half you need to a half to each phase.
832 base = startOffset - (double)(i) / (double)(phaseCount);
833 sumCoefs = 0.0;
834
835 for(j = 0; j < MHW_SCALER_UV_WIN_SIZE; ++j)
836 {
837 pos = base + (double) j;
838 phaseCoefs[j] = MosUtilities::MosLanczos((float)(pos * sf), MHW_SCALER_UV_WIN_SIZE, fLanczosT);
839 sumCoefs += phaseCoefs[j];
840 }
841 // Normalize coefs and save
842 for(j = 0; j < MHW_SCALER_UV_WIN_SIZE; ++j)
843 {
844 piCoefs[j] = (int32_t) floor((0.5 + (double)(tableCoefUnit) * (phaseCoefs[j] / sumCoefs)));
845
846 //For debug purposes:
847 minCoef[j] = MOS_MIN(minCoef[j], piCoefs[j]);
848 maxCoef[j] = MOS_MAX(maxCoef[j], piCoefs[j]);
849 }
850
851 // Recalc center coef
852 sumQuantCoefs = 0;
853 for(j = 0; j < MHW_SCALER_UV_WIN_SIZE; ++j)
854 {
855 sumQuantCoefs += piCoefs[j];
856 }
857
858 // Fix center coef so that filter is balanced
859 if (i <= phaseCount/2)
860 {
861 piCoefs[centerPixel] -= sumQuantCoefs - tableCoefUnit;
862 }
863 else
864 {
865 piCoefs[centerPixel + 1] -= sumQuantCoefs - tableCoefUnit;
866 }
867 }
868
869 return eStatus;
870 }
871
872 //!
873 //! \brief Calculate polyphase tables UV offset for Gen9, across SFC and Render engine to set the sampler states
874 //! \details Calculate Polyphase tables for UV with chroma siting for
875 //! 420 to 444 conversion
876 //! \param int32_t* piCoefs
877 //! [out] Polyphase Table to fill
878 //! \param float fLanczosT
879 //! [in] Lanczos modifying factor
880 //! \param float fInverseScaleFactor
881 //! [in] Inverse scaling factor
882 //! \param int32_t iUvPhaseOffset
883 //! [in] UV Phase Offset
884 //! \return MOS_STATUS
885 //! MOS_STATUS_SUCCESS if success, else fail reason
886 //!
Mhw_CalcPolyphaseTablesUVOffset(int32_t * piCoefs,float fLanczosT,float fInverseScaleFactor,int32_t iUvPhaseOffset)887 MOS_STATUS Mhw_CalcPolyphaseTablesUVOffset(
888 int32_t *piCoefs,
889 float fLanczosT,
890 float fInverseScaleFactor,
891 int32_t iUvPhaseOffset)
892 {
893 int32_t phaseCount, tableCoefUnit, centerPixel, sumQuantCoefs;
894 double phaseCoefs[MHW_SCALER_UV_WIN_SIZE];
895 double startOffset, sf, pos, sumCoefs, base;
896 int32_t minCoef[MHW_SCALER_UV_WIN_SIZE];
897 int32_t maxCoef[MHW_SCALER_UV_WIN_SIZE];
898 int32_t i, j;
899 int32_t adjusted_phase;
900 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
901
902 MHW_FUNCTION_ENTER;
903
904 MHW_CHK_NULL_RETURN(piCoefs);
905
906 phaseCount = MHW_TABLE_PHASE_COUNT;
907 centerPixel = (MHW_SCALER_UV_WIN_SIZE / 2) - 1;
908 startOffset = (double)(-centerPixel +
909 (double)iUvPhaseOffset / (double)(phaseCount));
910 tableCoefUnit = 1 << MHW_TBL_COEF_PREC;
911
912 MOS_ZeroMemory(minCoef, sizeof(minCoef));
913 MOS_ZeroMemory(maxCoef, sizeof(maxCoef));
914 MOS_ZeroMemory(piCoefs, sizeof(int32_t)* MHW_SCALER_UV_WIN_SIZE * phaseCount);
915
916 sf = MOS_MIN(1.0, fInverseScaleFactor); // Sf isn't used for upscaling
917 if (sf < 1.0)
918 {
919 fLanczosT = 3.0;
920 }
921
922 for (i = 0; i < phaseCount; ++i, piCoefs += MHW_SCALER_UV_WIN_SIZE)
923 {
924 // Write all
925 // Note - to shift by a half you need to a half to each phase.
926 base = startOffset - (double)(i) / (double)(phaseCount);
927 sumCoefs = 0.0;
928
929 for (j = 0; j < MHW_SCALER_UV_WIN_SIZE; ++j)
930 {
931 pos = base + (double)j;
932 phaseCoefs[j] = MosUtilities::MosLanczos((float)(pos * sf), 6/*MHW_SCALER_UV_WIN_SIZE*/, fLanczosT);
933 sumCoefs += phaseCoefs[j];
934 }
935 // Normalize coefs and save
936 for (j = 0; j < MHW_SCALER_UV_WIN_SIZE; ++j)
937 {
938 piCoefs[j] = (int32_t)floor((0.5 + (double)(tableCoefUnit)* (phaseCoefs[j] / sumCoefs)));
939
940 // For debug purposes:
941 minCoef[j] = MOS_MIN(minCoef[j], piCoefs[j]);
942 maxCoef[j] = MOS_MAX(maxCoef[j], piCoefs[j]);
943 }
944
945 // Recalc center coef
946 sumQuantCoefs = 0;
947 for (j = 0; j < MHW_SCALER_UV_WIN_SIZE; ++j)
948 {
949 sumQuantCoefs += piCoefs[j];
950 }
951
952 // Fix center coef so that filter is balanced
953 adjusted_phase = i - iUvPhaseOffset;
954 if (adjusted_phase <= phaseCount / 2)
955 {
956 piCoefs[centerPixel] -= sumQuantCoefs - tableCoefUnit;
957 }
958 else // if(adjusted_phase < phaseCount)
959 {
960 piCoefs[centerPixel + 1] -= sumQuantCoefs - tableCoefUnit;
961 }
962 }
963
964 return eStatus;
965 }
966
967 //!
968 //! \brief Allocate BB
969 //! \details Allocated Batch Buffer
970 //! \param PMOS_INTERFACE pOsInterface
971 //! [in] Pointer to OS Interface
972 //! \param PMHW_BATCH_BUFFER pBatchBuffer
973 //! [in/out] Pointer to Batch Buffer
974 //! \param PMHW_BATCH_BUFFER pBatchBufferList
975 //! [in/out] If valid, represents the batch buffer list maintained by the client
976 //! \param uint32_t dwSize
977 //! [in] Sixe of the batch vuffer to be allocated
978 //! \param bool notLockable
979 //! [in] Indicate if the batch buffer not lockable, by default is false
980 //! \param bool inSystemMem
981 //! [in] Indicate if the batch buffer in system memory, by default is false
982 //! \return MOS_STATUS
983 //! true if the Batch Buffer was successfully allocated
984 //! false if failed
985 //!
Mhw_AllocateBb(PMOS_INTERFACE pOsInterface,PMHW_BATCH_BUFFER pBatchBuffer,PMHW_BATCH_BUFFER pBatchBufferList,uint32_t dwSize,uint32_t batchCount,bool notLockable,bool inSystemMem)986 MOS_STATUS Mhw_AllocateBb(
987 PMOS_INTERFACE pOsInterface,
988 PMHW_BATCH_BUFFER pBatchBuffer,
989 PMHW_BATCH_BUFFER pBatchBufferList,
990 uint32_t dwSize,
991 uint32_t batchCount,
992 bool notLockable,
993 bool inSystemMem)
994 {
995 MHW_FUNCTION_ENTER;
996
997 MOS_RESOURCE OsResource;
998 MOS_ALLOC_GFXRES_PARAMS AllocParams;
999 uint32_t allocSize;
1000 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1001
1002 MHW_CHK_NULL_RETURN(pOsInterface);
1003 MHW_CHK_NULL_RETURN(pBatchBuffer);
1004 MHW_ASSERT(!(notLockable && inSystemMem)); // Notlockable system memory doesn't make sense
1005
1006 dwSize += 8 * MHW_CACHELINE_SIZE;
1007 dwSize = MOS_ALIGN_CEIL(dwSize, MOS_PAGE_SIZE);
1008 allocSize = dwSize * batchCount;
1009
1010 MOS_ZeroMemory(&OsResource, sizeof(OsResource));
1011 MOS_ZeroMemory(&AllocParams, sizeof(AllocParams));
1012 AllocParams.Type = MOS_GFXRES_BUFFER;
1013 AllocParams.TileType = MOS_TILE_LINEAR;
1014 AllocParams.Format = Format_Buffer;
1015 AllocParams.dwBytes = allocSize;
1016 AllocParams.pBufName = "BatchBuffer";
1017 AllocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_MEDIA_BATCH_BUFFERS;
1018 AllocParams.Flags.bNotLockable = notLockable ? 1 : 0;
1019 if (notLockable)
1020 {
1021 AllocParams.dwMemType = MOS_MEMPOOL_DEVICEMEMORY;
1022 }
1023 else if (inSystemMem)
1024 {
1025 AllocParams.dwMemType = MOS_MEMPOOL_SYSTEMMEMORY;
1026 }
1027 else
1028 {
1029 AllocParams.dwMemType = MOS_MEMPOOL_VIDEOMEMORY;
1030 }
1031
1032 MHW_CHK_STATUS_RETURN(pOsInterface->pfnAllocateResource(
1033 pOsInterface,
1034 &AllocParams,
1035 &OsResource));
1036
1037 // Reset Allocation
1038 pOsInterface->pfnResetResourceAllocationIndex(pOsInterface, &OsResource);
1039
1040 pBatchBuffer->OsResource = OsResource;
1041 pBatchBuffer->iSize = (int32_t)dwSize;
1042 pBatchBuffer->count = batchCount;
1043 pBatchBuffer->iRemaining = pBatchBuffer->iSize;
1044 pBatchBuffer->iCurrent = 0;
1045 pBatchBuffer->bLocked = false;
1046 #if (_DEBUG || _RELEASE_INTERNAL)
1047 pBatchBuffer->iLastCurrent = 0;
1048 #endif
1049
1050 // Link BB for synchronization
1051 pBatchBuffer->bBusy = false;
1052 pBatchBuffer->dwCmdBufId = 0;
1053
1054 if (pBatchBufferList)
1055 {
1056 pBatchBuffer->pNext = pBatchBufferList;
1057 pBatchBufferList = pBatchBuffer;
1058 if (pBatchBuffer->pNext)
1059 {
1060 pBatchBuffer->pNext->pPrev = pBatchBuffer;
1061 }
1062 }
1063
1064 return eStatus;
1065 }
1066
1067 //!
1068 //! \brief Free BB
1069 //! \details Frees Batch Buffer
1070 //! \param PMOS_INTERFACE pOsInterface
1071 //! [in] Pointer to OS Interface
1072 //! \param PMHW_BATCH_BUFFER pBatchBuffer
1073 //! [in] Pointer to Batch Buffer
1074 //! \param PMHW_BATCH_BUFFER pBatchBufferList
1075 //! [in/out] If valid, represents the batch buffer list maintained by the client
1076 //! \return MOS_STATUS
1077 //!
Mhw_FreeBb(PMOS_INTERFACE pOsInterface,PMHW_BATCH_BUFFER pBatchBuffer,PMHW_BATCH_BUFFER pBatchBufferList)1078 MOS_STATUS Mhw_FreeBb(
1079 PMOS_INTERFACE pOsInterface,
1080 PMHW_BATCH_BUFFER pBatchBuffer,
1081 PMHW_BATCH_BUFFER pBatchBufferList)
1082 {
1083 MHW_FUNCTION_ENTER;
1084
1085 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1086
1087 MHW_CHK_NULL_RETURN(pOsInterface);
1088 MHW_CHK_NULL_RETURN(pBatchBuffer);
1089
1090 if (pBatchBuffer->bLocked)
1091 {
1092 MHW_CHK_STATUS_RETURN(Mhw_UnlockBb(pOsInterface, pBatchBuffer, true));
1093 }
1094
1095 pOsInterface->pfnFreeResource(pOsInterface, &pBatchBuffer->OsResource);
1096
1097 pBatchBuffer->dwCmdBufId = 0;
1098 pBatchBuffer->iSize = 0;
1099 pBatchBuffer->count = 0;
1100 pBatchBuffer->iCurrent = 0;
1101 #if (_DEBUG || _RELEASE_INTERNAL)
1102 pBatchBuffer->iLastCurrent = 0;
1103 #endif
1104
1105 if (pBatchBufferList)
1106 {
1107 // Unlink BB from synchronization list
1108 if (pBatchBuffer->pNext)
1109 {
1110 pBatchBuffer->pNext->pPrev = pBatchBuffer->pPrev;
1111 }
1112
1113 if (pBatchBuffer->pPrev)
1114 {
1115 pBatchBuffer->pPrev->pNext = pBatchBuffer->pNext;
1116 }
1117 else
1118 {
1119 pBatchBufferList = pBatchBuffer->pNext;
1120 }
1121
1122 pBatchBuffer->pPrev = pBatchBuffer->pNext = nullptr;
1123 }
1124
1125 return eStatus;
1126 }
1127
1128 //!
1129 //! \brief Lock BB
1130 //! \details Locks Batch Buffer
1131 //! \param PMOS_INTERFACE pOsInterface
1132 //! [in] Pointer to OS Interface
1133 //! \param PMHW_BATCH_BUFFER pBatchBuffer
1134 //! [in] Pointer to Batch Buffer
1135 //! \return MOS_STATUS
1136 //!
Mhw_LockBb(PMOS_INTERFACE pOsInterface,PMHW_BATCH_BUFFER pBatchBuffer)1137 MOS_STATUS Mhw_LockBb(
1138 PMOS_INTERFACE pOsInterface,
1139 PMHW_BATCH_BUFFER pBatchBuffer)
1140 {
1141 MHW_FUNCTION_ENTER;
1142
1143 MOS_LOCK_PARAMS LockFlags;
1144 MOS_STATUS eStatus;
1145
1146 MHW_CHK_NULL_RETURN(pOsInterface);
1147 MHW_CHK_NULL_RETURN(pBatchBuffer);
1148
1149 eStatus = MOS_STATUS_UNKNOWN;
1150
1151 if (pBatchBuffer->bLocked)
1152 {
1153 MHW_ASSERTMESSAGE("Batch Buffer is already locked.");
1154 return eStatus;
1155 }
1156
1157 MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS));
1158 LockFlags.WriteOnly = 1;
1159 pBatchBuffer->pData = (uint8_t*)pOsInterface->pfnLockResource(
1160 pOsInterface,
1161 &pBatchBuffer->OsResource,
1162 &LockFlags);
1163
1164 MHW_CHK_NULL_RETURN(pBatchBuffer->pData);
1165
1166 pBatchBuffer->bLocked = true;
1167 eStatus = MOS_STATUS_SUCCESS;
1168
1169 return eStatus;
1170 }
1171
1172 //!
1173 //! \brief Unlock BB
1174 //! \details Unlocks Batch Buffer
1175 //! \param PMOS_INTERFACE pOsInterface
1176 //! [in] Pointer to OS Interface
1177 //! \param PMHW_BATCH_BUFFER pBatchBuffer
1178 //! [in] Pointer to Batch Buffer
1179 //! \param bool bResetBuffer
1180 //! [in] Reset BB information concerning current offset and size
1181 //! \return MOS_STATUS
1182 //!
Mhw_UnlockBb(PMOS_INTERFACE pOsInterface,PMHW_BATCH_BUFFER pBatchBuffer,bool bResetBuffer)1183 MOS_STATUS Mhw_UnlockBb(
1184 PMOS_INTERFACE pOsInterface,
1185 PMHW_BATCH_BUFFER pBatchBuffer,
1186 bool bResetBuffer)
1187 {
1188 MHW_FUNCTION_ENTER;
1189
1190 MOS_STATUS eStatus;
1191
1192 MHW_CHK_NULL_RETURN(pOsInterface);
1193 MHW_CHK_NULL_RETURN(pBatchBuffer);
1194
1195 eStatus = MOS_STATUS_UNKNOWN;
1196
1197 if (!pBatchBuffer->bLocked)
1198 {
1199 MHW_ASSERTMESSAGE("Batch buffer is locked.");
1200 return eStatus;
1201 }
1202
1203 if (bResetBuffer)
1204 {
1205 pBatchBuffer->iRemaining = pBatchBuffer->iSize;
1206 pBatchBuffer->iCurrent = 0;
1207 }
1208
1209 MHW_CHK_STATUS_RETURN(pOsInterface->pfnUnlockResource(
1210 pOsInterface,
1211 &pBatchBuffer->OsResource));
1212
1213 pBatchBuffer->bLocked = false;
1214 pBatchBuffer->pData = nullptr;
1215
1216 eStatus = MOS_STATUS_SUCCESS;
1217
1218 return eStatus;
1219 }
1220
1221 //!
1222 //! \brief Convert To Nano Seconds
1223 //! \details Convert to Nano Seconds
1224 //! \param PVPHAL_HW_int32_tERFACE pHwInterface
1225 //! [in] Pointer to Hardware Interface Structure
1226 //! \param uint64_t iTicks
1227 //! [in] Ticks
1228 //! \param uint64_t* piNs
1229 //! [in] Nano Seconds
1230 //! \return MOS_STATUS
1231 //!
Mhw_ConvertToNanoSeconds(uint64_t iTicks,uint64_t * piNs)1232 MOS_STATUS Mhw_ConvertToNanoSeconds(
1233 uint64_t iTicks,
1234 uint64_t *piNs)
1235 {
1236 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1237
1238 MHW_CHK_NULL_RETURN(piNs);
1239
1240 *piNs = iTicks * MHW_NS_PER_TICK_RENDER_ENGINE;
1241
1242 return eStatus;
1243 }
1244
1245 //!
1246 //! \brief Convert Mos Tile Type to TR Mode
1247 //! \details Convert Mos Tile Type to TR Mode
1248 //! \param MOS_TILE_TYPE Type
1249 //! [in] MOS tile type
1250 //! \return uint32_t
1251 //! Tile Resouece Mode
1252 //!
Mhw_ConvertToTRMode(MOS_TILE_TYPE Type)1253 uint32_t Mhw_ConvertToTRMode(MOS_TILE_TYPE Type)
1254 {
1255 switch (Type)
1256 {
1257 case MOS_TILE_YS:
1258 return TRMODE_TILEYS;
1259 case MOS_TILE_YF:
1260 return TRMODE_TILEYF;
1261 default:
1262 return TRMODE_NONE;
1263 }
1264 }
1265