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 ¶m->pitch, ¶m->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