xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/cm/hal/cm_hal_os.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2009-2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file      cm_hal_os.cpp
24 //! \brief     HAL Layer for CM Component on Linux
25 //!
26 #include "mos_os.h"
27 #include "cm_hal.h"
28 #include "cm_def_os.h"
29 #include "cm_execution_adv.h"
30 #include "mos_graphicsresource.h"
31 #include "mos_utilities.h"
32 #include "mos_bufmgr_api.h"
33 
34 #define Y_TILE_WIDTH  128
35 #define Y_TILE_HEIGHT 32
36 #define X_TILE_WIDTH  512
37 #define X_TILE_HEIGHT 8
38 #define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y))
39 
40 //*-----------------------------------------------------------------------------
41 //| Purpose:    Referece the OsResource
42 //| Returns:    N/A
43 //*-----------------------------------------------------------------------------
HalCm_OsResource_Reference(PMOS_RESOURCE osResource)44 void HalCm_OsResource_Reference(
45     PMOS_RESOURCE    osResource)
46 {
47     if (osResource && osResource->bo)
48     {
49         mos_bo_reference((MOS_LINUX_BO *)(osResource->bo));
50     }
51 }
52 
53 //*-----------------------------------------------------------------------------
54 //| Purpose:    unreferece the OsResource
55 //| Returns:    N/A
56 //*-----------------------------------------------------------------------------
HalCm_OsResource_Unreference(PMOS_RESOURCE osResource)57 void HalCm_OsResource_Unreference(
58     PMOS_RESOURCE    osResource)
59 {
60     if (osResource && osResource->bo)
61     {
62         mos_bo_unreference((MOS_LINUX_BO *)(osResource->bo));
63         osResource->bo = nullptr;
64     }
65 }
66 
67 //*-----------------------------------------------------------------------------
68 //| Purpose:    Reference the Command Buffer and Pass it to event
69 //| Returns:    N/A
70 //*-----------------------------------------------------------------------------
HalCm_ReferenceCommandBuf_Linux(PMOS_RESOURCE osResource,void ** cmdBuffer)71 MOS_STATUS HalCm_ReferenceCommandBuf_Linux(
72     PMOS_RESOURCE     osResource,        //  [in]  Command Buffer's MOS Resurce
73     void             **cmdBuffer)       // [out] Comamnd Buffer to pass to event
74 {
75     if (osResource && osResource->bo)
76     {
77         mos_bo_reference((MOS_LINUX_BO *)(osResource->bo));
78         *cmdBuffer = osResource->bo;
79     }
80 
81     return MOS_STATUS_SUCCESS;
82 }
83 
84 //*-----------------------------------------------------------------------------
85 //| Purpose:    Set Command Buffer Resource and Pass it to event
86 //| Returns:    N/A
87 //*-----------------------------------------------------------------------------
HalCm_SetCommandBufResource_Linux(PMOS_RESOURCE osResource,void ** cmdBuffer)88 MOS_STATUS HalCm_SetCommandBufResource_Linux(
89     PMOS_RESOURCE     osResource,        //  [in]  Command Buffer's MOS Resurce
90     void             **cmdBuffer)       // [out] Comamnd Buffer to pass to event
91 {
92     if (osResource && osResource->bo)
93     {
94         *cmdBuffer = osResource->bo;
95     }
96 
97     return MOS_STATUS_SUCCESS;
98 }
99 
100 //*-----------------------------------------------------------------------------
101 //| Purpose:    Get 2D surface info and register to OS-Command-Buffer's patch list.
102 //| Returns:    Result of the operation.
103 //*-----------------------------------------------------------------------------
HalCm_GetSurfaceAndRegister(PCM_HAL_STATE state,PRENDERHAL_SURFACE renderHalSurface,CM_HAL_KERNEL_ARG_KIND surfKind,uint32_t index,bool pixelPitch)104 MOS_STATUS HalCm_GetSurfaceAndRegister(
105     PCM_HAL_STATE                state,
106     PRENDERHAL_SURFACE           renderHalSurface,
107     CM_HAL_KERNEL_ARG_KIND       surfKind,
108     uint32_t                     index,
109     bool                         pixelPitch)
110 {
111     MOS_STATUS eStatus = MOS_STATUS_UNKNOWN;
112     RENDERHAL_GET_SURFACE_INFO      info;
113     PRENDERHAL_INTERFACE            renderHal   = state->renderHal;
114     PMOS_SURFACE                    surface     = &renderHalSurface->OsSurface;
115     PRENDERHAL_MEDIA_STATE_LEGACY   mediaState  = nullptr;
116 
117     if (!renderHalSurface)
118     {
119         goto finish;
120     }
121     else
122     {
123         MOS_ZeroMemory(renderHalSurface, sizeof(RENDERHAL_SURFACE));
124     }
125 
126     switch(surfKind)
127     {
128         case CM_ARGUMENT_STATE_BUFFER:
129             mediaState = (PRENDERHAL_MEDIA_STATE_LEGACY)state->pfnGetMediaStatePtrForSurfaceIndex( state, index );
130             CM_CHK_HRESULT_GOTOFINISH_MOSERROR(renderHal->pOsInterface->pfnRegisterResource(
131                 renderHal->pOsInterface, mediaState->pDynamicState->memoryBlock.GetResource(), true, true));
132             surface->OsResource.user_provided_va = state->pfnGetStateBufferVAPtrForSurfaceIndex( state, index );
133             surface->dwWidth = mediaState->pDynamicState->Curbe.dwSize;
134             surface->dwHeight = 1;
135             surface->Format = Format_RAW;
136             return MOS_STATUS_SUCCESS; // state buffer's OS resource belong to DSH, so don't need sync it and just return directly.
137 
138         case CM_ARGUMENT_SURFACEBUFFER:
139             surface->dwWidth      = state->bufferTable[index].size;
140             surface->dwHeight     = 1;
141             surface->Format       = Format_RAW;
142             renderHalSurface->rcSrc.right  = surface->dwWidth;
143             renderHalSurface->rcSrc.bottom = surface->dwHeight;
144             renderHalSurface->rcDst        = renderHalSurface->rcSrc;
145             CM_CHK_HRESULT_GOTOFINISH_MOSERROR(renderHal->pOsInterface->pfnRegisterResource(
146                 renderHal->pOsInterface, &(state->bufferTable[index].osResource), true, true));
147             surface->OsResource  = state->bufferTable[index].osResource;
148         break;
149 
150         case CM_ARGUMENT_SURFACE3D:
151             /* First register resource on Linux to get allocation slot on GpuContext */
152             CM_CHK_HRESULT_GOTOFINISH_MOSERROR(renderHal->pOsInterface->pfnRegisterResource(
153                 renderHal->pOsInterface, &(state->surf3DTable[index].osResource), true, true));
154 
155             surface->OsResource   = state->surf3DTable[index].osResource;
156             surface->Format       = Format_Invalid;
157 
158             MOS_ZeroMemory(&info, sizeof(RENDERHAL_GET_SURFACE_INFO));
159 
160             CM_CHK_MOSSTATUS_GOTOFINISH(RenderHal_GetSurfaceInfo(
161                 renderHal->pOsInterface,
162                 &info,
163                 surface));
164 
165             surface->Format       = state->surf3DTable[index].osResource.Format;
166             renderHalSurface->rcSrc.right  = surface->dwWidth;
167             renderHalSurface->rcSrc.bottom = surface->dwHeight;
168             renderHalSurface->rcDst        = renderHalSurface->rcSrc;
169         break;
170 
171         case CM_ARGUMENT_SURFACE2D:
172             /* First register resource on Linux to get allocation slot on GpuContext */
173             CM_CHK_HRESULT_GOTOFINISH_MOSERROR(renderHal->pOsInterface->pfnRegisterResource(
174                 renderHal->pOsInterface, &(state->umdSurf2DTable[index].osResource), true, true));
175 
176             surface->OsResource     = state->umdSurf2DTable[index].osResource;
177 
178             MOS_ZeroMemory(&info, sizeof(RENDERHAL_GET_SURFACE_INFO));
179             CM_CHK_MOSSTATUS_GOTOFINISH(RenderHal_GetSurfaceInfo(
180                 renderHal->pOsInterface,
181                 &info,
182                 surface));
183 
184             if ( (surface->Format == Format_NV12 || surface->Format == Format_YV12 || surface->Format == Format_Y210 || surface->Format == Format_Y216)
185                   && (!pixelPitch))
186             {
187                 renderHalSurface->SurfType = RENDERHAL_SURF_OUT_RENDERTARGET;
188             }
189 
190             surface->Format         = state->umdSurf2DTable[index].format;
191             renderHalSurface->rcSrc.right  = surface->dwWidth;
192             renderHalSurface->rcSrc.bottom = surface->dwHeight;
193             renderHalSurface->rcDst        = renderHalSurface->rcSrc;
194             break;
195 
196         case CM_ARGUMENT_SURFACE2D_UP:
197             /* First register resource on Linux to get allocation slot on GpuContext */
198             CM_CHK_HRESULT_GOTOFINISH_MOSERROR(renderHal->pOsInterface->pfnRegisterResource(
199                 renderHal->pOsInterface,  &(state->surf2DUPTable[index].osResource), true, true));
200 
201             // Get Details of 2D surface and fill the VPHAL surface
202             surface->OsResource = state->surf2DUPTable[index].osResource;
203             surface->dwWidth    = state->surf2DUPTable[index].width;
204             surface->dwHeight   = state->surf2DUPTable[index].height;
205             surface->Format     = state->surf2DUPTable[index].format;
206             surface->dwDepth    = 1;
207             surface->TileType   = MOS_TILE_LINEAR;
208             //surface->Channel    = MOS_S3D_NONE;
209             surface->dwOffset   = 0;
210 
211             if ( (surface->Format == Format_NV12 || surface->Format == Format_YV12 || surface->Format == Format_Y210 || surface->Format == Format_Y216)
212                   && (!pixelPitch))
213             {
214                 renderHalSurface->SurfType = RENDERHAL_SURF_OUT_RENDERTARGET;
215             }
216 
217             MOS_ZeroMemory(&info, sizeof(RENDERHAL_GET_SURFACE_INFO));
218 
219             CM_CHK_MOSSTATUS_GOTOFINISH(RenderHal_GetSurfaceInfo(
220                 renderHal->pOsInterface,
221                 &info,
222                 surface));
223 
224             renderHalSurface->rcSrc.right  = surface->dwWidth;
225             renderHalSurface->rcSrc.bottom = surface->dwHeight;
226             renderHalSurface->rcDst        = renderHalSurface->rcSrc;
227             break;
228 
229         case CM_ARGUMENT_VME_STATE:
230             /* First register resource on Linux to get allocation slot on GpuContext */
231             CM_CHK_HRESULT_GOTOFINISH_MOSERROR(renderHal->pOsInterface->pfnRegisterResource(
232                 renderHal->pOsInterface, &(state->umdSurf2DTable[index].osResource), true, true));
233 
234             surface->OsResource = state->umdSurf2DTable[index].osResource;
235 
236             MOS_ZeroMemory(&info, sizeof(RENDERHAL_GET_SURFACE_INFO));
237 
238             CM_CHK_MOSSTATUS_GOTOFINISH(RenderHal_GetSurfaceInfo(
239                 renderHal->pOsInterface,
240                 &info,
241                 surface));
242 
243             surface->Format     = state->umdSurf2DTable[index].format;
244 
245             if (!state->cmHalInterface->IsSupportedVMESurfaceFormat(surface->Format))
246             {
247                 eStatus = MOS_STATUS_INVALID_PARAMETER;
248                 CM_ASSERTMESSAGE("Invalid VME surface format");
249                 goto finish;
250             }
251 
252             renderHalSurface->rcSrc.right  = surface->dwWidth;
253             renderHalSurface->rcSrc.bottom = surface->dwHeight;
254             renderHalSurface->rcDst        = renderHalSurface->rcSrc;
255             break;
256 
257         case CM_ARGUMENT_SURFACE_SAMPLER8X8_AVS:
258         case CM_ARGUMENT_SURFACE_SAMPLER8X8_VA:
259             /* First register resource on Linux to get allocation slot on GpuContext */
260             CM_CHK_HRESULT_GOTOFINISH_MOSERROR(renderHal->pOsInterface->pfnRegisterResource(
261                 renderHal->pOsInterface, &(state->umdSurf2DTable[index].osResource), true, true));
262 
263             // Get Details of 2D surface and fill the VPHAL surface
264             surface->OsResource  = state->umdSurf2DTable[index].osResource;
265 
266             MOS_ZeroMemory(&info, sizeof(RENDERHAL_GET_SURFACE_INFO));
267 
268             CM_CHK_MOSSTATUS_GOTOFINISH(RenderHal_GetSurfaceInfo(
269                 renderHal->pOsInterface,
270                 &info,
271                 surface));
272 
273             surface->Format        = state->umdSurf2DTable[index].osResource.Format;
274             renderHalSurface->rcSrc.right  = surface->dwWidth;
275             renderHalSurface->rcSrc.bottom = surface->dwHeight;
276             renderHalSurface->rcDst        = renderHalSurface->rcSrc;
277             break;
278 
279         default:
280             eStatus = MOS_STATUS_INVALID_PARAMETER;
281             CM_ASSERTMESSAGE(
282                 "Argument kind '%d' is not supported", surfKind);
283             goto finish;
284     }
285 
286     //Tag-based Sync on the Resource/surface
287     CM_CHK_MOSSTATUS_GOTOFINISH(state->pfnSyncOnResource(state, surface, true));
288 
289     eStatus = MOS_STATUS_SUCCESS;
290 finish:
291     return eStatus;
292 }
293 
294 //===============<Os-dependent DDI Functions>============================================
295 //*-----------------------------------------------------------------------------
296 //| Purpose:    Get 2D surface pitch and physical size for SURFACE2D_UP
297 //| Returns:    Result of the operation.
298 //*-----------------------------------------------------------------------------
HalCm_GetSurfPitchSize(uint32_t width,uint32_t height,MOS_FORMAT format,uint32_t * pitch,uint32_t * physicalSize,PCM_HAL_STATE state)299 MOS_STATUS HalCm_GetSurfPitchSize(
300     uint32_t width, uint32_t height, MOS_FORMAT format, uint32_t *pitch, uint32_t *physicalSize, PCM_HAL_STATE state)
301 {
302 
303     MOS_STATUS           eStatus = MOS_STATUS_SUCCESS;
304     GMM_RESOURCE_INFO*   gmmResInfo = nullptr;
305     GMM_RESOURCE_FLAG    gmmFlags;
306     GMM_RESCREATE_PARAMS gmmParams;
307 
308     MOS_ZeroMemory( &gmmFlags, sizeof( GMM_RESOURCE_FLAG ) );
309     MOS_ZeroMemory( &gmmParams, sizeof( GMM_RESCREATE_PARAMS ) );
310 
311     if( nullptr == state ||
312         nullptr == state->osInterface ||
313         nullptr == pitch ||
314         nullptr == physicalSize)
315     {
316         eStatus = MOS_STATUS_NULL_POINTER;
317         goto finish;
318     }
319 
320     gmmFlags.Info.Linear    = true;
321     gmmFlags.Info.Cacheable = true;
322     gmmFlags.Gpu.Texture    = true;
323 
324     gmmParams.Type           = RESOURCE_2D;
325     gmmParams.Format         = MosInterface::MosFmtToGmmFmt( format );
326     gmmParams.Flags          = gmmFlags;
327     gmmParams.BaseWidth      = width;
328     gmmParams.BaseHeight     = height;
329     gmmParams.Depth          = 1;
330     gmmParams.ArraySize      = 1;
331     gmmParams.NoGfxMemory    = true;
332 
333     // get pitch and size
334     if (nullptr == state ||
335         nullptr == state->osInterface)
336     {
337         eStatus = MOS_STATUS_NULL_POINTER;
338         goto finish;
339     }
340     gmmResInfo = state->osInterface->pfnGetGmmClientContext(state->osInterface)->CreateResInfoObject(&gmmParams);
341     if (gmmResInfo != nullptr)
342     {
343         *pitch             = static_cast<uint32_t>( gmmResInfo->GetRenderPitch() );
344         *physicalSize      = static_cast<uint32_t>( gmmResInfo->GetSizeSurface() );
345         state->osInterface->pfnGetGmmClientContext(state->osInterface)->DestroyResInfoObject(gmmResInfo);
346     }
347     else
348     {
349         *pitch = 0;
350         *physicalSize = 0;
351     }
352 
353 finish:
354     return eStatus;
355 
356 }
357 
358 //*-----------------------------------------------------------------------------
359 //| Purpose:    Get 2D surface pitch and physical size for SURFACE2D_UP
360 //| Returns:    Result of the operation.
361 //*-----------------------------------------------------------------------------
HalCm_GetSurface2DPitchAndSize(PCM_HAL_STATE state,PCM_HAL_SURFACE2D_UP_PARAM param)362 MOS_STATUS HalCm_GetSurface2DPitchAndSize(
363     PCM_HAL_STATE                   state,                                             // [in]  Pointer to CM State
364     PCM_HAL_SURFACE2D_UP_PARAM      param)                                             // [in]  Pointer to Buffer Param
365 {
366     return HalCm_GetSurfPitchSize(param->width, param->height, param->format,
367                                   &param->pitch, &param->physicalSize, state);
368 }
369 
370 //*-----------------------------------------------------------------------------
371 //| Purpose:    Register APP/Runtime-level created Event Handle as a UMD Object;
372 //| Returns:    Result of the operation.
373 //*-----------------------------------------------------------------------------
HalCm_RegisterUMDNotifyEventHandle(PCM_HAL_STATE state,PCM_HAL_OSSYNC_PARAM syncParam)374 MOS_STATUS HalCm_RegisterUMDNotifyEventHandle(
375     PCM_HAL_STATE             state,
376     PCM_HAL_OSSYNC_PARAM      syncParam)
377 {
378     MOS_STATUS              eStatus;
379     UNUSED(state);
380     UNUSED(syncParam);
381     //-----------------------------------------
382     CM_ASSERT(state);
383     CM_ASSERT(syncParam);
384     //-----------------------------------------
385     eStatus               = MOS_STATUS_SUCCESS;
386 
387     return eStatus;
388 }
389 
HalCm_GetSurf2DUPBaseWidth(uint32_t width,uint32_t pitch,MOS_FORMAT format)390 uint32_t HalCm_GetSurf2DUPBaseWidth( uint32_t width, uint32_t pitch, MOS_FORMAT format)
391 {
392     uint32_t baseWidth = width;
393     uint32_t pixelSize = 1;
394 
395     switch(format)
396     {
397         case Format_L8 :
398         case Format_P8 :
399         case Format_A8 :
400         case Format_NV12:
401             pixelSize = 1;
402             break;
403 
404         case Format_X8R8G8B8    :
405         case Format_A8R8G8B8    :
406         case Format_A8B8G8R8    :
407         case Format_R32F        :
408             pixelSize = 4;
409             break;
410 
411         case Format_V8U8        :
412         case Format_YUY2        :
413         case Format_UYVY        :
414             pixelSize = 2;
415             break;
416 
417         default:
418             CM_ASSERTMESSAGE("Error: Unsupported surface format.");
419             break;
420     }
421 
422     baseWidth = pitch/pixelSize;
423     return baseWidth;
424 }
425 
426 //*-----------------------------------------------------------------------------
427 //| Purpose:    Allocate Linear Buffer or BufferUP
428 //| Returns:    Result of the operation.
429 //*-----------------------------------------------------------------------------
HalCm_AllocateBuffer_Linux(PCM_HAL_STATE state,PCM_HAL_BUFFER_PARAM param)430 MOS_STATUS HalCm_AllocateBuffer_Linux(
431     PCM_HAL_STATE           state,                                             // [in]  Pointer to CM State
432     PCM_HAL_BUFFER_PARAM    param)                                             // [in]  Pointer to Buffer Param
433 {
434     MOS_STATUS              eStatus;
435     PMOS_INTERFACE          osInterface;
436     PCM_HAL_BUFFER_ENTRY    entry = nullptr;
437     MOS_ALLOC_GFXRES_PARAMS allocParams;
438     uint32_t                i;
439     uint32_t                size;
440     uint32_t                tileformat;
441     const char              *fmt;
442     PMOS_RESOURCE           osResource;
443     MOS_LINUX_BO             *bo = nullptr;
444 
445     size  = param->size;
446     tileformat = TILING_NONE;
447 
448     //-----------------------------------------------
449     CM_ASSERT(param->size > 0);
450     //-----------------------------------------------
451 
452     eStatus        = MOS_STATUS_SUCCESS;
453     osInterface    = state->renderHal->pOsInterface;
454 
455     // Find a free slot
456     for (i = 0; i < state->cmDeviceParam.maxBufferTableSize; i++)
457     {
458         if (state->bufferTable[i].size == 0)
459         {
460             entry              = &state->bufferTable[i];
461             param->handle      = (uint32_t)i;
462             break;
463         }
464     }
465 
466     if (!entry)
467     {
468         eStatus = MOS_STATUS_INVALID_PARAMETER;
469         CM_ASSERTMESSAGE("Buffer table is full");
470         goto finish;
471     }
472 
473     // State buffer doesn't need any MOS RESOURCE, so it will return directly after getting a position in the buffer table
474     if ( param->type == CM_BUFFER_STATE )
475     {
476         entry->size = param->size;
477         entry->isAllocatedbyCmrtUmd = false;
478         return eStatus;
479     }
480 
481     osResource = &(entry->osResource);
482 
483     if (param->isAllocatedbyCmrtUmd)
484     {
485         // Resets the Resource
486         Mos_ResetResource(osResource);
487 
488         if (param->data == nullptr)
489         {
490             MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
491             allocParams.Type          = MOS_GFXRES_BUFFER;
492             allocParams.TileType      = MOS_TILE_LINEAR;
493             allocParams.dwBytes       = param->size;
494             allocParams.pSystemMemory = param->data;
495             allocParams.Format        = Format_Buffer;  //used in VpHal_OsAllocateResource_Linux!
496 
497             if (param->type == CM_BUFFER_N)
498             {
499                 allocParams.pBufName = "CmBuffer";
500             }
501             else if (param->type == CM_BUFFER_STATELESS)
502             {
503                 allocParams.pBufName = "CmBufferStateless";
504             }
505 
506             CM_CHK_HRESULT_GOTOFINISH_MOSERROR(osInterface->pfnAllocateResource(
507                 osInterface,
508                 &allocParams,
509                 &entry->osResource));
510 
511         }
512         else  //BufferUP
513         {
514             // If user provides a system memory pointer, the gfx resource is backed
515             // by the system memory pages. The resource is required to be linear.
516             GMM_RESCREATE_PARAMS    gmmParams;
517             MOS_ZeroMemory(&gmmParams, sizeof(GMM_RESCREATE_PARAMS));
518 
519             gmmParams.Flags.Info.Linear = true;
520             gmmParams.Flags.Info.Cacheable = true;
521             gmmParams.NoGfxMemory = true;
522             gmmParams.Type = RESOURCE_BUFFER;
523             gmmParams.Flags.Gpu.State = true;
524             gmmParams.BaseWidth = param->size;
525             gmmParams.BaseHeight = 1;
526             gmmParams.ArraySize = 1;
527             gmmParams.Format = MosInterface::MosFmtToGmmFmt(Format_Buffer);
528 
529             GMM_CLIENT_CONTEXT* pGmmClientContext = osInterface->pfnGetGmmClientContext(osInterface);
530             GMM_RESOURCE_INFO* tmpGmmResInfoPtr = pGmmClientContext->CreateResInfoObject(&gmmParams);
531             osResource->pGmmResInfo = tmpGmmResInfoPtr;
532 
533             MosUtilities::MosAtomicIncrement(MosUtilities::m_mosMemAllocCounterGfx);
534 
535             struct mos_drm_bo_alloc_userptr alloc_uptr;
536             alloc_uptr.name = "CM Buffer UP";
537             alloc_uptr.addr = (void *)(param->data);
538             alloc_uptr.tiling_mode = tileformat;
539             alloc_uptr.stride = ROUND_UP_TO(size,MOS_PAGE_SIZE);
540             alloc_uptr.size = ROUND_UP_TO(size,MOS_PAGE_SIZE);
541 
542             bo =  mos_bo_alloc_userptr(osInterface->pOsContext->bufmgr, &alloc_uptr);
543 
544             osResource->bMapped = false;
545             if (bo)
546             {
547                 osResource->Format   = Format_Buffer;
548                 osResource->iWidth   = ROUND_UP_TO(size,MOS_PAGE_SIZE);
549                 osResource->iHeight  = 1;
550                 osResource->iPitch   = ROUND_UP_TO(size,MOS_PAGE_SIZE);
551                 osResource->bo       = bo;
552                 osResource->TileType = LinuxToMosTileType(tileformat);
553                 osResource->pData    = (uint8_t*) bo->virt;
554             }
555             else
556             {
557                 fmt = "BufferUP";
558                 CM_ASSERTMESSAGE("Fail to Alloc BufferUP %7d bytes (%d x %d %s resource)\n",size, size, 1, fmt);
559                 eStatus = MOS_STATUS_UNKNOWN;
560             }
561             osResource->bConvertedFromDDIResource = true;
562         }
563     }
564     else
565     {
566         entry->osResource = *param->mosResource;
567         HalCm_OsResource_Reference(&entry->osResource);
568     }
569 
570     entry->size = param->size;
571     entry->isAllocatedbyCmrtUmd = param->isAllocatedbyCmrtUmd;
572     entry->surfaceStateEntry[0].surfaceStateSize = entry->size;
573     entry->surfaceStateEntry[0].surfaceStateOffset = 0;
574     entry->surfaceStateEntry[0].surfaceStateMOCS = 0;
575     if(param->type == CM_BUFFER_STATELESS)
576     {
577         state->statelessBufferUsed = true;
578 
579         // get GPU virtual address
580         // Fix: pfnGetResourceGfxAddress is not implemented. Need to find solution to
581         // get the GFX address.
582         param->gfxAddress = osInterface->pfnGetResourceGfxAddress(osInterface,
583                                                                   &(entry->osResource));
584         entry->address = reinterpret_cast<void *>(param->gfxAddress);
585     }
586 
587     if (state->advExecutor)
588     {
589         entry->surfStateMgr = state->advExecutor->CreateBufferStateMgr(&entry->osResource);
590         state->advExecutor->SetBufferOrigSize(entry->surfStateMgr, entry->size);
591     }
592 
593 finish:
594     return eStatus;
595 }
596 
597 //*-----------------------------------------------------------------------------
598 //| Purpose:    Allocate Surface2DUP (zero-copy, map system memory to video address space)
599 //| Returns:    Result of the operation.
600 //*-----------------------------------------------------------------------------
HalCm_AllocateSurface2DUP_Linux(PCM_HAL_STATE state,PCM_HAL_SURFACE2D_UP_PARAM param)601 MOS_STATUS HalCm_AllocateSurface2DUP_Linux(
602     PCM_HAL_STATE state,               // [in]  Pointer to CM State
603     PCM_HAL_SURFACE2D_UP_PARAM param)  // [in]  Pointer to Buffer Param
604 {
605     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
606     PMOS_INTERFACE osInterface = state->renderHal->pOsInterface;
607     PCM_HAL_SURFACE2D_UP_ENTRY entry = nullptr;
608 
609     MOS_ALLOC_GFXRES_PARAMS allocParams;
610 
611     //-----------------------------------------------
612     CM_ASSERT(state);
613     CM_ASSERT(param->width > 0 && param->height > 0);
614     //-----------------------------------------------
615 
616     // Find a free slot
617     for (uint32_t i = 0; i < state->cmDeviceParam.max2DSurfaceUPTableSize; ++i)
618     {
619         if (state->surf2DUPTable[i].width == 0)
620         {
621             entry              = &state->surf2DUPTable[i];
622             param->handle      = (uint32_t)i;
623             break;
624         }
625     }
626     if (!entry)
627     {
628         eStatus = MOS_STATUS_INVALID_PARAMETER;
629         CM_ASSERTMESSAGE("Surface2DUP table is full");
630         goto finish;
631     }
632     MOS_ZeroMemory(&allocParams, sizeof(allocParams));
633     allocParams.Type          = MOS_GFXRES_2D;
634     allocParams.TileType      = MOS_TILE_LINEAR;
635     allocParams.dwWidth       = param->width;
636     allocParams.dwHeight      = param->height;
637     allocParams.pSystemMemory = param->data;
638     allocParams.Format        = param->format;
639     allocParams.pBufName      = "CmSurface2DUP";
640 
641     CM_CHK_HRESULT_GOTOFINISH_MOSERROR(osInterface->pfnAllocateResource(
642         osInterface,
643         &allocParams,
644         &entry->osResource));
645 
646     entry->width  = param->width;
647     entry->height = param->height;
648     entry->format  = param->format;
649 
650     if (state->advExecutor)
651     {
652         entry->surfStateMgr = state->advExecutor->Create2DStateMgr(&entry->osResource);
653     }
654 
655 finish:
656     return eStatus;
657 }
658 
659 //*-----------------------------------------------------------------------------
660 //| Purpose:    Get GPU current frequency
661 //| Returns:    Result of the operation.
662 //*-----------------------------------------------------------------------------
HalCm_GetGPUCurrentFrequency(PCM_HAL_STATE state,uint32_t * currentFrequency)663 MOS_STATUS HalCm_GetGPUCurrentFrequency(
664     PCM_HAL_STATE               state,                                         // [in]  Pointer to CM State
665     uint32_t                    *currentFrequency)                                   // [out] Pointer to current frequency
666 {
667     UNUSED(state);
668 
669     //-----------------------------------------
670     CM_ASSERT(state);
671     //-----------------------------------------
672     *currentFrequency   = 0;
673 
674     return MOS_STATUS_SUCCESS;
675 }
676 
HalCm_GetGpuTime(PCM_HAL_STATE state,uint64_t * gpuTime)677 MOS_STATUS HalCm_GetGpuTime(PCM_HAL_STATE state, uint64_t *gpuTime)
678 {
679     UNUSED(state);
680     *gpuTime = 0;
681 
682     return MOS_STATUS_SUCCESS;
683 }
684 
685 //*-----------------------------------------------------------------------------
686 // Purpose: Check if conditional batch buffer supported
687 // Returns: False on Linux
688 //*-----------------------------------------------------------------------------
HalCm_IsCbbEnabled(PCM_HAL_STATE state)689 bool HalCm_IsCbbEnabled(
690     PCM_HAL_STATE                           state)
691 {
692     return false;
693 }
694 
695 //*-----------------------------------------------------------------------------
696 // Purpose: Wait kernel finished in state heap
697 // Returns: Result of the operation
698 //*-----------------------------------------------------------------------------
HalCm_SyncKernel(PCM_HAL_STATE state,uint32_t sync)699 int32_t HalCm_SyncKernel(
700     PCM_HAL_STATE                           state,
701     uint32_t                                sync)
702 {
703     int32_t                    eStatus = CM_SUCCESS;
704     PRENDERHAL_INTERFACE       renderHal = state->renderHal;
705     PRENDERHAL_STATE_HEAP      stateHeap = renderHal->pStateHeap;
706 
707     // Update Sync tags
708     CM_CHK_MOSSTATUS_GOTOFINISH(renderHal->pfnRefreshSync(renderHal));
709 
710     while ( ( int32_t )( stateHeap->dwSyncTag - sync ) < 0 )
711     {
712         CM_CHK_MOSSTATUS_GOTOFINISH( renderHal->pfnRefreshSync( renderHal ) );
713     }
714 
715 finish:
716     return eStatus;
717 }
718 
719 //===============<Os-dependent Private/Non-DDI Functions, Part 2>============================================
720 
721 //Require DRM VMAP patch,
722 //Referecing:
723 //    [Intel-gfx] [PATCH 21/21] drm/i915: Introduce vmap (mapping of user pages into video memory) ioctl
724 //    http://lists.freedesktop.org/archives/intel-gfx/2011-April/010241.html
HalCm_GetLibDrmVMapFnt(PCM_HAL_STATE cmState)725 void HalCm_GetLibDrmVMapFnt(
726                  PCM_HAL_STATE           cmState)
727 {
728     cmState->hLibModule = nullptr;
729     cmState->drmVMap = nullptr;
730     return ;
731 }
732 
733 //*-----------------------------------------------------------------------------
734 //| Purpose:  Gets platform information like slices/sub-slices/EUPerSubSlice etc.
735 //| Returns:  Result of the operation
736 //*-----------------------------------------------------------------------------
HalCm_GetPlatformInfo_Linux(PCM_HAL_STATE state,PCM_PLATFORM_INFO platformInfo,bool euSaturated)737 MOS_STATUS HalCm_GetPlatformInfo_Linux(
738     PCM_HAL_STATE                  state,              // [in] Pointer to CM State
739     PCM_PLATFORM_INFO               platformInfo,        // [out] Pointer to platformInfo
740     bool                           euSaturated)
741 {
742 
743     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
744     MEDIA_SYSTEM_INFO             *gtSystemInfo;
745 
746     UNUSED(euSaturated);
747 
748     gtSystemInfo = state->osInterface->pfnGetGtSystemInfo(state->osInterface);
749 
750     platformInfo->numHWThreadsPerEU    = gtSystemInfo->ThreadCount / gtSystemInfo->EUCount;
751     platformInfo->numEUsPerSubSlice    = gtSystemInfo->EUCount / gtSystemInfo->SubSliceCount;
752 
753     if (state->cmHalInterface->CheckMediaModeAvailability())
754     {
755         platformInfo->numSlices            = gtSystemInfo->SliceCount;
756         platformInfo->numSubSlices         = gtSystemInfo->SubSliceCount;
757     }
758     else
759     { // not use Slice/SubSlice count  set to 0
760         platformInfo->numSlices = 0;
761         platformInfo->numSubSlices = 0;
762     }
763 
764     return eStatus;
765 }
766 
767 //*-----------------------------------------------------------------------------
768 //| Purpose:  Gets GT system information for which slices/sub-slices are enabled
769 //| Returns:  Result of the operation
770 //*-----------------------------------------------------------------------------
HalCm_GetGTSystemInfo_Linux(PCM_HAL_STATE state,PCM_GT_SYSTEM_INFO pSystemInfo)771 MOS_STATUS HalCm_GetGTSystemInfo_Linux(
772     PCM_HAL_STATE                state,                // [in] Pointer to CM state
773     PCM_GT_SYSTEM_INFO           pSystemInfo            // [out] Pointer to CM GT system info
774 )
775 {
776     MEDIA_SYSTEM_INFO            *gtSystemInfo;
777     CM_EXPECTED_GT_SYSTEM_INFO    expectedGTInfo;
778 
779     gtSystemInfo = state->osInterface->pfnGetGtSystemInfo(state->osInterface);
780 
781     pSystemInfo->numMaxSlicesSupported    = gtSystemInfo->MaxSlicesSupported;
782     pSystemInfo->numMaxSubSlicesSupported = gtSystemInfo->MaxSubSlicesSupported;
783 
784     state->cmHalInterface->GetExpectedGtSystemConfig(&expectedGTInfo);
785 
786     // check numSlices/SubSlices enabled equal the expected number for this GT
787     // if match, pSystemInfo->isSliceInfoValid = true, else pSystemInfo->isSliceInfoValid = false
788     if ((expectedGTInfo.numSlices    == gtSystemInfo->SliceCount) &&
789         (expectedGTInfo.numSubSlices == gtSystemInfo->SubSliceCount))
790     {
791         pSystemInfo->isSliceInfoValid = true;
792     }
793     else
794     {
795         pSystemInfo->isSliceInfoValid = false;
796     }
797 
798     // if valid, set the number slice/subSlice to enabled for numSlices/numSubSlices
799     if(pSystemInfo->isSliceInfoValid)
800     {
801         for(uint32_t i = 0; i < gtSystemInfo->SliceCount; ++i)
802         {
803             pSystemInfo->sliceInfo[i].Enabled = true;
804             for(uint32_t j = 0; j < gtSystemInfo->SubSliceCount; ++j)
805             {
806                 pSystemInfo->sliceInfo[i].SubSliceInfo[j].Enabled = true;
807             }
808         }
809     }
810 
811     return MOS_STATUS_SUCCESS;
812 }
813 
814 //*-----------------------------------------------------------------------------
815 //| Purpose:    Query the status of the task
816 //| Returns:    Result of the operation.
817 //*-----------------------------------------------------------------------------
HalCm_QueryTask_Linux(PCM_HAL_STATE state,PCM_HAL_QUERY_TASK_PARAM queryParam)818 MOS_STATUS HalCm_QueryTask_Linux(
819     PCM_HAL_STATE             state,
820     PCM_HAL_QUERY_TASK_PARAM  queryParam)
821 {
822     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
823     PRENDERHAL_INTERFACE    renderHal;
824     int64_t                 *piSyncStart;
825     int64_t                 *piSyncEnd;
826     uint64_t                ticks;
827     int32_t                 syncOffset;
828     PRENDERHAL_STATE_HEAP   stateHeap;
829     uint64_t                hwStartNs;
830     uint64_t                hwEndNs;
831     int32_t                 maxTasks;
832 
833     //-----------------------------------------
834     CM_ASSERT(state);
835     CM_ASSERT(queryParam);
836     //-----------------------------------------
837 
838     maxTasks = (int32_t)state->cmDeviceParam.maxTasks;
839     if ((queryParam->taskId < 0) || (queryParam->taskId >= maxTasks) ||
840         (state->taskStatusTable[queryParam->taskId] == CM_INVALID_INDEX))
841     {
842         eStatus = MOS_STATUS_INVALID_PARAMETER;
843         CM_ASSERTMESSAGE("Invalid Task ID'%d'.", queryParam->taskId);
844         goto finish;
845     }
846 
847     renderHal = state->renderHal;
848     stateHeap = renderHal->pStateHeap;
849     syncOffset = state->pfnGetTaskSyncLocation(state, queryParam->taskId);
850     piSyncStart = (int64_t*)(state->renderTimeStampResource.data + syncOffset);
851     piSyncEnd = piSyncStart + 1;
852     queryParam->taskDurationNs = CM_INVALID_INDEX;
853 
854     if (*piSyncStart == CM_INVALID_INDEX)
855     {
856         queryParam->status = CM_TASK_QUEUED;
857     }
858     else if (*piSyncEnd == CM_INVALID_INDEX)
859     {
860         queryParam->status = CM_TASK_IN_PROGRESS;
861     }
862     else
863     {
864         queryParam->status = CM_TASK_FINISHED;
865 
866         hwStartNs = HalCm_ConvertTicksToNanoSeconds(state, *piSyncStart);
867         hwEndNs = HalCm_ConvertTicksToNanoSeconds(state, *piSyncEnd);
868 
869         ticks = *piSyncEnd - *piSyncStart;
870 
871         queryParam->taskDurationTicks = ticks;
872         queryParam->taskHWStartTimeStampInTicks = *piSyncStart;
873         queryParam->taskHWEndTimeStampInTicks   = *piSyncEnd;
874 
875         // Convert ticks to Nanoseconds
876         queryParam->taskDurationNs = HalCm_ConvertTicksToNanoSeconds(state, ticks);
877 
878         queryParam->taskGlobalSubmitTimeCpu = state->taskTimeStamp->submitTimeInCpu[queryParam->taskId];
879         CM_CHK_MOSSTATUS_GOTOFINISH(state->pfnConvertToQPCTime(state->taskTimeStamp->submitTimeInGpu[queryParam->taskId], &queryParam->taskSubmitTimeGpu));
880         CM_CHK_MOSSTATUS_GOTOFINISH(state->pfnConvertToQPCTime(hwStartNs, &queryParam->taskHWStartTimeStamp));
881         CM_CHK_MOSSTATUS_GOTOFINISH(state->pfnConvertToQPCTime(hwEndNs, &queryParam->taskHWEndTimeStamp));
882 
883         state->taskStatusTable[queryParam->taskId] = CM_INVALID_INDEX;
884     }
885 
886 finish:
887     return eStatus;
888 }
889 
HalCm_WriteGPUStatusTagToCMTSResource_Linux(PCM_HAL_STATE state,PMOS_COMMAND_BUFFER cmdBuffer,int32_t taskID,bool isVebox)890 MOS_STATUS HalCm_WriteGPUStatusTagToCMTSResource_Linux(
891     PCM_HAL_STATE             state,
892     PMOS_COMMAND_BUFFER       cmdBuffer,
893     int32_t                   taskID,
894     bool                      isVebox)
895 {
896     UNUSED(state);
897     UNUSED(cmdBuffer);
898     UNUSED(taskID);
899     UNUSED(isVebox);
900     return MOS_STATUS_SUCCESS;
901 }
902 
903 //*-----------------------------------------------------------------------------
904 //| Purpose:    Lock the resource and return
905 //| Returns:    Result of the operation.
906 //*-----------------------------------------------------------------------------
HalCm_Lock2DResource(PCM_HAL_STATE state,PCM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM param)907 MOS_STATUS HalCm_Lock2DResource(
908     PCM_HAL_STATE               state,                                         // [in]  Pointer to CM State
909     PCM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM     param)                                         // [in]  Pointer to 2D Param
910 {
911     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
912     MOS_LOCK_PARAMS             lockFlags;
913     RENDERHAL_GET_SURFACE_INFO  info;
914 
915     MOS_SURFACE                 surface;
916     PMOS_INTERFACE              osInterface = nullptr;
917 
918     if ((param->lockFlag != CM_HAL_LOCKFLAG_READONLY) && (param->lockFlag != CM_HAL_LOCKFLAG_WRITEONLY) )
919     {
920         CM_ASSERTMESSAGE("Invalid lock flag!");
921         eStatus = MOS_STATUS_UNKNOWN;
922         goto finish;
923     }
924 
925     MOS_ZeroMemory(&surface, sizeof(surface));
926     surface.Format = Format_Invalid;
927     osInterface   = state->osInterface;
928 
929     if(param->data == nullptr)
930     {   // CMRT@UMD
931         PCM_HAL_SURFACE2D_ENTRY    entry;
932 
933         // Get the 2D Resource Entry
934         entry = &state->umdSurf2DTable[param->handle];
935 
936         // Get resource information
937         surface.OsResource = entry->osResource;
938         MOS_ZeroMemory(&info, sizeof(RENDERHAL_GET_SURFACE_INFO));
939 
940         CM_CHK_MOSSTATUS_GOTOFINISH(RenderHal_GetSurfaceInfo(
941                   osInterface,
942                   &info,
943                   &surface));
944 
945         param->pitch = surface.dwPitch;
946         param->format = surface.Format;
947         param->YSurfaceOffset = surface.YPlaneOffset;
948         param->USurfaceOffset = surface.UPlaneOffset;
949         param->VSurfaceOffset = surface.VPlaneOffset;
950 
951         // Lock the resource
952         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
953 
954         if (param->lockFlag == CM_HAL_LOCKFLAG_READONLY)
955         {
956             lockFlags.ReadOnly = true;
957         }
958         else
959         {
960             lockFlags.WriteOnly = true;
961         }
962 
963         lockFlags.ForceCached = true;
964 
965         param->data = osInterface->pfnLockResource(
966                         osInterface,
967                         &entry->osResource,
968                         &lockFlags);
969 
970     }
971     else
972     {
973         CM_ASSERTMESSAGE("Error: Failed to lock surface 2d resource.");
974         eStatus = MOS_STATUS_UNKNOWN;
975     }
976     CM_CHK_NULL_GOTOFINISH_MOSERROR(param->data);
977 
978 finish:
979     return eStatus;
980 }
981 
982 //*-----------------------------------------------------------------------------
983 //| Purpose:    Unlock the resource and return
984 //| Returns:    Result of the operation.
985 //*-----------------------------------------------------------------------------
HalCm_Unlock2DResource(PCM_HAL_STATE state,PCM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM param)986 MOS_STATUS HalCm_Unlock2DResource(
987     PCM_HAL_STATE                           state,                                         // [in]  Pointer to CM State
988     PCM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM     param)                                         // [in]  Pointer to 2D Param
989 {
990     MOS_STATUS              eStatus        = MOS_STATUS_SUCCESS;
991     PMOS_INTERFACE          osInterface    = state->osInterface;
992 
993     if(param->data == nullptr)
994     {
995         PCM_HAL_SURFACE2D_ENTRY     entry;
996 
997         // Get the 2D Resource Entry
998         entry = &state->umdSurf2DTable[param->handle];
999 
1000         // UnLock the resource
1001         CM_CHK_HRESULT_GOTOFINISH_MOSERROR(osInterface->pfnUnlockResource(osInterface, &(entry->osResource)));
1002     }
1003     else
1004     {
1005         CM_ASSERTMESSAGE("Error: Failed to unlock surface 2d resource.");
1006         eStatus = MOS_STATUS_UNKNOWN;
1007     }
1008 
1009 finish:
1010     return eStatus;
1011 }
1012 
1013 //*-----------------------------------------------------------------------------
1014 //| Purpose: Get the GfxMap Filter based on the texture filter type
1015 //| Returns: Result
1016 //*-----------------------------------------------------------------------------
HalCm_GetGfxMapFilter(uint32_t filterMode,MHW_GFX3DSTATE_MAPFILTER * gfxFilter)1017 MOS_STATUS HalCm_GetGfxMapFilter(
1018     uint32_t                     filterMode,
1019     MHW_GFX3DSTATE_MAPFILTER     *gfxFilter)
1020 {
1021     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1022 
1023     switch(filterMode)
1024     {
1025     case CM_TEXTURE_FILTER_TYPE_LINEAR:
1026         *gfxFilter = MHW_GFX3DSTATE_MAPFILTER_LINEAR;
1027         break;
1028     case CM_TEXTURE_FILTER_TYPE_POINT:
1029         *gfxFilter = MHW_GFX3DSTATE_MAPFILTER_NEAREST;
1030         break;
1031     case CM_TEXTURE_FILTER_TYPE_ANISOTROPIC:
1032         *gfxFilter = MHW_GFX3DSTATE_MAPFILTER_ANISOTROPIC;
1033         break;
1034 
1035     default:
1036         eStatus = MOS_STATUS_INVALID_PARAMETER;
1037         CM_ASSERTMESSAGE("Filter '%d' not supported", filterMode);
1038         goto finish;
1039     }
1040 
1041 finish:
1042     return eStatus;
1043 }
1044 
1045 //*-----------------------------------------------------------------------------
1046 //| Purpose: Get the Gfx Texture Address based on the texture coordinate type
1047 //| Returns: Result
1048 //*-----------------------------------------------------------------------------
HalCm_GetGfxTextAddress(uint32_t addressMode,MHW_GFX3DSTATE_TEXCOORDMODE * gfxAddress)1049 MOS_STATUS HalCm_GetGfxTextAddress(
1050     uint32_t                     addressMode,
1051     MHW_GFX3DSTATE_TEXCOORDMODE  *gfxAddress)
1052 {
1053     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1054 
1055     switch(addressMode)
1056     {
1057 
1058     case CM_TEXTURE_ADDRESS_WRAP:
1059         *gfxAddress = MHW_GFX3DSTATE_TEXCOORDMODE_WRAP;
1060         break;
1061     case CM_TEXTURE_ADDRESS_MIRROR:
1062         *gfxAddress = MHW_GFX3DSTATE_TEXCOORDMODE_MIRROR;
1063         break;
1064     case CM_TEXTURE_ADDRESS_CLAMP:
1065         *gfxAddress = MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP;
1066         break;
1067     case CM_TEXTURE_ADDRESS_BORDER:
1068         *gfxAddress = MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP_BORDER;
1069         break;
1070 
1071     default:
1072         eStatus = MOS_STATUS_INVALID_PARAMETER;
1073         CM_ASSERTMESSAGE("Address '%d' not supported", addressMode);
1074         goto finish;
1075     }
1076 
1077 finish:
1078     return eStatus;
1079 }
1080 
1081 //*-----------------------------------------------------------------------------
1082 //| Purpose:    If WA required to set SLM in L3
1083 //| Returns:    Display corruption observed when running MDF workload.
1084 //|             This issue is related to SLM setting in L3.
1085 //|             To resolve this problem, we need to disable SLM after
1086 //|             command submission.
1087 //*-----------------------------------------------------------------------------
HalCm_IsWaSLMinL3Cache_Linux()1088 bool HalCm_IsWaSLMinL3Cache_Linux()
1089 {
1090     bool flag;
1091 #if ANDROID
1092     flag = false;
1093 #else
1094     flag = true;
1095 #endif
1096     return flag;
1097 }
1098 
1099 //*-----------------------------------------------------------------------------
1100 //| Purpose:    Enable GPU frequency Turbo boost on Linux
1101 //| Returns:    MOS_STATUS_SUCCESS.
1102 //*-----------------------------------------------------------------------------
HalCm_EnableTurboBoost_Linux(PCM_HAL_STATE state)1103 MOS_STATUS HalCm_EnableTurboBoost_Linux(
1104     PCM_HAL_STATE             state)
1105 {
1106 #ifndef ANDROID
1107     mos_enable_turbo_boost(state->osInterface->pOsContext->bufmgr);
1108 #endif
1109     //if drmIoctl fail, we will stay in normal mode.
1110     return MOS_STATUS_SUCCESS;
1111 }
1112 
1113 //!
1114 //! \brief    Updates tracker resource used in state heap management
1115 //! \param    [in] state
1116 //!           CM HAL State
1117 //! \param    [in,out] cmdBuffer
1118 //!           Command buffer containing the workload
1119 //! \param    [in] tag
1120 //|           Tag to write to tracker resource
1121 //! \return   MOS_STATUS
1122 //!           MOS_STATUS_SUCCESS if success, else fail reason
1123 //!
HalCm_UpdateTrackerResource_Linux(PCM_HAL_STATE state,PMOS_COMMAND_BUFFER cmdBuffer,uint32_t tag)1124 MOS_STATUS HalCm_UpdateTrackerResource_Linux(
1125     PCM_HAL_STATE       state,
1126     PMOS_COMMAND_BUFFER cmdBuffer,
1127     uint32_t            tag)
1128 {
1129     MHW_MI_STORE_DATA_PARAMS storeDataParams;
1130     MOS_GPU_CONTEXT          gpuContext = MOS_GPU_CONTEXT_INVALID_HANDLE;
1131     MOS_STATUS               eStatus = MOS_STATUS_SUCCESS;
1132 
1133     MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
1134     gpuContext = state->renderHal->pOsInterface->CurrentGpuContextOrdinal;
1135     if (gpuContext == MOS_GPU_CONTEXT_VEBOX)
1136     {
1137         MOS_RESOURCE osResource = state->renderHal->veBoxTrackerRes.osResource;
1138         storeDataParams.pOsResource = &osResource;
1139     }
1140     else
1141     {
1142         state->renderHal->trackerProducer.GetLatestTrackerResource(state->renderHal->currentTrackerIndex,
1143                             &storeDataParams.pOsResource,
1144                             &storeDataParams.dwResourceOffset);
1145     }
1146 
1147     storeDataParams.dwValue = tag;
1148     eStatus = state->renderHal->pMhwMiInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams);
1149     return eStatus;
1150 }
1151 
HalCm_RegisterStream(CM_HAL_STATE * state)1152 uint32_t HalCm_RegisterStream(CM_HAL_STATE *state)
1153 {
1154     return state->osInterface->streamIndex;
1155 }
1156 
HalCm_OsInitInterface(PCM_HAL_STATE cmState)1157 void HalCm_OsInitInterface(
1158     PCM_HAL_STATE           cmState)          // [out]  pointer to CM State
1159 {
1160     CM_ASSERT(cmState);
1161 
1162     cmState->pfnGetSurface2DPitchAndSize            = HalCm_GetSurface2DPitchAndSize;
1163     cmState->pfnGetGPUCurrentFrequency              = HalCm_GetGPUCurrentFrequency;
1164     cmState->pfnRegisterUMDNotifyEventHandle        = HalCm_RegisterUMDNotifyEventHandle;
1165     cmState->pfnAllocateBuffer                      = HalCm_AllocateBuffer_Linux;
1166     cmState->pfnAllocateSurface2DUP                 = HalCm_AllocateSurface2DUP_Linux;
1167     cmState->pfnGetGpuTime                          = HalCm_GetGpuTime;
1168     cmState->pfnGetPlatformInfo                     = HalCm_GetPlatformInfo_Linux;
1169     cmState->pfnGetGTSystemInfo                     = HalCm_GetGTSystemInfo_Linux;
1170     cmState->pfnReferenceCommandBuffer              = HalCm_ReferenceCommandBuf_Linux;
1171     cmState->pfnSetCommandBufferResource            = HalCm_SetCommandBufResource_Linux;
1172     cmState->pfnQueryTask                           = HalCm_QueryTask_Linux;
1173     cmState->pfnIsWASLMinL3Cache                    = HalCm_IsWaSLMinL3Cache_Linux;
1174     cmState->pfnEnableTurboBoost                    = HalCm_EnableTurboBoost_Linux;
1175     cmState->pfnUpdateTrackerResource               = HalCm_UpdateTrackerResource_Linux;
1176     cmState->pfnRegisterStream                      = HalCm_RegisterStream;
1177 
1178     cmState->pfnGetGfxMapFilter                     = HalCm_GetGfxMapFilter;
1179     cmState->pfnGetGfxTextAddress                   = HalCm_GetGfxTextAddress;
1180     cmState->pfnDecompressSurface                   = HalCm_DecompressSurface;
1181     cmState->pfnSetOsResourceFromDdi                = HalCm_SetOsResourceFromDdi;
1182     cmState->pfnGetSipBinary                        = HalCm_GetSipBinary;
1183     cmState->pfnSurfaceSync                         = HalCm_SurfaceSync;
1184     cmState->pfnSyncKernel                          = HalCm_SyncKernel;
1185 
1186     HalCm_GetLibDrmVMapFnt(cmState);
1187     cmState->syncOnResource                         = false;
1188     return;
1189 }
1190 
1191 //*-------------------------------------------------------------------------------------
1192 //| Purpose:    Add PipeControl with a Conditional Time Stamp (valid/invalid time stamp)
1193 //| Returns:    On Success, right before Pipe Control commands, insert commands to write
1194 //|             time stamp to Sync Location. When the condition same as following
1195 //|             "conditional buffer end" command is assert, the time stamp is a valid value,
1196 //|             otherwise an invalid time stamp is used to write Sync Location.
1197 //*-------------------------------------------------------------------------------------
1198 
HalCm_OsAddArtifactConditionalPipeControl(PCM_HAL_MI_REG_OFFSETS offsets,PCM_HAL_STATE state,PMOS_COMMAND_BUFFER cmdBuffer,int32_t syncOffset,PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS conditionalParams,uint32_t trackerTag)1199 MOS_STATUS HalCm_OsAddArtifactConditionalPipeControl(
1200     PCM_HAL_MI_REG_OFFSETS offsets,
1201     PCM_HAL_STATE state,
1202     PMOS_COMMAND_BUFFER cmdBuffer, //commmand buffer
1203     int32_t syncOffset,   //offset to syncation of time stamp
1204     PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS conditionalParams, //comparing Params
1205     uint32_t trackerTag)
1206 {
1207     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1208     MHW_MI_LOAD_REGISTER_REG_PARAMS     loadRegRegParams;
1209     MHW_MI_LOAD_REGISTER_IMM_PARAMS     loadRegImmParams;
1210     MHW_MI_LOAD_REGISTER_MEM_PARAMS     loadRegMemParams;
1211 
1212     MHW_MI_STORE_REGISTER_MEM_PARAMS    storeRegParams;
1213     MHW_MI_STORE_DATA_PARAMS            storeDataParams;
1214     MHW_MI_FLUSH_DW_PARAMS              flushDwParams;
1215     MHW_MI_MATH_PARAMS                  mathParams;
1216     MHW_MI_ALU_PARAMS                   aluParams[20];
1217     MHW_MI_STORE_REGISTER_MEM_PARAMS    storeRegMemParams;
1218     MHW_PIPE_CONTROL_PARAMS             pipeCtrlParams;
1219 
1220     PMHW_MI_INTERFACE  mhwMiInterface = state->renderHal->pMhwMiInterface;
1221 
1222     MOS_ZeroMemory(&loadRegRegParams, sizeof(loadRegRegParams));
1223     loadRegRegParams.dwSrcRegister = offsets->timeStampOffset;         //read time stamp
1224     loadRegRegParams.dwDstRegister = offsets->gprOffset + 0;
1225     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterRegCmd(cmdBuffer, &loadRegRegParams));
1226     loadRegRegParams.dwSrcRegister = offsets->timeStampOffset + 4;
1227     loadRegRegParams.dwDstRegister = offsets->gprOffset + 4;
1228     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterRegCmd(cmdBuffer, &loadRegRegParams));     //R0: time stamp
1229 
1230     MOS_ZeroMemory(&mathParams, sizeof(mathParams));
1231     MOS_ZeroMemory(&aluParams, sizeof(aluParams));
1232 
1233     aluParams[0].AluOpcode = MHW_MI_ALU_AND;
1234 
1235     // store      reg1, CF
1236     aluParams[1].AluOpcode = MHW_MI_ALU_STORE;
1237     aluParams[1].Operand1 = MHW_MI_ALU_GPREG1;
1238     aluParams[1].Operand2 = MHW_MI_ALU_CF;
1239     // store      reg2, CF
1240     aluParams[2].AluOpcode = MHW_MI_ALU_STORE;
1241     aluParams[2].Operand1 = MHW_MI_ALU_GPREG2;
1242     aluParams[2].Operand2 = MHW_MI_ALU_CF;
1243     // store      reg3, CF
1244     aluParams[2].AluOpcode = MHW_MI_ALU_STORE;
1245     aluParams[2].Operand1 = MHW_MI_ALU_GPREG3;
1246     aluParams[2].Operand2 = MHW_MI_ALU_CF;                                                                      //clear R1 -- R3
1247 
1248     mathParams.pAluPayload = aluParams;
1249     mathParams.dwNumAluParams = 3;
1250     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiMathCmd(cmdBuffer, &mathParams));                     //MI cmd to clear R1 - R3
1251 
1252     MOS_ZeroMemory(&loadRegMemParams, sizeof(loadRegMemParams));
1253     loadRegMemParams.presStoreBuffer = conditionalParams->presSemaphoreBuffer;
1254     loadRegMemParams.dwOffset = conditionalParams->dwOffset;
1255     loadRegMemParams.dwRegister = offsets->gprOffset + 8 * 1;
1256     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &loadRegMemParams));    //R1: compared value 32bits, in coditional surface
1257                                                                                                   // Load current tracker tag from resource to R8
1258     MOS_ZeroMemory(&loadRegMemParams, sizeof(loadRegMemParams));
1259     state->renderHal->trackerProducer.GetLatestTrackerResource(state->renderHal->currentTrackerIndex,
1260                                 &loadRegMemParams.presStoreBuffer,
1261                                 &loadRegMemParams.dwOffset);
1262     loadRegMemParams.dwRegister = offsets->gprOffset+ 8 * 8;
1263     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &loadRegMemParams));  // R8: current tracker tag
1264 
1265                                                                                                 // Load new tag passed to this function to R9
1266     MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
1267     loadRegImmParams.dwData = trackerTag;
1268     loadRegImmParams.dwRegister = offsets->gprOffset+ 8 * 9;
1269     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &loadRegImmParams));  // R9: new tracker tag
1270                                                                                                 //
1271 
1272     if (!conditionalParams->bDisableCompareMask)
1273     {
1274         loadRegMemParams.presStoreBuffer = conditionalParams->presSemaphoreBuffer;
1275         loadRegMemParams.dwOffset = conditionalParams->dwOffset + 4;
1276         loadRegMemParams.dwRegister = offsets->gprOffset + 8 * 2;
1277         CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &loadRegMemParams)); //r1, r2: compared value and its mask
1278         //load1 reg1, srca
1279         aluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
1280         aluParams[0].Operand1 = MHW_MI_ALU_SRCA;
1281         aluParams[0].Operand2 = MHW_MI_ALU_GPREG1;
1282         //load reg2, srcb
1283         aluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
1284         aluParams[1].Operand1 = MHW_MI_ALU_SRCB;
1285         aluParams[1].Operand2 = MHW_MI_ALU_GPREG2;
1286         //add
1287         aluParams[2].AluOpcode = MHW_MI_ALU_AND;
1288         //store reg1, accu
1289         aluParams[3].AluOpcode = MHW_MI_ALU_STORE;
1290         aluParams[3].Operand1 = MHW_MI_ALU_GPREG1;
1291         aluParams[3].Operand2 = MHW_MI_ALU_ACCU;                                                                     //REG14 = TS + 1
1292 
1293         mathParams.pAluPayload = aluParams;
1294         mathParams.dwNumAluParams = 4;
1295         CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiMathCmd(cmdBuffer, &mathParams));                     //R1 & R2 --> R1: compared value, to be used
1296     }
1297 
1298     MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
1299     loadRegImmParams.dwData = conditionalParams->dwValue;
1300     loadRegImmParams.dwRegister = offsets->gprOffset + 8 * 2;
1301     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &loadRegImmParams));    //R2: user value 32bits
1302 
1303     MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
1304     loadRegImmParams.dwData = 1;
1305     loadRegImmParams.dwRegister = offsets->gprOffset + 8 * 3;
1306     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &loadRegImmParams));    //R3 = 1
1307 
1308     //load1 reg3, srca
1309     aluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
1310     aluParams[0].Operand1 = MHW_MI_ALU_SRCA;
1311     aluParams[0].Operand2 = MHW_MI_ALU_GPREG3;
1312     //load reg0, srcb
1313     aluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
1314     aluParams[1].Operand1 = MHW_MI_ALU_SRCB;
1315     aluParams[1].Operand2 = MHW_MI_ALU_GPREG0;
1316     //add
1317     aluParams[2].AluOpcode = MHW_MI_ALU_ADD;
1318     //store reg14, accu
1319     aluParams[3].AluOpcode = MHW_MI_ALU_STORE;
1320     aluParams[3].Operand1 = MHW_MI_ALU_GPREG14;
1321     aluParams[3].Operand2 = MHW_MI_ALU_ACCU;                                                                     //REG14 = TS + 1
1322 
1323     // load     srcB, reg1
1324     aluParams[4].AluOpcode = MHW_MI_ALU_LOAD;
1325     aluParams[4].Operand1 = MHW_MI_ALU_SRCB;
1326     aluParams[4].Operand2 = MHW_MI_ALU_GPREG1;                                               //load compared val
1327     // load     srcA, reg2
1328     aluParams[5].AluOpcode = MHW_MI_ALU_LOAD;
1329     aluParams[5].Operand1 = MHW_MI_ALU_SRCA;
1330     aluParams[5].Operand2 = MHW_MI_ALU_GPREG2;                                              //load user val
1331     // sub      srcA, srcB
1332     aluParams[6].AluOpcode = MHW_MI_ALU_SUB;                                                //if (compared > user) 1 ==> CF otherwise 0 ==> CF
1333     // store      reg4, CF
1334     aluParams[7].AluOpcode = MHW_MI_ALU_STOREINV;
1335     aluParams[7].Operand1 = MHW_MI_ALU_GPREG4;
1336     aluParams[7].Operand2 = MHW_MI_ALU_CF;                                                 //!CF ==> R4, mask
1337     //load      reg4, srcA
1338     aluParams[8].AluOpcode = MHW_MI_ALU_LOAD;
1339     aluParams[8].Operand1 = MHW_MI_ALU_SRCA;
1340     aluParams[8].Operand2 = MHW_MI_ALU_GPREG4;
1341     //load reg14, SRCB
1342     aluParams[9].AluOpcode = MHW_MI_ALU_LOAD;
1343     aluParams[9].Operand1 = MHW_MI_ALU_SRCB;
1344     aluParams[9].Operand2 = MHW_MI_ALU_GPREG14;
1345     //and
1346     aluParams[10].AluOpcode = MHW_MI_ALU_AND;                                             //0 or TS+1 (!CF & TS)
1347 
1348     //store reg6, accu
1349     aluParams[11].AluOpcode = MHW_MI_ALU_STORE;                                       //R6 = (TS+1) (to terminate) or 0 (to continue)
1350     aluParams[11].Operand1 = MHW_MI_ALU_GPREG6;
1351     aluParams[11].Operand2 = MHW_MI_ALU_ACCU;
1352 
1353     //invalud time stamp is all '1's for MDF
1354     //load reg6, SRCA
1355     aluParams[12].AluOpcode = MHW_MI_ALU_LOAD;
1356     aluParams[12].Operand1 = MHW_MI_ALU_SRCA;
1357     aluParams[12].Operand2 = MHW_MI_ALU_GPREG6;
1358     //load1 SRCB
1359     aluParams[13].AluOpcode = MHW_MI_ALU_LOAD;
1360     aluParams[13].Operand1 = MHW_MI_ALU_SRCB;
1361     aluParams[13].Operand2 = MHW_MI_ALU_GPREG3;
1362     //sub
1363     aluParams[14].AluOpcode = MHW_MI_ALU_SUB;                                             //-1 or TS (!CF & TS)
1364     //store reg7, accu
1365     aluParams[15].AluOpcode = MHW_MI_ALU_STORE;                                       //R7 = (TS) (to terminate) or all '1'  ( -1 to continue)
1366     aluParams[15].Operand1 = MHW_MI_ALU_GPREG7;
1367     aluParams[15].Operand2 = MHW_MI_ALU_ACCU;
1368 
1369     mathParams.pAluPayload = aluParams;
1370     mathParams.dwNumAluParams = 16;
1371     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiMathCmd(cmdBuffer, &mathParams));            //set artifact time stamp (-1 or TS) per condition in GPR R7
1372 
1373     // Add R3 (has value 1) to R4 (~CF) and store result in R10
1374     aluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
1375     aluParams[0].Operand1 = MHW_MI_ALU_SRCA;
1376     aluParams[0].Operand2 = MHW_MI_ALU_GPREG3;
1377 
1378     aluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
1379     aluParams[1].Operand1 = MHW_MI_ALU_SRCB;
1380     aluParams[1].Operand2 = MHW_MI_ALU_GPREG4;
1381 
1382     aluParams[2].AluOpcode = MHW_MI_ALU_ADD;
1383 
1384     aluParams[3].AluOpcode = MHW_MI_ALU_STORE;
1385     aluParams[3].Operand1 = MHW_MI_ALU_GPREG10;
1386     aluParams[3].Operand2 = MHW_MI_ALU_ACCU;
1387 
1388     // AND R8 (current tracker tag) with R10 (~CF + 1) and store in R11
1389     aluParams[4].AluOpcode = MHW_MI_ALU_LOAD;
1390     aluParams[4].Operand1 = MHW_MI_ALU_SRCA;
1391     aluParams[4].Operand2 = MHW_MI_ALU_GPREG8;
1392 
1393     aluParams[5].AluOpcode = MHW_MI_ALU_LOAD;
1394     aluParams[5].Operand1 = MHW_MI_ALU_SRCB;
1395     aluParams[5].Operand2 = MHW_MI_ALU_GPREG10;
1396 
1397     aluParams[6].AluOpcode = MHW_MI_ALU_AND;
1398 
1399     aluParams[7].AluOpcode = MHW_MI_ALU_STORE;
1400     aluParams[7].Operand1 = MHW_MI_ALU_GPREG11;
1401     aluParams[7].Operand2 = MHW_MI_ALU_ACCU;
1402 
1403     // Store inverse of R10 (-1 --> continue, 0 --> terminate) to R12
1404     aluParams[8].AluOpcode = MHW_MI_ALU_STOREINV;
1405     aluParams[8].Operand1 = MHW_MI_ALU_GPREG12;
1406     aluParams[8].Operand2 = MHW_MI_ALU_GPREG10;
1407 
1408     // AND R9 (new tracker tag) and R12 and store in R13
1409     aluParams[9].AluOpcode = MHW_MI_ALU_LOAD;
1410     aluParams[9].Operand1 = MHW_MI_ALU_SRCA;
1411     aluParams[9].Operand2 = MHW_MI_ALU_GPREG9;
1412 
1413     aluParams[10].AluOpcode = MHW_MI_ALU_LOAD;
1414     aluParams[10].Operand1 = MHW_MI_ALU_SRCB;
1415     aluParams[10].Operand2 = MHW_MI_ALU_GPREG12;
1416 
1417     aluParams[11].AluOpcode = MHW_MI_ALU_AND;
1418 
1419     aluParams[12].AluOpcode = MHW_MI_ALU_STORE;
1420     aluParams[12].Operand1 = MHW_MI_ALU_GPREG13;
1421     aluParams[12].Operand2 = MHW_MI_ALU_ACCU;
1422 
1423     // ADD R11 and R13 and store in R15
1424     aluParams[13].AluOpcode = MHW_MI_ALU_LOAD;
1425     aluParams[13].Operand1 = MHW_MI_ALU_SRCA;
1426     aluParams[13].Operand2 = MHW_MI_ALU_GPREG11;
1427 
1428     aluParams[14].AluOpcode = MHW_MI_ALU_LOAD;
1429     aluParams[14].Operand1 = MHW_MI_ALU_SRCB;
1430     aluParams[14].Operand2 = MHW_MI_ALU_GPREG13;
1431 
1432     aluParams[15].AluOpcode = MHW_MI_ALU_ADD;
1433 
1434     aluParams[16].AluOpcode = MHW_MI_ALU_STORE;
1435     aluParams[16].Operand1 = MHW_MI_ALU_GPREG15;
1436     aluParams[16].Operand2 = MHW_MI_ALU_ACCU;
1437 
1438     mathParams.pAluPayload = aluParams;
1439     mathParams.dwNumAluParams = 17;
1440     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiMathCmd(cmdBuffer, &mathParams));
1441 
1442     // Store R15 to trackerResource
1443     MOS_ZeroMemory(&storeRegMemParams, sizeof(storeRegMemParams));
1444     state->renderHal->trackerProducer.GetLatestTrackerResource(state->renderHal->currentTrackerIndex,
1445                                             &storeRegMemParams.presStoreBuffer,
1446                                             &storeRegMemParams.dwOffset);
1447     storeRegMemParams.dwRegister = offsets->gprOffset+ 8 * 15;
1448     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegMemParams));
1449 
1450     //store R6 to synclocation
1451     MOS_ZeroMemory(&storeRegMemParams, sizeof(storeRegMemParams));
1452     storeRegMemParams.presStoreBuffer = &state->renderTimeStampResource.osResource;
1453     storeRegMemParams.dwOffset = syncOffset + sizeof(uint64_t);
1454     storeRegMemParams.dwRegister = offsets->gprOffset + 8 * 7;
1455     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegMemParams));
1456     storeRegMemParams.presStoreBuffer = &state->renderTimeStampResource.osResource;
1457     storeRegMemParams.dwOffset = syncOffset + sizeof(uint64_t) + 4;
1458     storeRegMemParams.dwRegister = offsets->gprOffset + 4 + 8 * 7 ;
1459     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegMemParams));
1460 
1461     // Insert a pipe control for synchronization
1462     pipeCtrlParams = g_cRenderHal_InitPipeControlParams;
1463     pipeCtrlParams.dwPostSyncOp = MHW_FLUSH_NOWRITE;
1464     pipeCtrlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
1465     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddPipeControl(cmdBuffer, nullptr, &pipeCtrlParams));
1466 
1467     pipeCtrlParams.dwFlushMode = MHW_FLUSH_READ_CACHE;
1468     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddPipeControl(cmdBuffer, nullptr, &pipeCtrlParams));
1469 
1470 finish:
1471     return eStatus;
1472 };
1473 
HalCm_GetNumCmdBuffers(PMOS_INTERFACE osInterface,uint32_t maxTaskNumber)1474 uint32_t HalCm_GetNumCmdBuffers(PMOS_INTERFACE osInterface, uint32_t maxTaskNumber)
1475 {
1476     UNUSED(maxTaskNumber);
1477     return 0;
1478 }
1479 
HalCm_GetSipBinary(PCM_HAL_STATE state)1480 MOS_STATUS HalCm_GetSipBinary(PCM_HAL_STATE state)
1481 {
1482     UNUSED(state);
1483     // Function not implemented on Linux, just return success for sanity check
1484     return MOS_STATUS_SUCCESS;
1485 }
1486 
HalCm_SetupSipSurfaceState(PCM_HAL_STATE state,PCM_HAL_INDEX_PARAM indexParam,int32_t bindingTable)1487 MOS_STATUS HalCm_SetupSipSurfaceState(
1488     PCM_HAL_STATE               state,
1489     PCM_HAL_INDEX_PARAM         indexParam,
1490     int32_t                     bindingTable)
1491 {
1492     UNUSED(state);
1493     UNUSED(indexParam);
1494     UNUSED(bindingTable);
1495     // Function not implemented on Linux, just return success for sanity check
1496     return MOS_STATUS_SUCCESS;
1497 }
1498 
1499 //!
1500 //! \brief    Prepare virtual engine hint parametere
1501 //! \details  Prepare virtual engine hint parameter for CCS node
1502 //! \param    PCM_HAL_STATE state
1503 //!           [in] Pointer to CM_HAL_STATE Structure
1504 //! \param    bool bScalable
1505 //!           [in] is scalable pipe or single pipe
1506 //! \param    PMOS_VIRTUALENGINE_HINT_PARAMS pVeHintParam
1507 //!           [out] Pointer to prepared VE hint parameter struct
1508 //! \return   MOS_STATUS
1509 //!
HalCm_PrepareVEHintParam(PCM_HAL_STATE state,bool bScalable,PMOS_VIRTUALENGINE_HINT_PARAMS pVeHintParam)1510 MOS_STATUS HalCm_PrepareVEHintParam(
1511     PCM_HAL_STATE                  state,
1512     bool                           bScalable,
1513     PMOS_VIRTUALENGINE_HINT_PARAMS pVeHintParam)
1514 {
1515     return MOS_STATUS_UNIMPLEMENTED;
1516 }
1517 
1518 
1519 //!
1520 //! \brief    Decompress the surface
1521 //! \details  Decompress the media compressed surface
1522 //! \param    PCM_HAL_STATE state
1523 //!           [in] Pointer to CM_HAL_STATE Structure
1524 //! \param    PCM_HAL_KERNEL_ARG_PARAM argParam
1525 //!           [in]Pointer to HAL cm kernel argrument parameter
1526 //! \param    uint32_t threadIndex
1527 //!           [in] is used to get index of surface array
1528 //! \return   MOS_STATUS
1529 //!
HalCm_DecompressSurface(PCM_HAL_STATE state,PCM_HAL_KERNEL_ARG_PARAM argParam,uint32_t threadIndex)1530 MOS_STATUS HalCm_DecompressSurface(
1531     PCM_HAL_STATE              state,
1532     PCM_HAL_KERNEL_ARG_PARAM   argParam,
1533     uint32_t                   threadIndex)
1534 {
1535     MOS_STATUS                 eStatus = MOS_STATUS_SUCCESS;
1536     uint32_t                   handle = 0;
1537     uint8_t                    *src = nullptr;
1538     PCM_HAL_SURFACE2D_ENTRY    pEntry = nullptr;
1539     PMOS_RESOURCE              pOsResource = nullptr;
1540     PMOS_INTERFACE             pOsInterface = nullptr;
1541     GMM_RESOURCE_FLAG          GmmFlags = { 0 };
1542 
1543     //Get the index of  surface array handle from kernel data
1544     CM_ASSERT(argParam->unitSize == sizeof(handle));
1545     src = argParam->firstValue + (threadIndex * argParam->unitSize);
1546     handle = *((uint32_t *)src) & CM_SURFACE_MASK;
1547     if (handle == CM_NULL_SURFACE)
1548     {
1549         eStatus = MOS_STATUS_SUCCESS;
1550         goto finish;
1551     }
1552 
1553     pEntry = &state->umdSurf2DTable[handle];
1554     pOsResource = &pEntry->osResource;
1555     pOsInterface = state->osInterface;
1556 
1557     if (pOsResource->pGmmResInfo)
1558     {
1559         GmmFlags = pOsResource->pGmmResInfo->GetResFlags();
1560         if (GmmFlags.Gpu.MMC || pOsResource->pGmmResInfo->IsMediaMemoryCompressed(0))
1561         {
1562             MOS_OS_ASSERT(pOsInterface);
1563             pOsInterface->pfnDecompResource(pOsInterface, pOsResource);
1564         }
1565     }
1566 
1567 finish:
1568     return eStatus;
1569 }
1570 
HalCm_SurfaceSync(PCM_HAL_STATE pState,PMOS_SURFACE pSurface,bool bReadSync)1571 MOS_STATUS HalCm_SurfaceSync(
1572     PCM_HAL_STATE                pState,
1573     PMOS_SURFACE                 pSurface,
1574     bool                         bReadSync )
1575 {
1576     UNUSED(pState);
1577     UNUSED(pSurface);
1578     UNUSED(bReadSync);
1579 
1580     return MOS_STATUS_SUCCESS;
1581 }
1582 
1583 //!
1584 //! \brief    initialization os resource from DDI
1585 //! \details  initialization os resource from DDI
1586 //! \param    PMOS_RESOURCE pResource
1587 //!           [in] Pointer to OS Resource
1588 //! \param    PMOS_RESOURCE pOsResource
1589 //!           [out] Pointer to OS Resource
1590 //! \param    UINT MipSlice
1591 //!           [in] Slice info
1592 //! \return   MOS_STATUS
1593 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1594 //!
HalCm_SetOsResourceFromDdi(PMOS_RESOURCE resource,PMOS_RESOURCE osResource,uint32_t mipSlice)1595 MOS_STATUS HalCm_SetOsResourceFromDdi(
1596     PMOS_RESOURCE     resource,
1597     PMOS_RESOURCE     osResource,
1598     uint32_t          mipSlice)
1599 {
1600     UNUSED(resource);
1601     UNUSED(osResource);
1602     UNUSED(mipSlice);
1603 
1604     return MOS_STATUS_SUCCESS;
1605 }
1606