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 "i915_drm.h"
30 #include "cm_execution_adv.h"
31 #include "mos_graphicsresource.h"
32 #include "mos_utilities.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   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 = 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(HalCm_SyncOnResource(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         = state->osInterface->pfnFmt_MosToGmm( 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_Linux(PCM_HAL_STATE state,PCM_HAL_SURFACE2D_UP_PARAM param)362 MOS_STATUS HalCm_GetSurface2DPitchAndSize_Linux(
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_Linux(PCM_HAL_STATE state,PCM_HAL_OSSYNC_PARAM syncParam)374 MOS_STATUS HalCm_RegisterUMDNotifyEventHandle_Linux(
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 = I915_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 = osInterface->pfnFmt_MosToGmm(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 #if defined(DRM_IOCTL_I915_GEM_USERPTR)
536            bo =  mos_bo_alloc_userptr(osInterface->pOsContext->bufmgr,
537                                  "CM Buffer UP",
538                                  (void *)(param->data),
539                                  tileformat,
540                                  ROUND_UP_TO(size,MOS_PAGE_SIZE),
541                                  ROUND_UP_TO(size,MOS_PAGE_SIZE),
542 #if defined(ANDROID)
543                                  I915_USERPTR_UNSYNCHRONIZED
544 #else
545                  0
546 #endif
547                  );
548 #else
549            bo =  mos_bo_alloc_vmap(osInterface->pOsContext->bufmgr,
550                                 "CM Buffer UP",
551                                 (void *)(param->data),
552                                 tileformat,
553                                 ROUND_UP_TO(size,MOS_PAGE_SIZE),
554                                 ROUND_UP_TO(size,MOS_PAGE_SIZE),
555 #if defined(ANDROID)
556                                  I915_USERPTR_UNSYNCHRONIZED
557 #else
558                  0
559 #endif
560                  );
561 #endif
562 
563             osResource->bMapped = false;
564             if (bo)
565             {
566                 osResource->Format   = Format_Buffer;
567                 osResource->iWidth   = ROUND_UP_TO(size,MOS_PAGE_SIZE);
568                 osResource->iHeight  = 1;
569                 osResource->iPitch   = ROUND_UP_TO(size,MOS_PAGE_SIZE);
570                 osResource->bo       = bo;
571                 osResource->TileType = LinuxToMosTileType(tileformat);
572                 osResource->pData    = (uint8_t*) bo->virt;
573             }
574             else
575             {
576                 fmt = "BufferUP";
577                 CM_ASSERTMESSAGE("Fail to Alloc BufferUP %7d bytes (%d x %d %s resource)\n",size, size, 1, fmt);
578                 eStatus = MOS_STATUS_UNKNOWN;
579             }
580             osResource->bConvertedFromDDIResource = true;
581         }
582     }
583     else
584     {
585         entry->osResource = *param->mosResource;
586         HalCm_OsResource_Reference(&entry->osResource);
587     }
588 
589     entry->size = param->size;
590     entry->isAllocatedbyCmrtUmd = param->isAllocatedbyCmrtUmd;
591     entry->surfaceStateEntry[0].surfaceStateSize = entry->size;
592     entry->surfaceStateEntry[0].surfaceStateOffset = 0;
593     entry->surfaceStateEntry[0].surfaceStateMOCS = 0;
594     if(param->type == CM_BUFFER_STATELESS)
595     {
596         state->statelessBufferUsed = true;
597 
598         // get GPU virtual address
599         // Fix: pfnGetResourceGfxAddress is not implemented. Need to find solution to
600         // get the GFX address.
601         param->gfxAddress = osInterface->pfnGetResourceGfxAddress(osInterface,
602                                                                   &(entry->osResource));
603         entry->address = reinterpret_cast<void *>(param->gfxAddress);
604     }
605 
606     if (state->advExecutor)
607     {
608         entry->surfStateMgr = state->advExecutor->CreateBufferStateMgr(&entry->osResource);
609         state->advExecutor->SetBufferOrigSize(entry->surfStateMgr, entry->size);
610     }
611 
612 finish:
613     return eStatus;
614 }
615 
616 //*-----------------------------------------------------------------------------
617 //| Purpose:    Allocate Surface2DUP (zero-copy, map system memory to video address space)
618 //| Returns:    Result of the operation.
619 //*-----------------------------------------------------------------------------
HalCm_AllocateSurface2DUP_Linux(PCM_HAL_STATE state,PCM_HAL_SURFACE2D_UP_PARAM param)620 MOS_STATUS HalCm_AllocateSurface2DUP_Linux(
621     PCM_HAL_STATE state,               // [in]  Pointer to CM State
622     PCM_HAL_SURFACE2D_UP_PARAM param)  // [in]  Pointer to Buffer Param
623 {
624     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
625     PMOS_INTERFACE osInterface = state->renderHal->pOsInterface;
626     PCM_HAL_SURFACE2D_UP_ENTRY entry = nullptr;
627 
628     MOS_ALLOC_GFXRES_PARAMS allocParams;
629 
630     //-----------------------------------------------
631     CM_ASSERT(state);
632     CM_ASSERT(param->width > 0 && param->height > 0);
633     //-----------------------------------------------
634 
635     // Find a free slot
636     for (uint32_t i = 0; i < state->cmDeviceParam.max2DSurfaceUPTableSize; ++i)
637     {
638         if (state->surf2DUPTable[i].width == 0)
639         {
640             entry              = &state->surf2DUPTable[i];
641             param->handle      = (uint32_t)i;
642             break;
643         }
644     }
645     if (!entry)
646     {
647         eStatus = MOS_STATUS_INVALID_PARAMETER;
648         CM_ASSERTMESSAGE("Surface2DUP table is full");
649         goto finish;
650     }
651     MOS_ZeroMemory(&allocParams, sizeof(allocParams));
652     allocParams.Type          = MOS_GFXRES_2D;
653     allocParams.TileType      = MOS_TILE_LINEAR;
654     allocParams.dwWidth       = param->width;
655     allocParams.dwHeight      = param->height;
656     allocParams.pSystemMemory = param->data;
657     allocParams.Format        = param->format;
658     allocParams.pBufName      = "CmSurface2DUP";
659 
660     CM_CHK_HRESULT_GOTOFINISH_MOSERROR(osInterface->pfnAllocateResource(
661         osInterface,
662         &allocParams,
663         &entry->osResource));
664 
665     entry->width  = param->width;
666     entry->height = param->height;
667     entry->format  = param->format;
668 
669     if (state->advExecutor)
670     {
671         entry->surfStateMgr = state->advExecutor->Create2DStateMgr(&entry->osResource);
672     }
673 
674 finish:
675     return eStatus;
676 }
677 
678 //*-----------------------------------------------------------------------------
679 //| Purpose:    Get GPU current frequency
680 //| Returns:    Result of the operation.
681 //*-----------------------------------------------------------------------------
HalCm_GetGPUCurrentFrequency_Linux(PCM_HAL_STATE state,uint32_t * currentFrequency)682 MOS_STATUS HalCm_GetGPUCurrentFrequency_Linux(
683     PCM_HAL_STATE               state,                                         // [in]  Pointer to CM State
684     uint32_t                    *currentFrequency)                                   // [out] Pointer to current frequency
685 {
686     UNUSED(state);
687 
688     //-----------------------------------------
689     CM_ASSERT(state);
690     //-----------------------------------------
691     *currentFrequency   = 0;
692 
693     return MOS_STATUS_SUCCESS;
694 }
695 
HalCm_GetGpuTime_Linux(PCM_HAL_STATE state,uint64_t * gpuTime)696 MOS_STATUS HalCm_GetGpuTime_Linux(PCM_HAL_STATE state, uint64_t *gpuTime)
697 {
698     UNUSED(state);
699     *gpuTime = 0;
700 
701     return MOS_STATUS_SUCCESS;
702 }
703 
704 //*-----------------------------------------------------------------------------
705 // Purpose: Check if conditional batch buffer supported
706 // Returns: False on Linux
707 //*-----------------------------------------------------------------------------
HalCm_IsCbbEnabled(PCM_HAL_STATE state)708 bool HalCm_IsCbbEnabled(
709     PCM_HAL_STATE                           state)
710 {
711     return false;
712 }
713 
714 //*-----------------------------------------------------------------------------
715 // Purpose: Wait kernel finished in state heap
716 // Returns: Result of the operation
717 //*-----------------------------------------------------------------------------
HalCm_SyncKernel(PCM_HAL_STATE state,uint32_t sync)718 int32_t HalCm_SyncKernel(
719     PCM_HAL_STATE                           state,
720     uint32_t                                sync)
721 {
722     int32_t                    eStatus = CM_SUCCESS;
723     PRENDERHAL_INTERFACE       renderHal = state->renderHal;
724     PRENDERHAL_STATE_HEAP      stateHeap = renderHal->pStateHeap;
725 
726     // Update Sync tags
727     CM_CHK_MOSSTATUS_GOTOFINISH(renderHal->pfnRefreshSync(renderHal));
728 
729     while ( ( int32_t )( stateHeap->dwSyncTag - sync ) < 0 )
730     {
731         CM_CHK_MOSSTATUS_GOTOFINISH( renderHal->pfnRefreshSync( renderHal ) );
732     }
733 
734 finish:
735     return eStatus;
736 }
737 
738 //===============<Os-dependent Private/Non-DDI Functions, Part 2>============================================
739 
740 //Require DRM VMAP patch,
741 //Referecing:
742 //    [Intel-gfx] [PATCH 21/21] drm/i915: Introduce vmap (mapping of user pages into video memory) ioctl
743 //    http://lists.freedesktop.org/archives/intel-gfx/2011-April/010241.html
HalCm_GetLibDrmVMapFnt(PCM_HAL_STATE cmState)744 void HalCm_GetLibDrmVMapFnt(
745                  PCM_HAL_STATE           cmState)
746 {
747     cmState->hLibModule = nullptr;
748     cmState->drmVMap = nullptr;
749     return ;
750 }
751 
752 //*-----------------------------------------------------------------------------
753 //| Purpose:  Gets platform information like slices/sub-slices/EUPerSubSlice etc.
754 //| Returns:  Result of the operation
755 //*-----------------------------------------------------------------------------
HalCm_GetPlatformInfo_Linux(PCM_HAL_STATE state,PCM_PLATFORM_INFO platformInfo,bool euSaturated)756 MOS_STATUS HalCm_GetPlatformInfo_Linux(
757     PCM_HAL_STATE                  state,              // [in] Pointer to CM State
758     PCM_PLATFORM_INFO               platformInfo,        // [out] Pointer to platformInfo
759     bool                           euSaturated)
760 {
761 
762     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
763     MEDIA_SYSTEM_INFO             *gtSystemInfo;
764 
765     UNUSED(euSaturated);
766 
767     gtSystemInfo = state->osInterface->pfnGetGtSystemInfo(state->osInterface);
768 
769     platformInfo->numHWThreadsPerEU    = gtSystemInfo->ThreadCount / gtSystemInfo->EUCount;
770     platformInfo->numEUsPerSubSlice    = gtSystemInfo->EUCount / gtSystemInfo->SubSliceCount;
771 
772     if (state->cmHalInterface->CheckMediaModeAvailability())
773     {
774         platformInfo->numSlices            = gtSystemInfo->SliceCount;
775         platformInfo->numSubSlices         = gtSystemInfo->SubSliceCount;
776     }
777     else
778     { // not use Slice/SubSlice count  set to 0
779         platformInfo->numSlices = 0;
780         platformInfo->numSubSlices = 0;
781     }
782 
783     return eStatus;
784 }
785 
786 //*-----------------------------------------------------------------------------
787 //| Purpose:  Gets GT system information for which slices/sub-slices are enabled
788 //| Returns:  Result of the operation
789 //*-----------------------------------------------------------------------------
HalCm_GetGTSystemInfo_Linux(PCM_HAL_STATE state,PCM_GT_SYSTEM_INFO pSystemInfo)790 MOS_STATUS HalCm_GetGTSystemInfo_Linux(
791     PCM_HAL_STATE                state,                // [in] Pointer to CM state
792     PCM_GT_SYSTEM_INFO           pSystemInfo            // [out] Pointer to CM GT system info
793 )
794 {
795     MEDIA_SYSTEM_INFO            *gtSystemInfo;
796     CM_EXPECTED_GT_SYSTEM_INFO    expectedGTInfo;
797 
798     gtSystemInfo = state->osInterface->pfnGetGtSystemInfo(state->osInterface);
799 
800     pSystemInfo->numMaxSlicesSupported    = gtSystemInfo->MaxSlicesSupported;
801     pSystemInfo->numMaxSubSlicesSupported = gtSystemInfo->MaxSubSlicesSupported;
802 
803     state->cmHalInterface->GetExpectedGtSystemConfig(&expectedGTInfo);
804 
805     // check numSlices/SubSlices enabled equal the expected number for this GT
806     // if match, pSystemInfo->isSliceInfoValid = true, else pSystemInfo->isSliceInfoValid = false
807     if ((expectedGTInfo.numSlices    == gtSystemInfo->SliceCount) &&
808         (expectedGTInfo.numSubSlices == gtSystemInfo->SubSliceCount))
809     {
810         pSystemInfo->isSliceInfoValid = true;
811     }
812     else
813     {
814         pSystemInfo->isSliceInfoValid = false;
815     }
816 
817     // if valid, set the number slice/subSlice to enabled for numSlices/numSubSlices
818     if(pSystemInfo->isSliceInfoValid)
819     {
820         for(uint32_t i = 0; i < gtSystemInfo->SliceCount; ++i)
821         {
822             pSystemInfo->sliceInfo[i].Enabled = true;
823             for(uint32_t j = 0; j < gtSystemInfo->SubSliceCount; ++j)
824             {
825                 pSystemInfo->sliceInfo[i].SubSliceInfo[j].Enabled = true;
826             }
827         }
828     }
829 
830     return MOS_STATUS_SUCCESS;
831 }
832 
833 //*-----------------------------------------------------------------------------
834 //| Purpose:    Query the status of the task
835 //| Returns:    Result of the operation.
836 //*-----------------------------------------------------------------------------
HalCm_QueryTask_Linux(PCM_HAL_STATE state,PCM_HAL_QUERY_TASK_PARAM queryParam)837 MOS_STATUS HalCm_QueryTask_Linux(
838     PCM_HAL_STATE             state,
839     PCM_HAL_QUERY_TASK_PARAM  queryParam)
840 {
841     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
842     PRENDERHAL_INTERFACE    renderHal;
843     int64_t                 *piSyncStart;
844     int64_t                 *piSyncEnd;
845     uint64_t                ticks;
846     int32_t                 syncOffset;
847     PRENDERHAL_STATE_HEAP   stateHeap;
848     uint64_t                hwStartNs;
849     uint64_t                hwEndNs;
850     int32_t                 maxTasks;
851 
852     //-----------------------------------------
853     CM_ASSERT(state);
854     CM_ASSERT(queryParam);
855     //-----------------------------------------
856 
857     maxTasks = (int32_t)state->cmDeviceParam.maxTasks;
858     if ((queryParam->taskId < 0) || (queryParam->taskId >= maxTasks) ||
859         (state->taskStatusTable[queryParam->taskId] == CM_INVALID_INDEX))
860     {
861         eStatus = MOS_STATUS_INVALID_PARAMETER;
862         CM_ASSERTMESSAGE("Invalid Task ID'%d'.", queryParam->taskId);
863         goto finish;
864     }
865 
866     renderHal = state->renderHal;
867     stateHeap = renderHal->pStateHeap;
868     syncOffset = state->pfnGetTaskSyncLocation(state, queryParam->taskId);
869     piSyncStart = (int64_t*)(state->renderTimeStampResource.data + syncOffset);
870     piSyncEnd = piSyncStart + 1;
871     queryParam->taskDurationNs = CM_INVALID_INDEX;
872 
873     if (*piSyncStart == CM_INVALID_INDEX)
874     {
875         queryParam->status = CM_TASK_QUEUED;
876     }
877     else if (*piSyncEnd == CM_INVALID_INDEX)
878     {
879         queryParam->status = CM_TASK_IN_PROGRESS;
880     }
881     else
882     {
883         queryParam->status = CM_TASK_FINISHED;
884 
885         hwStartNs = HalCm_ConvertTicksToNanoSeconds(state, *piSyncStart);
886         hwEndNs = HalCm_ConvertTicksToNanoSeconds(state, *piSyncEnd);
887 
888         ticks = *piSyncEnd - *piSyncStart;
889 
890         queryParam->taskDurationTicks = ticks;
891         queryParam->taskHWStartTimeStampInTicks = *piSyncStart;
892         queryParam->taskHWEndTimeStampInTicks   = *piSyncEnd;
893 
894         // Convert ticks to Nanoseconds
895         queryParam->taskDurationNs = HalCm_ConvertTicksToNanoSeconds(state, ticks);
896 
897         queryParam->taskGlobalSubmitTimeCpu = state->taskTimeStamp->submitTimeInCpu[queryParam->taskId];
898         CM_CHK_MOSSTATUS_GOTOFINISH(state->pfnConvertToQPCTime(state->taskTimeStamp->submitTimeInGpu[queryParam->taskId], &queryParam->taskSubmitTimeGpu));
899         CM_CHK_MOSSTATUS_GOTOFINISH(state->pfnConvertToQPCTime(hwStartNs, &queryParam->taskHWStartTimeStamp));
900         CM_CHK_MOSSTATUS_GOTOFINISH(state->pfnConvertToQPCTime(hwEndNs, &queryParam->taskHWEndTimeStamp));
901 
902         state->taskStatusTable[queryParam->taskId] = CM_INVALID_INDEX;
903     }
904 
905 finish:
906     return eStatus;
907 }
908 
HalCm_WriteGPUStatusTagToCMTSResource_Linux(PCM_HAL_STATE state,PMOS_COMMAND_BUFFER cmdBuffer,int32_t taskID,bool isVebox)909 MOS_STATUS HalCm_WriteGPUStatusTagToCMTSResource_Linux(
910     PCM_HAL_STATE             state,
911     PMOS_COMMAND_BUFFER       cmdBuffer,
912     int32_t                   taskID,
913     bool                      isVebox)
914 {
915     UNUSED(state);
916     UNUSED(cmdBuffer);
917     UNUSED(taskID);
918     UNUSED(isVebox);
919     return MOS_STATUS_SUCCESS;
920 }
921 
922 //*-----------------------------------------------------------------------------
923 //| Purpose:    Lock the resource and return
924 //| Returns:    Result of the operation.
925 //*-----------------------------------------------------------------------------
HalCm_Lock2DResource(PCM_HAL_STATE state,PCM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM param)926 MOS_STATUS HalCm_Lock2DResource(
927     PCM_HAL_STATE               state,                                         // [in]  Pointer to CM State
928     PCM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM     param)                                         // [in]  Pointer to 2D Param
929 {
930     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
931     MOS_LOCK_PARAMS             lockFlags;
932     RENDERHAL_GET_SURFACE_INFO  info;
933 
934     MOS_SURFACE                 surface;
935     PMOS_INTERFACE              osInterface = nullptr;
936 
937     if ((param->lockFlag != CM_HAL_LOCKFLAG_READONLY) && (param->lockFlag != CM_HAL_LOCKFLAG_WRITEONLY) )
938     {
939         CM_ASSERTMESSAGE("Invalid lock flag!");
940         eStatus = MOS_STATUS_UNKNOWN;
941         goto finish;
942     }
943 
944     MOS_ZeroMemory(&surface, sizeof(surface));
945     surface.Format = Format_Invalid;
946     osInterface   = state->osInterface;
947 
948     if(param->data == nullptr)
949     {   // CMRT@UMD
950         PCM_HAL_SURFACE2D_ENTRY    entry;
951 
952         // Get the 2D Resource Entry
953         entry = &state->umdSurf2DTable[param->handle];
954 
955         // Get resource information
956         surface.OsResource = entry->osResource;
957         MOS_ZeroMemory(&info, sizeof(RENDERHAL_GET_SURFACE_INFO));
958 
959         CM_CHK_MOSSTATUS_GOTOFINISH(RenderHal_GetSurfaceInfo(
960                   osInterface,
961                   &info,
962                   &surface));
963 
964         param->pitch = surface.dwPitch;
965         param->format = surface.Format;
966         param->YSurfaceOffset = surface.YPlaneOffset;
967         param->USurfaceOffset = surface.UPlaneOffset;
968         param->VSurfaceOffset = surface.VPlaneOffset;
969 
970         // Lock the resource
971         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
972 
973         if (param->lockFlag == CM_HAL_LOCKFLAG_READONLY)
974         {
975             lockFlags.ReadOnly = true;
976         }
977         else
978         {
979             lockFlags.WriteOnly = true;
980         }
981 
982         lockFlags.ForceCached = true;
983 
984         param->data = osInterface->pfnLockResource(
985                         osInterface,
986                         &entry->osResource,
987                         &lockFlags);
988 
989     }
990     else
991     {
992         CM_ASSERTMESSAGE("Error: Failed to lock surface 2d resource.");
993         eStatus = MOS_STATUS_UNKNOWN;
994     }
995     CM_CHK_NULL_GOTOFINISH_MOSERROR(param->data);
996 
997 finish:
998     return eStatus;
999 }
1000 
1001 //*-----------------------------------------------------------------------------
1002 //| Purpose:    Unlock the resource and return
1003 //| Returns:    Result of the operation.
1004 //*-----------------------------------------------------------------------------
HalCm_Unlock2DResource(PCM_HAL_STATE state,PCM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM param)1005 MOS_STATUS HalCm_Unlock2DResource(
1006     PCM_HAL_STATE                           state,                                         // [in]  Pointer to CM State
1007     PCM_HAL_SURFACE2D_LOCK_UNLOCK_PARAM     param)                                         // [in]  Pointer to 2D Param
1008 {
1009     MOS_STATUS              eStatus        = MOS_STATUS_SUCCESS;
1010     PMOS_INTERFACE          osInterface    = state->osInterface;
1011 
1012     if(param->data == nullptr)
1013     {
1014         PCM_HAL_SURFACE2D_ENTRY     entry;
1015 
1016         // Get the 2D Resource Entry
1017         entry = &state->umdSurf2DTable[param->handle];
1018 
1019         // UnLock the resource
1020         CM_CHK_HRESULT_GOTOFINISH_MOSERROR(osInterface->pfnUnlockResource(osInterface, &(entry->osResource)));
1021     }
1022     else
1023     {
1024         CM_ASSERTMESSAGE("Error: Failed to unlock surface 2d resource.");
1025         eStatus = MOS_STATUS_UNKNOWN;
1026     }
1027 
1028 finish:
1029     return eStatus;
1030 }
1031 
1032 //*-----------------------------------------------------------------------------
1033 //| Purpose: Get the GfxMap Filter based on the texture filter type
1034 //| Returns: Result
1035 //*-----------------------------------------------------------------------------
HalCm_GetGfxMapFilter(uint32_t filterMode,MHW_GFX3DSTATE_MAPFILTER * gfxFilter)1036 MOS_STATUS HalCm_GetGfxMapFilter(
1037     uint32_t                     filterMode,
1038     MHW_GFX3DSTATE_MAPFILTER     *gfxFilter)
1039 {
1040     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1041 
1042     switch(filterMode)
1043     {
1044     case CM_TEXTURE_FILTER_TYPE_LINEAR:
1045         *gfxFilter = MHW_GFX3DSTATE_MAPFILTER_LINEAR;
1046         break;
1047     case CM_TEXTURE_FILTER_TYPE_POINT:
1048         *gfxFilter = MHW_GFX3DSTATE_MAPFILTER_NEAREST;
1049         break;
1050     case CM_TEXTURE_FILTER_TYPE_ANISOTROPIC:
1051         *gfxFilter = MHW_GFX3DSTATE_MAPFILTER_ANISOTROPIC;
1052         break;
1053 
1054     default:
1055         eStatus = MOS_STATUS_INVALID_PARAMETER;
1056         CM_ASSERTMESSAGE("Filter '%d' not supported", filterMode);
1057         goto finish;
1058     }
1059 
1060 finish:
1061     return eStatus;
1062 }
1063 
1064 //*-----------------------------------------------------------------------------
1065 //| Purpose: Get the Gfx Texture Address based on the texture coordinate type
1066 //| Returns: Result
1067 //*-----------------------------------------------------------------------------
HalCm_GetGfxTextAddress(uint32_t addressMode,MHW_GFX3DSTATE_TEXCOORDMODE * gfxAddress)1068 MOS_STATUS HalCm_GetGfxTextAddress(
1069     uint32_t                     addressMode,
1070     MHW_GFX3DSTATE_TEXCOORDMODE  *gfxAddress)
1071 {
1072     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1073 
1074     switch(addressMode)
1075     {
1076 
1077     case CM_TEXTURE_ADDRESS_WRAP:
1078         *gfxAddress = MHW_GFX3DSTATE_TEXCOORDMODE_WRAP;
1079         break;
1080     case CM_TEXTURE_ADDRESS_MIRROR:
1081         *gfxAddress = MHW_GFX3DSTATE_TEXCOORDMODE_MIRROR;
1082         break;
1083     case CM_TEXTURE_ADDRESS_CLAMP:
1084         *gfxAddress = MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP;
1085         break;
1086     case CM_TEXTURE_ADDRESS_BORDER:
1087         *gfxAddress = MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP_BORDER;
1088         break;
1089 
1090     default:
1091         eStatus = MOS_STATUS_INVALID_PARAMETER;
1092         CM_ASSERTMESSAGE("Address '%d' not supported", addressMode);
1093         goto finish;
1094     }
1095 
1096 finish:
1097     return eStatus;
1098 }
1099 
1100 //*-----------------------------------------------------------------------------
1101 //| Purpose:    If WA required to set SLM in L3
1102 //| Returns:    Display corruption observed when running MDF workload.
1103 //|             This issue is related to SLM setting in L3.
1104 //|             To resolve this problem, we need to disable SLM after
1105 //|             command submission.
1106 //*-----------------------------------------------------------------------------
HalCm_IsWaSLMinL3Cache_Linux()1107 bool HalCm_IsWaSLMinL3Cache_Linux()
1108 {
1109     bool flag;
1110 #if ANDROID
1111     flag = false;
1112 #else
1113     flag = true;
1114 #endif
1115     return flag;
1116 }
1117 
1118 //*-----------------------------------------------------------------------------
1119 //| Purpose:    Enable GPU frequency Turbo boost on Linux
1120 //| Returns:    MOS_STATUS_SUCCESS.
1121 //*-----------------------------------------------------------------------------
1122 #define I915_CONTEXT_PRIVATE_PARAM_BOOST 0x80000000
HalCm_EnableTurboBoost_Linux(PCM_HAL_STATE state)1123 MOS_STATUS HalCm_EnableTurboBoost_Linux(
1124     PCM_HAL_STATE             state)
1125 {
1126 #ifndef ANDROID
1127     struct drm_i915_gem_context_param ctxParam;
1128     int32_t retVal = 0;
1129 
1130     MOS_ZeroMemory( &ctxParam, sizeof( ctxParam ) );
1131     ctxParam.param = I915_CONTEXT_PRIVATE_PARAM_BOOST;
1132     ctxParam.value = 1;
1133     retVal = drmIoctl( state->osInterface->pOsContext->fd,
1134                       DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctxParam );
1135 #endif
1136     //if drmIoctl fail, we will stay in normal mode.
1137     return MOS_STATUS_SUCCESS;
1138 }
1139 
1140 //!
1141 //! \brief    Updates tracker resource used in state heap management
1142 //! \param    [in] state
1143 //!           CM HAL State
1144 //! \param    [in,out] cmdBuffer
1145 //!           Command buffer containing the workload
1146 //! \param    [in] tag
1147 //|           Tag to write to tracker resource
1148 //! \return   MOS_STATUS
1149 //!           MOS_STATUS_SUCCESS if success, else fail reason
1150 //!
HalCm_UpdateTrackerResource_Linux(PCM_HAL_STATE state,PMOS_COMMAND_BUFFER cmdBuffer,uint32_t tag)1151 MOS_STATUS HalCm_UpdateTrackerResource_Linux(
1152     PCM_HAL_STATE       state,
1153     PMOS_COMMAND_BUFFER cmdBuffer,
1154     uint32_t            tag)
1155 {
1156     MHW_MI_STORE_DATA_PARAMS storeDataParams;
1157     MOS_GPU_CONTEXT          gpuContext = MOS_GPU_CONTEXT_INVALID_HANDLE;
1158     MOS_STATUS               eStatus = MOS_STATUS_SUCCESS;
1159 
1160     MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
1161     gpuContext = state->renderHal->pOsInterface->CurrentGpuContextOrdinal;
1162     if (gpuContext == MOS_GPU_CONTEXT_VEBOX)
1163     {
1164         MOS_RESOURCE osResource = state->renderHal->veBoxTrackerRes.osResource;
1165         storeDataParams.pOsResource = &osResource;
1166     }
1167     else
1168     {
1169         state->renderHal->trackerProducer.GetLatestTrackerResource(state->renderHal->currentTrackerIndex,
1170                             &storeDataParams.pOsResource,
1171                             &storeDataParams.dwResourceOffset);
1172     }
1173 
1174     storeDataParams.dwValue = tag;
1175     eStatus = state->renderHal->pMhwMiInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams);
1176     return eStatus;
1177 }
1178 
HalCm_RegisterStream(CM_HAL_STATE * state)1179 uint32_t HalCm_RegisterStream(CM_HAL_STATE *state)
1180 {
1181     return state->osInterface->streamIndex;
1182 }
1183 
HalCm_OsInitInterface(PCM_HAL_STATE cmState)1184 void HalCm_OsInitInterface(
1185     PCM_HAL_STATE           cmState)          // [out]  pointer to CM State
1186 {
1187     CM_ASSERT(cmState);
1188 
1189     cmState->pfnGetSurface2DPitchAndSize            = HalCm_GetSurface2DPitchAndSize_Linux;
1190     cmState->pfnRegisterUMDNotifyEventHandle        = HalCm_RegisterUMDNotifyEventHandle_Linux;
1191     cmState->pfnAllocateBuffer                      = HalCm_AllocateBuffer_Linux;
1192     cmState->pfnAllocateSurface2DUP                 = HalCm_AllocateSurface2DUP_Linux;
1193     cmState->pfnGetGPUCurrentFrequency              = HalCm_GetGPUCurrentFrequency_Linux;
1194     cmState->pfnGetGpuTime                          = HalCm_GetGpuTime_Linux;
1195     cmState->pfnGetPlatformInfo                     = HalCm_GetPlatformInfo_Linux;
1196     cmState->pfnGetGTSystemInfo                     = HalCm_GetGTSystemInfo_Linux;
1197     cmState->pfnReferenceCommandBuffer              = HalCm_ReferenceCommandBuf_Linux;
1198     cmState->pfnSetCommandBufferResource            = HalCm_SetCommandBufResource_Linux;
1199     cmState->pfnQueryTask                           = HalCm_QueryTask_Linux;
1200     cmState->pfnIsWASLMinL3Cache                    = HalCm_IsWaSLMinL3Cache_Linux;
1201     cmState->pfnEnableTurboBoost                    = HalCm_EnableTurboBoost_Linux;
1202     cmState->pfnUpdateTrackerResource               = HalCm_UpdateTrackerResource_Linux;
1203     cmState->pfnRegisterStream                      = HalCm_RegisterStream;
1204 
1205     HalCm_GetLibDrmVMapFnt(cmState);
1206     cmState->syncOnResource                         = false;
1207     return;
1208 }
1209 
1210 //*-------------------------------------------------------------------------------------
1211 //| Purpose:    Add PipeControl with a Conditional Time Stamp (valid/invalid time stamp)
1212 //| Returns:    On Success, right before Pipe Control commands, insert commands to write
1213 //|             time stamp to Sync Location. When the condition same as following
1214 //|             "conditional buffer end" command is assert, the time stamp is a valid value,
1215 //|             otherwise an invalid time stamp is used to write Sync Location.
1216 //*-------------------------------------------------------------------------------------
1217 
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)1218 MOS_STATUS HalCm_OsAddArtifactConditionalPipeControl(
1219     PCM_HAL_MI_REG_OFFSETS offsets,
1220     PCM_HAL_STATE state,
1221     PMOS_COMMAND_BUFFER cmdBuffer, //commmand buffer
1222     int32_t syncOffset,   //offset to syncation of time stamp
1223     PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS conditionalParams, //comparing Params
1224     uint32_t trackerTag)
1225 {
1226     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1227     MHW_MI_LOAD_REGISTER_REG_PARAMS     loadRegRegParams;
1228     MHW_MI_LOAD_REGISTER_IMM_PARAMS     loadRegImmParams;
1229     MHW_MI_LOAD_REGISTER_MEM_PARAMS     loadRegMemParams;
1230 
1231     MHW_MI_STORE_REGISTER_MEM_PARAMS    storeRegParams;
1232     MHW_MI_STORE_DATA_PARAMS            storeDataParams;
1233     MHW_MI_FLUSH_DW_PARAMS              flushDwParams;
1234     MHW_MI_MATH_PARAMS                  mathParams;
1235     MHW_MI_ALU_PARAMS                   aluParams[20];
1236     MHW_MI_STORE_REGISTER_MEM_PARAMS    storeRegMemParams;
1237     MHW_PIPE_CONTROL_PARAMS             pipeCtrlParams;
1238 
1239     PMHW_MI_INTERFACE  mhwMiInterface = state->renderHal->pMhwMiInterface;
1240 
1241     MOS_ZeroMemory(&loadRegRegParams, sizeof(loadRegRegParams));
1242     loadRegRegParams.dwSrcRegister = offsets->timeStampOffset;         //read time stamp
1243     loadRegRegParams.dwDstRegister = offsets->gprOffset + 0;
1244     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterRegCmd(cmdBuffer, &loadRegRegParams));
1245     loadRegRegParams.dwSrcRegister = offsets->timeStampOffset + 4;
1246     loadRegRegParams.dwDstRegister = offsets->gprOffset + 4;
1247     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterRegCmd(cmdBuffer, &loadRegRegParams));     //R0: time stamp
1248 
1249     MOS_ZeroMemory(&mathParams, sizeof(mathParams));
1250     MOS_ZeroMemory(&aluParams, sizeof(aluParams));
1251 
1252     aluParams[0].AluOpcode = MHW_MI_ALU_AND;
1253 
1254     // store      reg1, CF
1255     aluParams[1].AluOpcode = MHW_MI_ALU_STORE;
1256     aluParams[1].Operand1 = MHW_MI_ALU_GPREG1;
1257     aluParams[1].Operand2 = MHW_MI_ALU_CF;
1258     // store      reg2, CF
1259     aluParams[2].AluOpcode = MHW_MI_ALU_STORE;
1260     aluParams[2].Operand1 = MHW_MI_ALU_GPREG2;
1261     aluParams[2].Operand2 = MHW_MI_ALU_CF;
1262     // store      reg3, CF
1263     aluParams[2].AluOpcode = MHW_MI_ALU_STORE;
1264     aluParams[2].Operand1 = MHW_MI_ALU_GPREG3;
1265     aluParams[2].Operand2 = MHW_MI_ALU_CF;                                                                      //clear R1 -- R3
1266 
1267     mathParams.pAluPayload = aluParams;
1268     mathParams.dwNumAluParams = 3;
1269     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiMathCmd(cmdBuffer, &mathParams));                     //MI cmd to clear R1 - R3
1270 
1271     MOS_ZeroMemory(&loadRegMemParams, sizeof(loadRegMemParams));
1272     loadRegMemParams.presStoreBuffer = conditionalParams->presSemaphoreBuffer;
1273     loadRegMemParams.dwOffset = conditionalParams->dwOffset;
1274     loadRegMemParams.dwRegister = offsets->gprOffset + 8 * 1;
1275     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &loadRegMemParams));    //R1: compared value 32bits, in coditional surface
1276                                                                                                   // Load current tracker tag from resource to R8
1277     MOS_ZeroMemory(&loadRegMemParams, sizeof(loadRegMemParams));
1278     state->renderHal->trackerProducer.GetLatestTrackerResource(state->renderHal->currentTrackerIndex,
1279                                 &loadRegMemParams.presStoreBuffer,
1280                                 &loadRegMemParams.dwOffset);
1281     loadRegMemParams.dwRegister = offsets->gprOffset+ 8 * 8;
1282     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &loadRegMemParams));  // R8: current tracker tag
1283 
1284                                                                                                 // Load new tag passed to this function to R9
1285     MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
1286     loadRegImmParams.dwData = trackerTag;
1287     loadRegImmParams.dwRegister = offsets->gprOffset+ 8 * 9;
1288     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &loadRegImmParams));  // R9: new tracker tag
1289                                                                                                 //
1290 
1291     if (!conditionalParams->bDisableCompareMask)
1292     {
1293         loadRegMemParams.presStoreBuffer = conditionalParams->presSemaphoreBuffer;
1294         loadRegMemParams.dwOffset = conditionalParams->dwOffset + 4;
1295         loadRegMemParams.dwRegister = offsets->gprOffset + 8 * 2;
1296         CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &loadRegMemParams)); //r1, r2: compared value and its mask
1297         //load1 reg1, srca
1298         aluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
1299         aluParams[0].Operand1 = MHW_MI_ALU_SRCA;
1300         aluParams[0].Operand2 = MHW_MI_ALU_GPREG1;
1301         //load reg2, srcb
1302         aluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
1303         aluParams[1].Operand1 = MHW_MI_ALU_SRCB;
1304         aluParams[1].Operand2 = MHW_MI_ALU_GPREG2;
1305         //add
1306         aluParams[2].AluOpcode = MHW_MI_ALU_AND;
1307         //store reg1, accu
1308         aluParams[3].AluOpcode = MHW_MI_ALU_STORE;
1309         aluParams[3].Operand1 = MHW_MI_ALU_GPREG1;
1310         aluParams[3].Operand2 = MHW_MI_ALU_ACCU;                                                                     //REG14 = TS + 1
1311 
1312         mathParams.pAluPayload = aluParams;
1313         mathParams.dwNumAluParams = 4;
1314         CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiMathCmd(cmdBuffer, &mathParams));                     //R1 & R2 --> R1: compared value, to be used
1315     }
1316 
1317     MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
1318     loadRegImmParams.dwData = conditionalParams->dwValue;
1319     loadRegImmParams.dwRegister = offsets->gprOffset + 8 * 2;
1320     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &loadRegImmParams));    //R2: user value 32bits
1321 
1322     MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
1323     loadRegImmParams.dwData = 1;
1324     loadRegImmParams.dwRegister = offsets->gprOffset + 8 * 3;
1325     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &loadRegImmParams));    //R3 = 1
1326 
1327     //load1 reg3, srca
1328     aluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
1329     aluParams[0].Operand1 = MHW_MI_ALU_SRCA;
1330     aluParams[0].Operand2 = MHW_MI_ALU_GPREG3;
1331     //load reg0, srcb
1332     aluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
1333     aluParams[1].Operand1 = MHW_MI_ALU_SRCB;
1334     aluParams[1].Operand2 = MHW_MI_ALU_GPREG0;
1335     //add
1336     aluParams[2].AluOpcode = MHW_MI_ALU_ADD;
1337     //store reg14, accu
1338     aluParams[3].AluOpcode = MHW_MI_ALU_STORE;
1339     aluParams[3].Operand1 = MHW_MI_ALU_GPREG14;
1340     aluParams[3].Operand2 = MHW_MI_ALU_ACCU;                                                                     //REG14 = TS + 1
1341 
1342     // load     srcB, reg1
1343     aluParams[4].AluOpcode = MHW_MI_ALU_LOAD;
1344     aluParams[4].Operand1 = MHW_MI_ALU_SRCB;
1345     aluParams[4].Operand2 = MHW_MI_ALU_GPREG1;                                               //load compared val
1346     // load     srcA, reg2
1347     aluParams[5].AluOpcode = MHW_MI_ALU_LOAD;
1348     aluParams[5].Operand1 = MHW_MI_ALU_SRCA;
1349     aluParams[5].Operand2 = MHW_MI_ALU_GPREG2;                                              //load user val
1350     // sub      srcA, srcB
1351     aluParams[6].AluOpcode = MHW_MI_ALU_SUB;                                                //if (compared > user) 1 ==> CF otherwise 0 ==> CF
1352     // store      reg4, CF
1353     aluParams[7].AluOpcode = MHW_MI_ALU_STOREINV;
1354     aluParams[7].Operand1 = MHW_MI_ALU_GPREG4;
1355     aluParams[7].Operand2 = MHW_MI_ALU_CF;                                                 //!CF ==> R4, mask
1356     //load      reg4, srcA
1357     aluParams[8].AluOpcode = MHW_MI_ALU_LOAD;
1358     aluParams[8].Operand1 = MHW_MI_ALU_SRCA;
1359     aluParams[8].Operand2 = MHW_MI_ALU_GPREG4;
1360     //load reg14, SRCB
1361     aluParams[9].AluOpcode = MHW_MI_ALU_LOAD;
1362     aluParams[9].Operand1 = MHW_MI_ALU_SRCB;
1363     aluParams[9].Operand2 = MHW_MI_ALU_GPREG14;
1364     //and
1365     aluParams[10].AluOpcode = MHW_MI_ALU_AND;                                             //0 or TS+1 (!CF & TS)
1366 
1367     //store reg6, accu
1368     aluParams[11].AluOpcode = MHW_MI_ALU_STORE;                                       //R6 = (TS+1) (to terminate) or 0 (to continue)
1369     aluParams[11].Operand1 = MHW_MI_ALU_GPREG6;
1370     aluParams[11].Operand2 = MHW_MI_ALU_ACCU;
1371 
1372     //invalud time stamp is all '1's for MDF
1373     //load reg6, SRCA
1374     aluParams[12].AluOpcode = MHW_MI_ALU_LOAD;
1375     aluParams[12].Operand1 = MHW_MI_ALU_SRCA;
1376     aluParams[12].Operand2 = MHW_MI_ALU_GPREG6;
1377     //load1 SRCB
1378     aluParams[13].AluOpcode = MHW_MI_ALU_LOAD;
1379     aluParams[13].Operand1 = MHW_MI_ALU_SRCB;
1380     aluParams[13].Operand2 = MHW_MI_ALU_GPREG3;
1381     //sub
1382     aluParams[14].AluOpcode = MHW_MI_ALU_SUB;                                             //-1 or TS (!CF & TS)
1383     //store reg7, accu
1384     aluParams[15].AluOpcode = MHW_MI_ALU_STORE;                                       //R7 = (TS) (to terminate) or all '1'  ( -1 to continue)
1385     aluParams[15].Operand1 = MHW_MI_ALU_GPREG7;
1386     aluParams[15].Operand2 = MHW_MI_ALU_ACCU;
1387 
1388     mathParams.pAluPayload = aluParams;
1389     mathParams.dwNumAluParams = 16;
1390     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiMathCmd(cmdBuffer, &mathParams));            //set artifact time stamp (-1 or TS) per condition in GPR R7
1391 
1392     // Add R3 (has value 1) to R4 (~CF) and store result in R10
1393     aluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
1394     aluParams[0].Operand1 = MHW_MI_ALU_SRCA;
1395     aluParams[0].Operand2 = MHW_MI_ALU_GPREG3;
1396 
1397     aluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
1398     aluParams[1].Operand1 = MHW_MI_ALU_SRCB;
1399     aluParams[1].Operand2 = MHW_MI_ALU_GPREG4;
1400 
1401     aluParams[2].AluOpcode = MHW_MI_ALU_ADD;
1402 
1403     aluParams[3].AluOpcode = MHW_MI_ALU_STORE;
1404     aluParams[3].Operand1 = MHW_MI_ALU_GPREG10;
1405     aluParams[3].Operand2 = MHW_MI_ALU_ACCU;
1406 
1407     // AND R8 (current tracker tag) with R10 (~CF + 1) and store in R11
1408     aluParams[4].AluOpcode = MHW_MI_ALU_LOAD;
1409     aluParams[4].Operand1 = MHW_MI_ALU_SRCA;
1410     aluParams[4].Operand2 = MHW_MI_ALU_GPREG8;
1411 
1412     aluParams[5].AluOpcode = MHW_MI_ALU_LOAD;
1413     aluParams[5].Operand1 = MHW_MI_ALU_SRCB;
1414     aluParams[5].Operand2 = MHW_MI_ALU_GPREG10;
1415 
1416     aluParams[6].AluOpcode = MHW_MI_ALU_AND;
1417 
1418     aluParams[7].AluOpcode = MHW_MI_ALU_STORE;
1419     aluParams[7].Operand1 = MHW_MI_ALU_GPREG11;
1420     aluParams[7].Operand2 = MHW_MI_ALU_ACCU;
1421 
1422     // Store inverse of R10 (-1 --> continue, 0 --> terminate) to R12
1423     aluParams[8].AluOpcode = MHW_MI_ALU_STOREINV;
1424     aluParams[8].Operand1 = MHW_MI_ALU_GPREG12;
1425     aluParams[8].Operand2 = MHW_MI_ALU_GPREG10;
1426 
1427     // AND R9 (new tracker tag) and R12 and store in R13
1428     aluParams[9].AluOpcode = MHW_MI_ALU_LOAD;
1429     aluParams[9].Operand1 = MHW_MI_ALU_SRCA;
1430     aluParams[9].Operand2 = MHW_MI_ALU_GPREG9;
1431 
1432     aluParams[10].AluOpcode = MHW_MI_ALU_LOAD;
1433     aluParams[10].Operand1 = MHW_MI_ALU_SRCB;
1434     aluParams[10].Operand2 = MHW_MI_ALU_GPREG12;
1435 
1436     aluParams[11].AluOpcode = MHW_MI_ALU_AND;
1437 
1438     aluParams[12].AluOpcode = MHW_MI_ALU_STORE;
1439     aluParams[12].Operand1 = MHW_MI_ALU_GPREG13;
1440     aluParams[12].Operand2 = MHW_MI_ALU_ACCU;
1441 
1442     // ADD R11 and R13 and store in R15
1443     aluParams[13].AluOpcode = MHW_MI_ALU_LOAD;
1444     aluParams[13].Operand1 = MHW_MI_ALU_SRCA;
1445     aluParams[13].Operand2 = MHW_MI_ALU_GPREG11;
1446 
1447     aluParams[14].AluOpcode = MHW_MI_ALU_LOAD;
1448     aluParams[14].Operand1 = MHW_MI_ALU_SRCB;
1449     aluParams[14].Operand2 = MHW_MI_ALU_GPREG13;
1450 
1451     aluParams[15].AluOpcode = MHW_MI_ALU_ADD;
1452 
1453     aluParams[16].AluOpcode = MHW_MI_ALU_STORE;
1454     aluParams[16].Operand1 = MHW_MI_ALU_GPREG15;
1455     aluParams[16].Operand2 = MHW_MI_ALU_ACCU;
1456 
1457     mathParams.pAluPayload = aluParams;
1458     mathParams.dwNumAluParams = 17;
1459     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiMathCmd(cmdBuffer, &mathParams));
1460 
1461     // Store R15 to trackerResource
1462     MOS_ZeroMemory(&storeRegMemParams, sizeof(storeRegMemParams));
1463     state->renderHal->trackerProducer.GetLatestTrackerResource(state->renderHal->currentTrackerIndex,
1464                                             &storeRegMemParams.presStoreBuffer,
1465                                             &storeRegMemParams.dwOffset);
1466     storeRegMemParams.dwRegister = offsets->gprOffset+ 8 * 15;
1467     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegMemParams));
1468 
1469     //store R6 to synclocation
1470     MOS_ZeroMemory(&storeRegMemParams, sizeof(storeRegMemParams));
1471     storeRegMemParams.presStoreBuffer = &state->renderTimeStampResource.osResource;
1472     storeRegMemParams.dwOffset = syncOffset + sizeof(uint64_t);
1473     storeRegMemParams.dwRegister = offsets->gprOffset + 8 * 7;
1474     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegMemParams));
1475     storeRegMemParams.presStoreBuffer = &state->renderTimeStampResource.osResource;
1476     storeRegMemParams.dwOffset = syncOffset + sizeof(uint64_t) + 4;
1477     storeRegMemParams.dwRegister = offsets->gprOffset + 4 + 8 * 7 ;
1478     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegMemParams));
1479 
1480     // Insert a pipe control for synchronization
1481     pipeCtrlParams = g_cRenderHal_InitPipeControlParams;
1482     pipeCtrlParams.dwPostSyncOp = MHW_FLUSH_NOWRITE;
1483     pipeCtrlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
1484     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddPipeControl(cmdBuffer, nullptr, &pipeCtrlParams));
1485 
1486     pipeCtrlParams.dwFlushMode = MHW_FLUSH_READ_CACHE;
1487     CM_CHK_MOSSTATUS_GOTOFINISH(mhwMiInterface->AddPipeControl(cmdBuffer, nullptr, &pipeCtrlParams));
1488 
1489 finish:
1490     return eStatus;
1491 };
1492 
HalCm_GetNumCmdBuffers(PMOS_INTERFACE osInterface,uint32_t maxTaskNumber)1493 uint32_t HalCm_GetNumCmdBuffers(PMOS_INTERFACE osInterface, uint32_t maxTaskNumber)
1494 {
1495     UNUSED(maxTaskNumber);
1496     return 0;
1497 }
1498 
HalCm_GetSipBinary(PCM_HAL_STATE state)1499 MOS_STATUS HalCm_GetSipBinary(PCM_HAL_STATE state)
1500 {
1501     UNUSED(state);
1502     // Function not implemented on Linux, just return success for sanity check
1503     return MOS_STATUS_SUCCESS;
1504 }
1505 
HalCm_SetupSipSurfaceState(PCM_HAL_STATE state,PCM_HAL_INDEX_PARAM indexParam,int32_t bindingTable)1506 MOS_STATUS HalCm_SetupSipSurfaceState(
1507     PCM_HAL_STATE               state,
1508     PCM_HAL_INDEX_PARAM         indexParam,
1509     int32_t                     bindingTable)
1510 {
1511     UNUSED(state);
1512     UNUSED(indexParam);
1513     UNUSED(bindingTable);
1514     // Function not implemented on Linux, just return success for sanity check
1515     return MOS_STATUS_SUCCESS;
1516 }
1517 
1518 //!
1519 //! \brief    Prepare virtual engine hint parametere
1520 //! \details  Prepare virtual engine hint parameter for CCS node
1521 //! \param    PCM_HAL_STATE state
1522 //!           [in] Pointer to CM_HAL_STATE Structure
1523 //! \param    bool bScalable
1524 //!           [in] is scalable pipe or single pipe
1525 //! \param    PMOS_VIRTUALENGINE_HINT_PARAMS pVeHintParam
1526 //!           [out] Pointer to prepared VE hint parameter struct
1527 //! \return   MOS_STATUS
1528 //!
HalCm_PrepareVEHintParam(PCM_HAL_STATE state,bool bScalable,PMOS_VIRTUALENGINE_HINT_PARAMS pVeHintParam)1529 MOS_STATUS HalCm_PrepareVEHintParam(
1530     PCM_HAL_STATE                  state,
1531     bool                           bScalable,
1532     PMOS_VIRTUALENGINE_HINT_PARAMS pVeHintParam)
1533 {
1534     return MOS_STATUS_UNIMPLEMENTED;
1535 }
1536 
1537 
1538 //!
1539 //! \brief    Decompress the surface
1540 //! \details  Decompress the media compressed surface
1541 //! \param    PCM_HAL_STATE state
1542 //!           [in] Pointer to CM_HAL_STATE Structure
1543 //! \param    PCM_HAL_KERNEL_ARG_PARAM argParam
1544 //!           [in]Pointer to HAL cm kernel argrument parameter
1545 //! \param    uint32_t threadIndex
1546 //!           [in] is used to get index of surface array
1547 //! \return   MOS_STATUS
1548 //!
HalCm_DecompressSurface(PCM_HAL_STATE state,PCM_HAL_KERNEL_ARG_PARAM argParam,uint32_t threadIndex)1549 MOS_STATUS HalCm_DecompressSurface(
1550     PCM_HAL_STATE              state,
1551     PCM_HAL_KERNEL_ARG_PARAM   argParam,
1552     uint32_t                   threadIndex)
1553 {
1554     MOS_STATUS                 eStatus = MOS_STATUS_SUCCESS;
1555     uint32_t                   handle = 0;
1556     uint8_t                    *src = nullptr;
1557     PCM_HAL_SURFACE2D_ENTRY    pEntry = nullptr;
1558     PMOS_RESOURCE              pOsResource = nullptr;
1559     PMOS_INTERFACE             pOsInterface = nullptr;
1560     GMM_RESOURCE_FLAG          GmmFlags = { 0 };
1561 
1562     //Get the index of  surface array handle from kernel data
1563     CM_ASSERT(argParam->unitSize == sizeof(handle));
1564     src = argParam->firstValue + (threadIndex * argParam->unitSize);
1565     handle = *((uint32_t *)src) & CM_SURFACE_MASK;
1566     if (handle == CM_NULL_SURFACE)
1567     {
1568         eStatus = MOS_STATUS_SUCCESS;
1569         goto finish;
1570     }
1571 
1572     pEntry = &state->umdSurf2DTable[handle];
1573     pOsResource = &pEntry->osResource;
1574     pOsInterface = state->osInterface;
1575 
1576     if (pOsResource->pGmmResInfo)
1577     {
1578         GmmFlags = pOsResource->pGmmResInfo->GetResFlags();
1579         if (GmmFlags.Gpu.MMC || pOsResource->pGmmResInfo->IsMediaMemoryCompressed(0))
1580         {
1581             MOS_OS_ASSERT(pOsInterface);
1582             pOsInterface->pfnDecompResource(pOsInterface, pOsResource);
1583         }
1584     }
1585 
1586 finish:
1587     return eStatus;
1588 }
1589 
HalCm_SurfaceSync(PCM_HAL_STATE pState,PMOS_SURFACE pSurface,bool bReadSync)1590 MOS_STATUS HalCm_SurfaceSync(
1591     PCM_HAL_STATE                pState,
1592     PMOS_SURFACE                 pSurface,
1593     bool                         bReadSync )
1594 {
1595     UNUSED(pState);
1596     UNUSED(pSurface);
1597     UNUSED(bReadSync);
1598 
1599     return MOS_STATUS_SUCCESS;
1600 }
1601