xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/hw/mhw_utilities_next.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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(&params, 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