1 /*
2 * Copyright (c) 2019-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file mos_graphicsresource_specific_next.cpp
24 //! \brief Container class for the linux/Android specfic graphic resource
25 //!
26
27 #include "mos_defs.h"
28 #include "mos_util_debug.h"
29
30 #include "mos_graphicsresource_specific_next.h"
31 #include "mos_context_specific_next.h"
32 #include "memory_policy_manager.h"
33
GraphicsResourceSpecificNext()34 GraphicsResourceSpecificNext::GraphicsResourceSpecificNext()
35 {
36 MOS_OS_FUNCTION_ENTER;
37 }
38
~GraphicsResourceSpecificNext()39 GraphicsResourceSpecificNext::~GraphicsResourceSpecificNext()
40 {
41 MOS_OS_FUNCTION_ENTER;
42 }
43
ResourceIsNull()44 bool GraphicsResourceSpecificNext::ResourceIsNull()
45 {
46 return ((m_bo == nullptr)
47 #if (_DEBUG || _RELEASE_INTERNAL)
48 && ((m_pData == nullptr) )
49 #endif // (_DEBUG || _RELEASE_INTERNAL)
50 );
51
52 }
53
Allocate(OsContextNext * osContextPtr,CreateParams & params)54 MOS_STATUS GraphicsResourceSpecificNext::Allocate(OsContextNext* osContextPtr, CreateParams& params)
55 {
56 MOS_OS_FUNCTION_ENTER;
57
58 if (osContextPtr == nullptr)
59 {
60 MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
61 return MOS_STATUS_INVALID_HANDLE;
62 }
63
64 if (osContextPtr->GetOsContextValid() == false)
65 {
66 MOS_OS_ASSERTMESSAGE("The OS context got is not valid.");
67 return MOS_STATUS_INVALID_HANDLE;
68 }
69
70 OsContextSpecificNext *pOsContextSpecific = static_cast<OsContextSpecificNext *>(osContextPtr);
71
72 GMM_CLIENT_CONTEXT *gmmClientContext = pOsContextSpecific->GetGmmClientContext();
73 if (nullptr == gmmClientContext)
74 {
75 MOS_OS_ASSERTMESSAGE("Get GMM Client Context failed.");
76 return MOS_STATUS_INVALID_HANDLE;
77 }
78
79 MOS_STATUS status = MOS_STATUS_SUCCESS;
80 uint32_t tileFormatLinux = TILING_NONE;
81 uint32_t alignedHeight = params.m_height;
82 uint32_t bufHeight = params.m_height;
83 GMM_RESOURCE_TYPE resourceType = RESOURCE_2D;
84 int32_t mem_type = MOS_MEMPOOL_VIDEOMEMORY;
85
86 GMM_RESCREATE_PARAMS gmmParams;
87 MosUtilities::MosZeroMemory(&gmmParams, sizeof(gmmParams));
88
89 gmmParams.Usage = params.m_gmmResUsageType;
90
91 switch (params.m_type)
92 {
93 case MOS_GFXRES_BUFFER:
94 case MOS_GFXRES_SCRATCH:
95 gmmParams.Type = RESOURCE_BUFFER;
96 gmmParams.Flags.Gpu.State = true;
97 alignedHeight = 1;
98 break;
99
100 case MOS_GFXRES_2D:
101 gmmParams.Type = RESOURCE_2D;
102 gmmParams.Flags.Gpu.Video = true;
103 break;
104
105 case MOS_GFXRES_VOLUME:
106 gmmParams.Type = RESOURCE_3D;
107 gmmParams.Flags.Gpu.Video = true;
108 gmmParams.Depth = params.m_depth;
109 break;
110
111 default:
112 MOS_OS_ASSERTMESSAGE("Unknown surface type");
113 return MOS_STATUS_UNKNOWN;
114 }
115
116 // Create GmmResourceInfo
117 gmmParams.Format = MosInterface::MosFmtToGmmFmt(params.m_format);
118 if (gmmParams.Format == GMM_FORMAT_INVALID)
119 {
120 MOS_OS_ASSERTMESSAGE("Unsupported format");
121 return MOS_STATUS_UNIMPLEMENTED;
122 }
123 gmmParams.BaseWidth = params.m_width;
124 gmmParams.BaseHeight = alignedHeight;
125 gmmParams.ArraySize = 1;
126
127 MOS_TILE_TYPE tileformat = params.m_tileType;
128 MOS_OS_NORMALMESSAGE("tilemode: tileformat = %d for %s, tileModeByForce = %d", tileformat, params.m_name.c_str(), params.m_tileModeByForce);
129 switch (tileformat)
130 {
131 case MOS_TILE_Y:
132 tileFormatLinux = TILING_Y;
133 if (params.m_isCompressible &&
134 MEDIA_IS_SKU(pOsContextSpecific->GetSkuTable(), FtrE2ECompression) &&
135 MEDIA_IS_SKU(pOsContextSpecific->GetSkuTable(), FtrCompressibleSurfaceDefault))
136 {
137 gmmParams.Flags.Gpu.MMC = 1;
138
139 if (params.m_compressionMode == MOS_MMC_RC)
140 {
141 gmmParams.Flags.Info.MediaCompressed = 0;
142 gmmParams.Flags.Info.RenderCompressed = 1;
143 }
144 else
145 {
146 gmmParams.Flags.Info.MediaCompressed = 1;
147 gmmParams.Flags.Info.RenderCompressed = 0;
148 }
149
150 gmmParams.Flags.Gpu.CCS = 1;
151 gmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
152 gmmParams.Flags.Gpu.RenderTarget = 1;
153
154 if(MEDIA_IS_SKU(pOsContextSpecific->GetSkuTable(), FtrFlatPhysCCS))
155 {
156 gmmParams.Flags.Gpu.UnifiedAuxSurface = 0;
157 }
158 }
159 SetTileModebyForce(gmmParams, params.m_tileModeByForce);
160 break;
161 case MOS_TILE_X:
162 gmmParams.Flags.Info.TiledX = true;
163 tileFormatLinux = TILING_X;
164 break;
165 default:
166 gmmParams.Flags.Info.Linear = true;
167 tileFormatLinux = TILING_NONE;
168 }
169
170 if (nullptr != params.m_pSystemMemory)
171 {
172 // If user provides a system memory pointer, the gfx resource is backed
173 // by the system memory pages. The resource is required to be linear.
174 gmmParams.Flags.Info.Linear = true;
175 gmmParams.Flags.Info.Cacheable = true;
176 gmmParams.NoGfxMemory = true;
177 GMM_RESOURCE_INFO *tmpGmmResInfoPtr = pOsContextSpecific
178 ->GetGmmClientContext()->CreateResInfoObject(&gmmParams);
179 if (tmpGmmResInfoPtr == nullptr)
180 {
181 MOS_OS_ASSERTMESSAGE("Create GmmResInfo failed");
182 return MOS_STATUS_UNKNOWN;
183 }
184
185 gmmParams.ExistingSysMemSize = GFX_ULONG_CAST(tmpGmmResInfoPtr->GetSizeSurface());
186 gmmParams.pExistingSysMem = (GMM_VOIDPTR64)params.m_pSystemMemory;
187 gmmParams.NoGfxMemory = false;
188 gmmParams.Flags.Info.ExistingSysMem = true;
189
190 pOsContextSpecific->GetGmmClientContext()
191 ->DestroyResInfoObject(tmpGmmResInfoPtr);
192 }
193 else
194 {
195 gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(pOsContextSpecific->GetSkuTable(), FtrLocalMemory);
196 }
197
198 GMM_RESOURCE_INFO* gmmResourceInfoPtr = pOsContextSpecific->GetGmmClientContext()->CreateResInfoObject(&gmmParams);
199
200 if (gmmResourceInfoPtr == nullptr)
201 {
202 MOS_OS_ASSERTMESSAGE("Get gmmResourceInfoPtr failed.");
203 return MOS_STATUS_INVALID_PARAMETER;
204 }
205
206 switch (gmmResourceInfoPtr->GetTileType())
207 {
208 case GMM_TILED_X:
209 tileformat = MOS_TILE_X;
210 tileFormatLinux = TILING_X;
211 break;
212 case GMM_TILED_Y:
213 tileformat = MOS_TILE_Y;
214 tileFormatLinux = TILING_Y;
215 break;
216 case GMM_NOT_TILED:
217 tileformat = MOS_TILE_LINEAR;
218 tileFormatLinux = TILING_NONE;
219 break;
220 default:
221 tileformat = MOS_TILE_Y;
222 tileFormatLinux = TILING_Y;
223 break;
224 }
225
226 if (params.m_tileType== MOS_TILE_Y)
227 {
228 gmmResourceInfoPtr->SetMmcMode((GMM_RESOURCE_MMC_INFO)params.m_compressionMode, 0);
229 }
230
231 if(!params.m_pSystemMemory)
232 {
233 MemoryPolicyParameter memPolicyPar;
234 MOS_ZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter));
235
236 memPolicyPar.skuTable = pOsContextSpecific->GetSkuTable();
237 memPolicyPar.waTable = pOsContextSpecific->GetWaTable();
238 memPolicyPar.resInfo = gmmResourceInfoPtr;
239 memPolicyPar.resName = params.m_name.c_str();
240 memPolicyPar.preferredMemType = params.m_memType;
241 memPolicyPar.isServer = PLATFORM_INFORMATION_IS_SERVER & mos_get_platform_information(pOsContextSpecific->GetBufMgr());
242
243 mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
244 }
245
246 uint32_t bufPitch = GFX_ULONG_CAST(gmmResourceInfoPtr->GetRenderPitch());
247 uint32_t bufSize = GFX_ULONG_CAST(gmmResourceInfoPtr->GetSizeSurface());
248 bufHeight = gmmResourceInfoPtr->GetBaseHeight();
249 MOS_LINUX_BO* boPtr = nullptr;
250
251 char bufName[m_maxBufNameLength];
252 MosUtilities::MosSecureStrcpy(bufName, m_maxBufNameLength, params.m_name.c_str());
253
254 unsigned int patIndex = MosInterface::GetPATIndexFromGmm(gmmClientContext, gmmResourceInfoPtr);
255 bool isCpuCacheable = gmmResourceInfoPtr->GetResFlags().Info.Cacheable;
256
257 MOS_TraceEventExt(EVENT_RESOURCE_ALLOCATE, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
258 if (nullptr != params.m_pSystemMemory)
259 {
260 struct mos_drm_bo_alloc_userptr alloc_uptr;
261 alloc_uptr.name = bufName;
262 alloc_uptr.addr = params.m_pSystemMemory;
263 alloc_uptr.tiling_mode = tileFormatLinux;
264 alloc_uptr.stride = bufPitch;
265 alloc_uptr.size = bufSize;
266 alloc_uptr.pat_index = patIndex;
267
268 boPtr = mos_bo_alloc_userptr(pOsContextSpecific->m_bufmgr, &alloc_uptr);
269 }
270 // Only Linear and Y TILE supported
271 else if (tileFormatLinux == TILING_NONE)
272 {
273 struct mos_drm_bo_alloc alloc;
274 alloc.name = bufName;
275 alloc.size = bufSize;
276 alloc.alignment = 4096;
277 alloc.ext.mem_type = mem_type;
278 alloc.ext.pat_index = patIndex;
279 alloc.ext.cpu_cacheable = isCpuCacheable;
280 boPtr = mos_bo_alloc(pOsContextSpecific->m_bufmgr, &alloc);
281 }
282 else
283 {
284 struct mos_drm_bo_alloc_tiled alloc_tiled;
285 alloc_tiled.name = bufName;
286 alloc_tiled.x = bufPitch;
287 alloc_tiled.y = bufSize/bufPitch;
288 alloc_tiled.cpp = 1;
289 alloc_tiled.ext.tiling_mode = tileFormatLinux;
290 alloc_tiled.ext.mem_type = mem_type;
291 alloc_tiled.ext.pat_index = patIndex;
292 alloc_tiled.ext.cpu_cacheable = isCpuCacheable;
293
294 boPtr = mos_bo_alloc_tiled(pOsContextSpecific->m_bufmgr, &alloc_tiled);
295 bufPitch = (uint32_t)alloc_tiled.pitch;
296 }
297
298 m_mapped = false;
299 if (boPtr)
300 {
301 m_format = params.m_format;
302 m_width = params.m_width;
303 m_height = bufHeight;
304 m_pitch = bufPitch;
305 m_count = 0;
306 m_bo = boPtr;
307 m_name = params.m_name;
308 m_pData = (uint8_t*) boPtr->virt;
309
310 m_gmmResInfo = gmmResourceInfoPtr;
311 m_mapped = false;
312 m_mmapOperation = MOS_MMAP_OPERATION_NONE;
313
314 m_arraySize = 1;
315 m_depth = MOS_MAX(1, gmmResourceInfoPtr->GetBaseDepth());
316 m_size = (uint32_t)gmmResourceInfoPtr->GetSizeSurface();
317 m_tileType = tileformat;
318 m_tileModeGMM = (MOS_TILE_MODE_GMM)gmmResourceInfoPtr->GetTileModeSurfaceState();
319 m_isGMMTileEnabled = true;
320
321 m_compressible = gmmParams.Flags.Gpu.MMC ?
322 (gmmResourceInfoPtr->GetMmcHint(0) == GMM_MMC_HINT_ON) : false;
323 m_isCompressed = gmmResourceInfoPtr->IsMediaMemoryCompressed(0);
324 m_compressionMode = (MOS_RESOURCE_MMC_MODE)gmmResourceInfoPtr->GetMmcMode(0);
325 m_memObjCtrlState = MosInterface::GetCachePolicyMemoryObject(pOsContextSpecific->GetGmmClientContext(), params.m_mocsMosResUsageType);
326
327 MOS_OS_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource), tile encoding %d.", bufSize, params.m_width, bufHeight, m_tileModeGMM);
328
329 struct {
330 uint32_t m_handle;
331 uint32_t m_resFormat;
332 uint32_t m_baseWidth;
333 uint32_t m_baseHeight;
334 uint32_t m_pitch;
335 uint32_t m_size;
336 uint32_t m_resTileType;
337 GMM_RESOURCE_FLAG m_resFlag;
338 uint32_t m_reserve;
339 } eventData;
340
341 eventData.m_handle = boPtr->handle;
342 eventData.m_baseWidth = m_width;
343 eventData.m_baseHeight = m_height;
344 eventData.m_pitch = m_pitch;
345 eventData.m_size = m_size;
346 eventData.m_resFormat = m_format;
347 eventData.m_resTileType = m_tileType;
348 eventData.m_resFlag = gmmResourceInfoPtr->GetResFlags();
349 eventData.m_reserve = 0;
350 MOS_TraceEventExt(EVENT_RESOURCE_ALLOCATE,
351 EVENT_TYPE_INFO,
352 &eventData,
353 sizeof(eventData),
354 params.m_name.c_str(),
355 params.m_name.size() + 1);
356 }
357 else
358 {
359 MOS_OS_ASSERTMESSAGE("Fail to Alloc %7d bytes (%d x %d resource).",bufSize, params.m_width, params.m_height);
360 status = MOS_STATUS_NO_SPACE;
361 }
362 MOS_TraceEventExt(EVENT_RESOURCE_ALLOCATE, EVENT_TYPE_END, &status, sizeof(status), nullptr, 0);
363
364 m_memAllocCounterGfx++;
365 return status;
366 }
367
Free(OsContextNext * osContextPtr,uint32_t freeFlag)368 void GraphicsResourceSpecificNext::Free(OsContextNext* osContextPtr, uint32_t freeFlag)
369 {
370 MOS_OS_FUNCTION_ENTER;
371
372 MOS_UNUSED(osContextPtr);
373 MOS_UNUSED(freeFlag);
374
375 OsContextSpecificNext *pOsContextSpecific = static_cast<OsContextSpecificNext *>(osContextPtr);
376
377 MOS_LINUX_BO* boPtr = m_bo;
378
379 if (boPtr)
380 {
381 AuxTableMgr *auxTableMgr = pOsContextSpecific->GetAuxTableMgr();
382 if (auxTableMgr)
383 {
384 auxTableMgr->UnmapResource(m_gmmResInfo, boPtr);
385 }
386 mos_bo_unreference(boPtr);
387 m_bo = nullptr;
388 if (nullptr != m_gmmResInfo)
389 {
390 pOsContextSpecific->GetGmmClientContext()->DestroyResInfoObject(m_gmmResInfo);
391 m_gmmResInfo = nullptr;
392 m_memAllocCounterGfx--;
393 }
394 }
395 return;
396 }
397
IsEqual(GraphicsResourceNext * toCompare)398 bool GraphicsResourceSpecificNext::IsEqual(GraphicsResourceNext* toCompare)
399 {
400 if (toCompare == nullptr)
401 {
402 return false;
403 }
404
405 GraphicsResourceSpecificNext *resSpecificPtr = static_cast<GraphicsResourceSpecificNext *>(toCompare);
406
407 return (m_bo == resSpecificPtr->m_bo);
408 }
409
IsValid()410 bool GraphicsResourceSpecificNext::IsValid()
411 {
412 return (m_bo != nullptr);
413 }
414
ConvertToMosResource(MOS_RESOURCE * pMosResource)415 MOS_STATUS GraphicsResourceSpecificNext::ConvertToMosResource(MOS_RESOURCE* pMosResource)
416 {
417 if (pMosResource == nullptr)
418 {
419 return MOS_STATUS_INVALID_PARAMETER;
420 }
421
422 pMosResource->Format = m_format;
423 pMosResource->iWidth = m_width;
424 pMosResource->iHeight = m_height;
425 pMosResource->iSize = m_size;
426 pMosResource->iPitch = m_pitch;
427 pMosResource->iDepth = m_depth;
428 pMosResource->TileType = m_tileType;
429 pMosResource->TileModeGMM = m_tileModeGMM;
430 pMosResource->bGMMTileEnabled = m_isGMMTileEnabled;
431 pMosResource->iCount = 0;
432 pMosResource->pData = m_pData;
433 pMosResource->bufname = m_name.c_str();
434 pMosResource->bo = m_bo;
435 pMosResource->bMapped = m_mapped;
436 pMosResource->MmapOperation = m_mmapOperation;
437 pMosResource->pGmmResInfo = m_gmmResInfo;
438
439 pMosResource->user_provided_va = m_userProvidedVA;
440
441 pMosResource->memObjCtrlState = m_memObjCtrlState;
442 pMosResource->mocsMosResUsageType = m_mocsMosResUsageType;
443
444 pMosResource->pGfxResourceNext = this;
445
446 return MOS_STATUS_SUCCESS;
447 }
448
Lock(OsContextNext * osContextPtr,LockParams & params)449 void* GraphicsResourceSpecificNext::Lock(OsContextNext* osContextPtr, LockParams& params)
450 {
451 MOS_OS_FUNCTION_ENTER;
452
453 if (osContextPtr == nullptr)
454 {
455 MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
456 return nullptr;
457 }
458
459 if (osContextPtr ->GetOsContextValid() == false)
460 {
461 MOS_OS_ASSERTMESSAGE("The OS context got is not valid.");
462 return nullptr;
463 }
464
465 OsContextSpecificNext *pOsContextSpecific = static_cast<OsContextSpecificNext *>(osContextPtr);
466
467 void* dataPtr = nullptr;
468 MOS_LINUX_BO* boPtr = m_bo;
469
470 if (boPtr)
471 {
472 // Do decompression for a compressed surface before lock
473 const auto pGmmResInfo = m_gmmResInfo;
474 MOS_OS_ASSERT(pGmmResInfo);
475 GMM_RESOURCE_FLAG GmmFlags = pGmmResInfo->GetResFlags();
476
477 if (!params.m_noDecompress &&
478 (((GmmFlags.Gpu.MMC || GmmFlags.Gpu.CCS) && GmmFlags.Info.MediaCompressed) ||
479 pGmmResInfo->IsMediaMemoryCompressed(0)))
480 {
481 MOS_RESOURCE mosResource = {};
482 ConvertToMosResource(&mosResource);
483
484 MosDecompression *mosDecompression = pOsContextSpecific->GetMosDecompression();
485 if (nullptr == mosDecompression)
486 {
487 MOS_OS_ASSERTMESSAGE("mosDecompression is NULL.");
488 return nullptr;
489 }
490 mosDecompression->MemoryDecompress(&mosResource);
491 }
492
493 if(false == m_mapped)
494 {
495 if (pOsContextSpecific->IsAtomSoc())
496 {
497 mos_bo_map_gtt(boPtr);
498 }
499 else
500 {
501 if (m_tileType != MOS_TILE_LINEAR && !params.m_tileAsTiled)
502 {
503 if (pOsContextSpecific->UseSwSwizzling())
504 {
505 mos_bo_map(boPtr, ( OSKM_LOCKFLAG_WRITEONLY & params.m_writeRequest ));
506 m_mmapOperation = MOS_MMAP_OPERATION_MMAP;
507 if (m_systemShadow == nullptr)
508 {
509 m_systemShadow = (uint8_t *)MOS_AllocMemory(boPtr->size);
510 MOS_OS_CHECK_CONDITION((m_systemShadow == nullptr), "Failed to allocate shadow surface", nullptr);
511 }
512 if (m_systemShadow)
513 {
514 int32_t flags = pOsContextSpecific->GetTileYFlag() ? 0 : 1;
515 uint64_t surfSize = m_gmmResInfo->GetSizeMainSurface();
516 MOS_OS_CHECK_CONDITION((m_tileType != MOS_TILE_Y), "Unsupported tile type", nullptr);
517 MOS_OS_CHECK_CONDITION((boPtr->size <= 0 || m_pitch <= 0), "Invalid BO size or pitch", nullptr);
518 MosUtilities::MosSwizzleData((uint8_t*)boPtr->virt, m_systemShadow,
519 MOS_TILE_Y, MOS_TILE_LINEAR,
520 (int32_t)(surfSize / m_pitch), m_pitch, flags);
521 }
522 }
523 else
524 {
525 mos_bo_map_gtt(boPtr);
526 m_mmapOperation = MOS_MMAP_OPERATION_MMAP_GTT;
527 }
528 }
529 else if (params.m_uncached)
530 {
531 mos_bo_map_wc(boPtr);
532 m_mmapOperation = MOS_MMAP_OPERATION_MMAP_WC;
533 }
534 else
535 {
536 mos_bo_map(boPtr, ( OSKM_LOCKFLAG_WRITEONLY & params.m_writeRequest ));
537 m_mmapOperation = MOS_MMAP_OPERATION_MMAP;
538 }
539 }
540 m_mapped = true;
541 m_pData = m_systemShadow ? m_systemShadow : (uint8_t *)boPtr->virt;
542 }
543
544 dataPtr = m_pData;
545 }
546
547 MOS_OS_ASSERT(dataPtr);
548 return dataPtr;
549 }
550
Unlock(OsContextNext * osContextPtr)551 MOS_STATUS GraphicsResourceSpecificNext::Unlock(OsContextNext* osContextPtr)
552 {
553 MOS_OS_FUNCTION_ENTER;
554
555 if (osContextPtr == nullptr)
556 {
557 MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
558 return MOS_STATUS_INVALID_HANDLE;
559 }
560
561 if (osContextPtr ->GetOsContextValid() == false)
562 {
563 MOS_OS_ASSERTMESSAGE("The OS context got is not valid.");
564 return MOS_STATUS_INVALID_HANDLE;
565 }
566
567 OsContextSpecificNext *pOsContextSpecific = static_cast<OsContextSpecificNext *>(osContextPtr);
568
569 MOS_LINUX_BO* boPtr = m_bo;
570 if (boPtr)
571 {
572 if (m_mapped)
573 {
574 if (pOsContextSpecific->IsAtomSoc())
575 {
576 mos_bo_unmap_gtt(boPtr);
577 }
578 else
579 {
580
581 if (m_systemShadow)
582 {
583 int32_t flags = pOsContextSpecific->GetTileYFlag() ? 0 : 1;
584 uint64_t surfSize = m_gmmResInfo->GetSizeMainSurface();
585 MosUtilities::MosSwizzleData(m_systemShadow, (uint8_t*)boPtr->virt,
586 MOS_TILE_LINEAR, MOS_TILE_Y,
587 (int32_t)(surfSize / m_pitch), m_pitch, flags);
588 MOS_FreeMemory(m_systemShadow);
589 m_systemShadow = nullptr;
590 }
591
592 switch(m_mmapOperation)
593 {
594 case MOS_MMAP_OPERATION_MMAP_GTT:
595 mos_bo_unmap_gtt(boPtr);
596 break;
597 case MOS_MMAP_OPERATION_MMAP_WC:
598 mos_bo_unmap_wc(boPtr);
599 break;
600 case MOS_MMAP_OPERATION_MMAP:
601 mos_bo_unmap(boPtr);
602 break;
603 default:
604 MOS_OS_ASSERTMESSAGE("Invalid mmap operation type");
605 break;
606 }
607 }
608
609 m_mapped = false;
610 m_mmapOperation = MOS_MMAP_OPERATION_NONE;
611
612 boPtr->virt = nullptr;
613 m_bo = boPtr;
614 }
615
616 m_pData = nullptr;
617 }
618
619 return MOS_STATUS_SUCCESS;
620 }
621
AllocateExternalResource(MOS_STREAM_HANDLE streamState,PMOS_ALLOC_GFXRES_PARAMS params,MOS_RESOURCE_HANDLE & resource)622 MOS_STATUS GraphicsResourceSpecificNext::AllocateExternalResource(
623 MOS_STREAM_HANDLE streamState,
624 PMOS_ALLOC_GFXRES_PARAMS params,
625 MOS_RESOURCE_HANDLE& resource)
626 {
627 MOS_OS_FUNCTION_ENTER;
628
629 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
630
631 MOS_OS_CHK_NULL_RETURN(resource);
632 MOS_OS_CHK_NULL_RETURN(streamState);
633 MOS_OS_CHK_NULL_RETURN(streamState->osDeviceContext);
634
635 const char *bufname = params->pBufName;;
636 int32_t iSize = 0;
637 int32_t iPitch = 0;
638 MOS_LINUX_BO *bo = nullptr;
639 MOS_TILE_TYPE tileformat = params->TileType;
640 uint32_t tileformat_linux = TILING_NONE;
641 int32_t iHeight = params->dwHeight;
642 int32_t iAlignedHeight = 0;
643 GMM_RESCREATE_PARAMS gmmParams;
644 GMM_RESOURCE_INFO *gmmResourceInfo = nullptr;
645 GMM_RESOURCE_TYPE resourceType = RESOURCE_2D;
646 unsigned int patIndex = PAT_INDEX_INVALID;
647 bool isCpuCacheable = true;
648
649 MosUtilities::MosZeroMemory(&gmmParams, sizeof(gmmParams));
650
651 MOS_OS_CHK_NULL_RETURN(streamState->perStreamParameters);
652 auto perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;
653
654 gmmParams.Usage = MosInterface::GetGmmResourceUsageType(params->ResUsageType);
655
656 switch (params->Format)
657 {
658 case Format_Buffer:
659 case Format_RAW:
660 resourceType = RESOURCE_BUFFER;
661 iAlignedHeight = 1;
662 //indicate buffer Restriction is Vertex.
663 gmmParams.Flags.Gpu.State = true;
664 break;
665 case Format_L8:
666 case Format_L16:
667 case Format_STMM:
668 case Format_AI44:
669 case Format_IA44:
670 case Format_R5G6B5:
671 case Format_R8G8B8:
672 case Format_X8R8G8B8:
673 case Format_A8R8G8B8:
674 case Format_X8B8G8R8:
675 case Format_A8B8G8R8:
676 case Format_R32S:
677 case Format_R32F:
678 case Format_V8U8:
679 case Format_YUY2:
680 case Format_UYVY:
681 case Format_P8:
682 case Format_A8:
683 case Format_AYUV:
684 case Format_NV12:
685 case Format_NV21:
686 case Format_YV12:
687 case Format_Buffer_2D:
688 case Format_R32U:
689 case Format_444P:
690 case Format_422H:
691 case Format_422V:
692 case Format_IMC3:
693 case Format_411P:
694 case Format_411R:
695 case Format_RGBP:
696 case Format_BGRP:
697 case Format_R16U:
698 case Format_R8U:
699 case Format_R8UN:
700 case Format_P010:
701 case Format_P016:
702 case Format_Y216:
703 case Format_Y416:
704 case Format_P208:
705 case Format_Y210:
706 case Format_Y410:
707 case Format_R16F:
708 resourceType = RESOURCE_2D;
709 //indicate buffer Restriction is Planar surface restrictions.
710 gmmParams.Flags.Gpu.Video = true;
711 break;
712 default:
713 MOS_OS_ASSERTMESSAGE("Unsupported format");
714 eStatus = MOS_STATUS_UNIMPLEMENTED;
715 return eStatus;
716 }
717
718 // Create GmmResourceInfo
719 gmmParams.BaseWidth = params->dwWidth;
720 gmmParams.BaseHeight = iAlignedHeight;
721 gmmParams.ArraySize = 1;
722 gmmParams.Type = resourceType;
723 gmmParams.Format = MosInterface::MosFmtToGmmFmt(params->Format);
724
725 MOS_OS_CHECK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID,
726 "Unsupported format",
727 MOS_STATUS_UNKNOWN);
728
729 switch (tileformat)
730 {
731 case MOS_TILE_Y:
732 gmmParams.Flags.Gpu.MMC = params->bIsCompressible;
733 tileformat_linux = TILING_Y;
734 break;
735 case MOS_TILE_X:
736 gmmParams.Flags.Info.TiledX = true;
737 tileformat_linux = TILING_X;
738 break;
739 default:
740 gmmParams.Flags.Info.Linear = true;
741 tileformat_linux = TILING_NONE;
742 }
743 gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&perStreamParameters->m_skuTable, FtrLocalMemory);
744
745 MOS_OS_CHK_NULL_RETURN(perStreamParameters->pGmmClientContext);
746 resource->pGmmResInfo = gmmResourceInfo = perStreamParameters->pGmmClientContext->CreateResInfoObject(&gmmParams);
747
748 MOS_OS_CHK_NULL_RETURN(gmmResourceInfo);
749
750 switch (gmmResourceInfo->GetTileType())
751 {
752 case GMM_TILED_X:
753 tileformat = MOS_TILE_X;
754 tileformat_linux = TILING_X;
755 break;
756 case GMM_TILED_Y:
757 tileformat = MOS_TILE_Y;
758 tileformat_linux = TILING_Y;
759 break;
760 case GMM_NOT_TILED:
761 tileformat = MOS_TILE_LINEAR;
762 tileformat_linux = TILING_NONE;
763 break;
764 default:
765 tileformat = MOS_TILE_Y;
766 tileformat_linux = TILING_Y;
767 break;
768 }
769
770 if (params->TileType == MOS_TILE_Y)
771 {
772 gmmResourceInfo->SetMmcMode((GMM_RESOURCE_MMC_INFO)params->CompressionMode, 0);
773 }
774
775 iPitch = GFX_ULONG_CAST(gmmResourceInfo->GetRenderPitch());
776 iSize = GFX_ULONG_CAST(gmmResourceInfo->GetSizeSurface());
777 iHeight = gmmResourceInfo->GetBaseHeight();
778
779 patIndex = MosInterface::GetPATIndexFromGmm(perStreamParameters->pGmmClientContext, gmmResourceInfo);
780 isCpuCacheable = gmmResourceInfo->GetResFlags().Info.Cacheable;
781
782 // Only Linear and Y TILE supported
783 if (tileformat_linux == TILING_NONE)
784 {
785 struct mos_drm_bo_alloc alloc;
786 alloc.name = bufname;
787 alloc.size = iSize;
788 alloc.alignment = 4096;
789 alloc.ext.mem_type = MOS_MEMPOOL_VIDEOMEMORY;
790 alloc.ext.pat_index = patIndex;
791 alloc.ext.cpu_cacheable = isCpuCacheable;
792 bo = mos_bo_alloc(perStreamParameters->bufmgr, &alloc);
793 }
794 else
795 {
796 struct mos_drm_bo_alloc_tiled alloc_tiled;
797 alloc_tiled.name = bufname;
798 alloc_tiled.x = iPitch;
799 alloc_tiled.y = iSize / iPitch;
800 alloc_tiled.cpp = 1;
801 alloc_tiled.ext.tiling_mode = tileformat_linux;
802 alloc_tiled.ext.mem_type = MOS_MEMPOOL_VIDEOMEMORY;
803 alloc_tiled.ext.pat_index = patIndex;
804 alloc_tiled.ext.cpu_cacheable = isCpuCacheable;
805
806 bo = mos_bo_alloc_tiled(perStreamParameters->bufmgr, &alloc_tiled);
807 iPitch = (int32_t)alloc_tiled.pitch;
808 }
809
810 resource->bMapped = false;
811 if (bo)
812 {
813 resource->Format = params->Format;
814 resource->iWidth = params->dwWidth;
815 resource->iHeight = iHeight;
816 resource->iPitch = iPitch;
817 resource->iCount = 0;
818 resource->bufname = bufname;
819 resource->bo = bo;
820 resource->TileType = tileformat;
821 resource->TileModeGMM = (MOS_TILE_MODE_GMM)gmmResourceInfo->GetTileModeSurfaceState();
822 resource->bGMMTileEnabled = true;
823 resource->pData = (uint8_t *)bo->virt; //It is useful for batch buffer to fill commands
824 if (params->ResUsageType == MOS_CODEC_RESOURCE_USAGE_BEGIN_CODEC ||
825 params->ResUsageType >= MOS_HW_RESOURCE_USAGE_MEDIA_BATCH_BUFFERS)
826 {
827 resource->memObjCtrlState = MosInterface::GetCachePolicyMemoryObject(perStreamParameters->pGmmClientContext, MOS_MP_RESOURCE_USAGE_DEFAULT);
828 resource->mocsMosResUsageType = MOS_MP_RESOURCE_USAGE_DEFAULT;
829 }
830 else
831 {
832 resource->memObjCtrlState = MosInterface::GetCachePolicyMemoryObject(perStreamParameters->pGmmClientContext, params->ResUsageType);
833 resource->mocsMosResUsageType = params->ResUsageType;
834 }
835 MOS_OS_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource), tile encoding.", iSize, params->dwWidth, iHeight, resource->TileModeGMM);
836 }
837 else
838 {
839 MOS_OS_ASSERTMESSAGE("Fail to Alloc %7d bytes (%d x %d resource).", iSize, params->dwWidth, params->dwHeight);
840 eStatus = MOS_STATUS_NO_SPACE;
841 }
842
843 return eStatus;
844 }
845
FreeExternalResource(MOS_STREAM_HANDLE streamState,MOS_RESOURCE_HANDLE resource,uint32_t flag)846 MOS_STATUS GraphicsResourceSpecificNext::FreeExternalResource(
847 MOS_STREAM_HANDLE streamState,
848 MOS_RESOURCE_HANDLE resource,
849 uint32_t flag)
850 {
851 MOS_OS_FUNCTION_ENTER;
852
853 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
854
855 MOS_OS_CHK_NULL_RETURN(resource);
856 MOS_OS_CHK_NULL_RETURN(streamState);
857 MOS_OS_CHK_NULL_RETURN(streamState->osDeviceContext);
858
859 if (resource && resource->bo)
860 {
861 OsContextSpecificNext *osCtx = static_cast<OsContextSpecificNext *>(streamState->osDeviceContext);
862 if (osCtx == nullptr)
863 {
864 MOS_OS_ASSERTMESSAGE("osCtx is nullptr!");
865 return MOS_STATUS_NULL_POINTER;
866 }
867 else
868 {
869 AuxTableMgr *auxTableMgr = osCtx->GetAuxTableMgr();
870
871 // Unmap Resource from Aux Table
872 if (auxTableMgr)
873 {
874 auxTableMgr->UnmapResource(resource->pGmmResInfo, resource->bo);
875 }
876 }
877
878 mos_bo_unreference((MOS_LINUX_BO *)(resource->bo));
879
880 MOS_OS_CHK_NULL_RETURN(streamState->perStreamParameters);
881 auto perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;
882
883 if (perStreamParameters != nullptr && perStreamParameters->contextOffsetList.size())
884 {
885 MOS_CONTEXT *pOsCtx = perStreamParameters;
886 auto item_ctx = pOsCtx->contextOffsetList.begin();
887
888 for (; item_ctx != pOsCtx->contextOffsetList.end();)
889 {
890 if (item_ctx->target_bo == resource->bo)
891 {
892 item_ctx = pOsCtx->contextOffsetList.erase(item_ctx);
893 }
894 else
895 {
896 item_ctx++;
897 }
898 }
899 }
900
901 resource->bo = nullptr;
902 }
903
904 return eStatus;
905 }
906
LockExternalResource(MOS_STREAM_HANDLE streamState,MOS_RESOURCE_HANDLE resource,PMOS_LOCK_PARAMS flags)907 void* GraphicsResourceSpecificNext::LockExternalResource(
908 MOS_STREAM_HANDLE streamState,
909 MOS_RESOURCE_HANDLE resource,
910 PMOS_LOCK_PARAMS flags)
911 {
912 MOS_OS_FUNCTION_ENTER;
913
914 void *pData = nullptr;
915 if (nullptr == streamState)
916 {
917 MOS_OS_ASSERTMESSAGE("input parameter streamState is NULL.");
918 return nullptr;
919 }
920
921 if (nullptr == resource)
922 {
923 MOS_OS_ASSERTMESSAGE("input parameter resource is NULL.");
924 return nullptr;
925 }
926
927 if (streamState->perStreamParameters == nullptr)
928 {
929 MOS_OS_ASSERTMESSAGE("perStreamParameters is nullptr, skip lock");
930 return nullptr;
931 }
932 auto perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;
933 if (resource && resource->bo && resource->pGmmResInfo)
934 {
935 MOS_LINUX_BO *bo = resource->bo;
936 GMM_RESOURCE_FLAG GmmFlags = resource->pGmmResInfo->GetResFlags();
937
938 // Do decompression for a compressed surface before lock
939 if (!flags->NoDecompress &&
940 (((GmmFlags.Gpu.MMC || GmmFlags.Gpu.CCS) && GmmFlags.Info.MediaCompressed) ||
941 resource->pGmmResInfo->IsMediaMemoryCompressed(0)))
942 {
943 MosDecompression *mosDecompression = nullptr;
944 MOS_STATUS status = MosInterface::GetMosDecompressionFromStreamState(streamState, mosDecompression);
945 if (status != MOS_STATUS_SUCCESS)
946 {
947 MOS_OS_ASSERTMESSAGE("Get Mos Decompression From StreamState failed, skip lock");
948 return nullptr;
949 }
950 if (nullptr == mosDecompression)
951 {
952 MOS_OS_ASSERTMESSAGE("mosDecompression is NULL.");
953 return nullptr;
954 }
955 mosDecompression->MemoryDecompress(resource);
956 }
957
958 if (false == resource->bMapped)
959 {
960 if (perStreamParameters->bIsAtomSOC)
961 {
962 mos_bo_map_gtt(bo);
963 }
964 else
965 {
966 if (resource->TileType != MOS_TILE_LINEAR && !flags->TiledAsTiled)
967 {
968 if (perStreamParameters->bUseSwSwizzling)
969 {
970 mos_bo_map(bo, (OSKM_LOCKFLAG_WRITEONLY & flags->WriteOnly));
971 resource->MmapOperation = MOS_MMAP_OPERATION_MMAP;
972 if (resource->pSystemShadow == nullptr)
973 {
974 resource->pSystemShadow = (uint8_t *)MOS_AllocMemory(bo->size);
975 MOS_OS_CHECK_CONDITION((resource->pSystemShadow == nullptr), "Failed to allocate shadow surface", nullptr);
976 }
977 if (resource->pSystemShadow)
978 {
979 int32_t swizzleflags = perStreamParameters->bTileYFlag ? 0 : 1;
980 MOS_OS_CHECK_CONDITION((resource->TileType != MOS_TILE_Y), "Unsupported tile type", nullptr);
981 MOS_OS_CHECK_CONDITION((bo->size <= 0 || resource->iPitch <= 0), "Invalid BO size or pitch", nullptr);
982 MosUtilities::MosSwizzleData((uint8_t *)bo->virt, resource->pSystemShadow, MOS_TILE_Y, MOS_TILE_LINEAR, bo->size / resource->iPitch, resource->iPitch, swizzleflags);
983 }
984 }
985 else
986 {
987 mos_bo_map_gtt(bo);
988 resource->MmapOperation = MOS_MMAP_OPERATION_MMAP_GTT;
989 }
990 }
991 else if (flags->Uncached)
992 {
993 mos_bo_map_wc(bo);
994 resource->MmapOperation = MOS_MMAP_OPERATION_MMAP_WC;
995 }
996 else
997 {
998 mos_bo_map(bo, (OSKM_LOCKFLAG_WRITEONLY & flags->WriteOnly));
999 resource->MmapOperation = MOS_MMAP_OPERATION_MMAP;
1000 }
1001 }
1002 resource->pData = resource->pSystemShadow ? resource->pSystemShadow : (uint8_t *)bo->virt;
1003 resource->bMapped = true;
1004 }
1005
1006 pData = resource->pData;
1007 }
1008
1009 MOS_OS_ASSERT(pData);
1010 return pData;
1011 }
1012
UnlockExternalResource(MOS_STREAM_HANDLE streamState,MOS_RESOURCE_HANDLE resource)1013 MOS_STATUS GraphicsResourceSpecificNext::UnlockExternalResource(
1014 MOS_STREAM_HANDLE streamState,
1015 MOS_RESOURCE_HANDLE resource)
1016 {
1017 MOS_OS_FUNCTION_ENTER;
1018
1019 MOS_OS_CHK_NULL_RETURN(resource);
1020 MOS_OS_CHK_NULL_RETURN(streamState);
1021 MOS_OS_CHK_NULL_RETURN(streamState->osDeviceContext);
1022
1023 MOS_OS_CHK_NULL_RETURN(streamState->perStreamParameters);
1024 auto perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;
1025
1026 if (resource->bo)
1027 {
1028 if (true == resource->bMapped)
1029 {
1030 if (perStreamParameters->bIsAtomSOC)
1031 {
1032 mos_bo_unmap_gtt(resource->bo);
1033 }
1034 else
1035 {
1036 if (resource->pSystemShadow)
1037 {
1038 int32_t flags = perStreamParameters->bTileYFlag ? 0 : 1;
1039 MosUtilities::MosSwizzleData(resource->pSystemShadow, (uint8_t *)resource->bo->virt, MOS_TILE_LINEAR, MOS_TILE_Y, resource->bo->size / resource->iPitch, resource->iPitch, flags);
1040 MOS_FreeMemory(resource->pSystemShadow);
1041 resource->pSystemShadow = nullptr;
1042 }
1043
1044 switch (resource->MmapOperation)
1045 {
1046 case MOS_MMAP_OPERATION_MMAP_GTT:
1047 mos_bo_unmap_gtt(resource->bo);
1048 break;
1049 case MOS_MMAP_OPERATION_MMAP_WC:
1050 mos_bo_unmap_wc(resource->bo);
1051 break;
1052 case MOS_MMAP_OPERATION_MMAP:
1053 mos_bo_unmap(resource->bo);
1054 break;
1055 default:
1056 MOS_OS_ASSERTMESSAGE("Invalid mmap operation type");
1057 break;
1058 }
1059 }
1060 resource->bo->virt = nullptr;
1061 resource->bMapped = false;
1062 }
1063 resource->pData = nullptr;
1064 }
1065
1066 return MOS_STATUS_SUCCESS;
1067 }
1068
SetTileModebyForce(GMM_RESCREATE_PARAMS & gmmParams,MOS_TILE_MODE_GMM tileMode)1069 MOS_STATUS GraphicsResourceSpecificNext::SetTileModebyForce(GMM_RESCREATE_PARAMS &gmmParams, MOS_TILE_MODE_GMM tileMode)
1070 {
1071 if (tileMode == MOS_TILE_64_GMM)
1072 {
1073 gmmParams.Flags.Info.Tile64 = true;
1074 }
1075 else if (tileMode == MOS_TILE_4_GMM)
1076 {
1077 gmmParams.Flags.Info.Tile4 = true;
1078 }
1079 return MOS_STATUS_SUCCESS;
1080 }
1081