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