1 /*==============================================================================
2 Copyright(c) 2017 Intel Corporation
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files(the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and / or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21 ============================================================================*/
22
23 #include "Internal/Common/GmmLibInc.h"
24
25 #if(!defined(__GMM_KMD__) && !GMM_LIB_DLL_MA)
26 int32_t GmmLib::Context::RefCount = 0;
27 #endif
28
29 #ifdef GMM_LIB_DLL
30
31 // Create Mutex Object used for syncronization of ProcessSingleton Context
32 #if !GMM_LIB_DLL_MA
33 #ifdef _WIN32
34 GMM_MUTEX_HANDLE GmmLib::Context::SingletonContextSyncMutex = ::CreateMutex(NULL, false, NULL);
35 #else //_WIN32
36 GMM_MUTEX_HANDLE GmmLib::Context::SingletonContextSyncMutex = PTHREAD_MUTEX_INITIALIZER;
37 #endif // _WIN32
38 #endif //!GMM_LIB_DLL_MA
39
40 /////////////////////////////////////////////////////////////////////////////////////
41 /// GMM lib DLL Multi Adapter Functions
42 /// 1. This is the main holder of the Gmmlib Context
43 /// 2. There is only one Multi-Adpater Context object created per process.
44 /// 3. Gmmlib dll is loaded only once per process, This done by the first UMD client
45 /// requesting Libcontext on a first Adpater to be registered with Gmmlib.
46 /// 4. Gmmlib dll is Unloaded only once per process, this is done by the last client
47 /// destroying the LibContext on the only last registered Adapter with Gmmlib.
48 /// 5. The LibContext for an Adapter is same across all the N clients and is always
49 /// equal.
50 /// 6. The ClientContext for all the N clients on particaluar Adapter is unique and
51 /// never equal.
52 /// 7 Ex: N UMD clients querying GmmLib for an GPU Adapter's Properties will have the
53 /// Same/Single LibContext and Unique N ClientContexts for that same adpater, on
54 /// same process.
55 /// 8. GmmLib is dynamically scalable for any number of GPU Adapters and any number
56 /// of Clients per Adapter.
57 /// 9. In Multiprocessing, for a process, the Gmmlib Multi-Adpater Context
58 /// object is protected/syncronized using the Lock/UnLockMAContextSyncMutex
59 /// 9. In Multiprocessing, for a process with Gmmlib Multi-Adpater Context the
60 /// LibContetxt is protected/syncronized using Lock/unLockSingletonContextSyncMutex
61 /////////////////////////////////////////////////////////////////////////////////////
62 GMM_MA_LIB_CONTEXT *pGmmMALibContext = NULL;
63
64 /////////////////////////////////////////////////////////////////////////////////////
65 /// Function to create GmmMultiAdapterContext Object
66 /// Called only during dll load time.
67 /// Since Linux doesnt have DLL Main equivalent, adding __attribute__((constructor))
68 /// for this GmmCreateMultiAdapterContext()
69 /////////////////////////////////////////////////////////////////////////////////////
GmmCreateMultiAdapterContext()70 extern "C" GMM_LIB_API_CONSTRUCTOR void GmmCreateMultiAdapterContext()
71 {
72 if(!pGmmMALibContext)
73 {
74 // This is called only during dll load
75 // Initializes the MA context.
76 pGmmMALibContext = new GMM_MA_LIB_CONTEXT();
77 }
78 }
79
80 /////////////////////////////////////////////////////////////////////////////////////
81 /// Function to Destroy GmmMultiAdapterContext Object
82 /// Called Only during Dll Unload.
83 /// Since Linux doesnt have DLL Main equivalent, adding __attribute__((destructor))
84 /// for this GmmDestroyMultiAdapterContext()
85 /////////////////////////////////////////////////////////////////////////////////////
GmmDestroyMultiAdapterContext()86 extern "C" GMM_LIB_API_DESTRUCTOR void GmmDestroyMultiAdapterContext()
87 {
88 if(pGmmMALibContext)
89 {
90 // Before destroying GmmMultiAdapterContext, check if all the Adapters have
91 // their GmmLibContext destroyed.
92 // At this point the linked list is empty and pHeadNode = NULL & NumAdapter=0.
93 if(!pGmmMALibContext->GetNumAdapters())
94 {
95 delete pGmmMALibContext;
96 pGmmMALibContext = NULL;
97 }
98 }
99 }
100
101 /////////////////////////////////////////////////////////////////////////////////////
102 /// GMM lib DLL function for creating Singleton Context (GmmLib::Context)
103 /// object which shall be process singleton across all UMD clients within a process
104 /// This function creates an object in the global MultiAdapter Context..
105 /// @see Class GmmLib::Context
106 ///
107 /// @param[in] Platform: platform variable. Includes product family (Haswell, Cherryview,
108 /// Broxton) with related render and display core revision (GEN3,
109 // ..., GEN10)
110 /// @param[in] pSkuTable: Pointer to the sku feature table. Set of capabilities to
111 /// allow code paths to be feature based and GEN agnostic.
112 /// @param[in] pWaTable: Pointer to the work around table. A set of anti-features,
113 /// often in early/prototype silicon that require work-arounds
114 /// until they are resolved to allow code paths to be GEN agnostic.
115 /// @param[in] pGtSysInfo: Pointer to the GT system info. Contains various GT System
116 /// Information such as EU counts, Thread Counts, Cache Sizes etc.
117 /// @param[in] sBDF: Adapter's BDF info for which SingletonContext has to be created
118 /// @return GMM_SUCCESS if Context is created, GMM_ERROR otherwise
119 /////////////////////////////////////////////////////////////////////////////////////
120 #ifdef _WIN32
GmmCreateLibContext(const PLATFORM Platform,const SKU_FEATURE_TABLE * pSkuTable,const WA_TABLE * pWaTable,const GT_SYSTEM_INFO * pGtSysInfo,ADAPTER_BDF sBdf)121 extern "C" GMM_STATUS GMM_STDCALL GmmCreateLibContext(const PLATFORM Platform,
122 const SKU_FEATURE_TABLE *pSkuTable,
123 const WA_TABLE * pWaTable,
124 const GT_SYSTEM_INFO * pGtSysInfo,
125 ADAPTER_BDF sBdf)
126 #else
127 extern "C" GMM_STATUS GMM_STDCALL GmmCreateLibContext(const PLATFORM Platform,
128 const void * pSkuTable,
129 const void * pWaTable,
130 const void * pGtSysInfo,
131 ADAPTER_BDF sBdf,
132 const GMM_CLIENT ClientType)
133 #endif
134 {
135 __GMM_ASSERTPTR(pSkuTable, GMM_ERROR);
136 __GMM_ASSERTPTR(pWaTable, GMM_ERROR);
137 __GMM_ASSERTPTR(pGtSysInfo, GMM_ERROR);
138
139 // If pGmmMALibContext object is NULL, return error as DLL load would have failed
140 if(!pGmmMALibContext)
141 {
142 return GMM_ERROR;
143 }
144
145 #if LHDM
146 return pGmmMALibContext->AddContext(Platform, pSkuTable, pWaTable, pGtSysInfo, sBdf, DeviceRegistryPath);
147 #else
148 return pGmmMALibContext->AddContext(Platform, pSkuTable, pWaTable, pGtSysInfo, sBdf, ClientType);
149 #endif
150 }
151
152 /////////////////////////////////////////////////////////////////////////////////////
153 /// GMM lib DLL function for deleting the Singleton Context.
154 /// Reference Count will be decremented and once the reference count reaches 0,
155 /// Singleton Context will be freed in memory. This removes a singleton context from
156 /// the global MultiAdapter Context
157 ///
158 /// @param[in] sbdf: Adapter's BDF info that needs its SingletonContext to be freed
159 /////////////////////////////////////////////////////////////////////////////////////
GmmLibContextFree(ADAPTER_BDF sBdf)160 extern "C" void GMM_STDCALL GmmLibContextFree(ADAPTER_BDF sBdf)
161 {
162 if (pGmmMALibContext)
163 {
164 pGmmMALibContext->RemoveContext(sBdf);
165 }
166 }
167 /////////////////////////////////////////////////////////////////////////////////////
168 /// Constructor to zero initialize the GmmLib::GmmMultiAdapterContext object and create
169 /// GmmMultiAdapterContext class object
170 /////////////////////////////////////////////////////////////////////////////////////
GmmMultiAdapterContext()171 GmmLib::GmmMultiAdapterContext::GmmMultiAdapterContext()
172 {
173 this->NumAdapters = 0;
174 pCpuReserveBase = NULL;
175 CpuReserveSize = 0;
176 // The Multi-Adapter Initialization is done dynamiclly using a Single Linked list Vector
177 // pHeadNode points to the root node of the linked list and registers the first
178 // adapter received from UMD.
179 // Initializing to NULL at DLL load.
180 this->pHeadNode = NULL;
181
182 // Initializes the GmmLib::GmmMultiAdapterContext sync Mutex
183 // This is required whenever any update has to be done Multiadapter context
184 // This includes Addition, deletion and search operations of the GMM_ADAPTER_INFO linked list
185 MAContextSyncMutex = PTHREAD_MUTEX_INITIALIZER;
186 }
187
188 /////////////////////////////////////////////////////////////////////////////////////
189 /// Destructor to free GmmLib::GmmMultiAdapterContext object memory
190 /////////////////////////////////////////////////////////////////////////////////////
~GmmMultiAdapterContext()191 GmmLib::GmmMultiAdapterContext::~GmmMultiAdapterContext()
192 {
193 uint32_t i = 0;
194
195 // Un-initializes the GmmLib::GmmMultiAdapterContext sync Mutex
196 pthread_mutex_destroy(&MAContextSyncMutex);
197 }
198
199 /////////////////////////////////////////////////////////////////////////////////////
200 /// Multi Adapter member function for creating Singleton Context (GmmLib::Context)
201 /// object which shall be process singleton across all UMD clients within a process.
202 /// This function is thread safe for the MultiAdapterContext object.
203 /// @see Class GmmLib::Context
204 ///
205 /// @param[in] Platform: platform variable. Includes product family (Haswell, Cherryview,
206 /// Broxton) with related render and display core revision (GEN3,
207 // ..., GEN10)
208 /// @param[in] pSkuTable: Pointer to the sku feature table. Set of capabilities to
209 /// allow code paths to be feature based and GEN agnostic.
210 /// @param[in] pWaTable: Pointer to the work around table. A set of anti-features,
211 /// often in early/prototype silicon that require work-arounds
212 /// until they are resolved to allow code paths to be GEN agnostic.
213 /// @param[in] pGtSysInfo: Pointer to the GT system info. Contains various GT System
214 /// Information such as EU counts, Thread Counts, Cache Sizes etc.
215 /// @param[in] sBDF: Adapter's BDF info for which SingletonContext i.e Adapter Node
216 /// has to be created.
217 /// @return GMM_SUCCESS if Context is created, GMM_ERROR otherwise
218 /////////////////////////////////////////////////////////////////////////////////////
219 #if LHDM
AddContext(const PLATFORM Platform,const SKU_FEATURE_TABLE * _pSkuTable,const WA_TABLE * _pWaTable,const GT_SYSTEM_INFO * _pGtSysInfo,ADAPTER_BDF sBdf,const char * DeviceRegistryPath,uint32_t PhysicalAdapterIndex)220 GMM_STATUS GMM_STDCALL GmmLib::GmmMultiAdapterContext::AddContext(const PLATFORM Platform,
221 const SKU_FEATURE_TABLE *_pSkuTable,
222 const WA_TABLE *_pWaTable,
223 const GT_SYSTEM_INFO *_pGtSysInfo,
224 ADAPTER_BDF sBdf,
225 const char *DeviceRegistryPath,
226 uint32_t PhysicalAdapterIndex)
227 #else
228 GMM_STATUS GMM_STDCALL GmmLib::GmmMultiAdapterContext::AddContext(const PLATFORM Platform,
229 const void *_pSkuTable,
230 const void *_pWaTable,
231 const void *_pGtSysInfo,
232 ADAPTER_BDF sBdf,
233 const GMM_CLIENT ClientType)
234 #endif
235 {
236 __GMM_ASSERTPTR(_pSkuTable, GMM_ERROR);
237 __GMM_ASSERTPTR(_pWaTable, GMM_ERROR);
238 __GMM_ASSERTPTR(_pGtSysInfo, GMM_ERROR);
239
240 GMM_STATUS Status = GMM_SUCCESS;
241 SKU_FEATURE_TABLE *pSkuTable;
242 WA_TABLE *pWaTable;
243 GT_SYSTEM_INFO *pSysInfo;
244 GMM_LIB_CONTEXT *pGmmLibContext = NULL;
245 GmmLib::GMM_ADAPTER_INFO *pNode = NULL;
246
247 pSkuTable = (SKU_FEATURE_TABLE *)_pSkuTable;
248 pWaTable = (WA_TABLE *)_pWaTable;
249 pSysInfo = (GT_SYSTEM_INFO *)_pGtSysInfo;
250
251 GMM_STATUS SyncLockStatus = LockMAContextSyncMutex();
252 if (SyncLockStatus != GMM_SUCCESS)
253 {
254 return SyncLockStatus;
255 }
256
257 // see if a context with the given BDF already exists
258 pNode = GetAdapterNodeUnlocked(sBdf);
259
260 if (pNode)
261 {
262 // The requested adapter context already exists. increment the reference count.
263 // No further initialization needed.
264 pNode->pGmmLibContext->IncrementRefCount();
265 UnLockMAContextSyncMutex();
266 return GMM_SUCCESS;
267 }
268
269 // No context exists for this bdf. Add a new node to store the context.
270 pNode = AddAdapterNode();
271 if (pNode == NULL)
272 {
273 UnLockMAContextSyncMutex();
274 return GMM_ERROR;
275 }
276
277 // No context for this adapter yet, Lets create a new LibContext
278 pGmmLibContext = new GMM_LIB_CONTEXT();
279 if (pGmmLibContext == NULL)
280 {
281 RemoveAdapterNode(pNode);
282 pNode = NULL;
283 UnLockMAContextSyncMutex();
284 return GMM_ERROR;
285 }
286
287 pGmmLibContext->IncrementRefCount();
288
289 Status = (pGmmLibContext->InitContext(Platform, pSkuTable, pWaTable, pSysInfo, ClientType));
290 if (Status != GMM_SUCCESS)
291 {
292 //clean everything and return error
293 pGmmLibContext->DecrementRefCount();
294 pGmmLibContext->DestroyContext();
295 // Delete/free the LibContext object
296 delete pGmmLibContext;
297 RemoveAdapterNode(pNode);
298 UnLockMAContextSyncMutex();
299 return GMM_ERROR;
300 }
301
302 #if LHDM
303 // Initialize SingletonContext Data.
304 // TBD: ProcessHeap creation requires size and GfxAddress parameters. These parameters are constants
305 // and are given by GMM lib internally by PageTableMgr. Hence pHeapObj should be created here at the
306 // time of SingletonContext creation. But untill all UMD clients have moved to GMM DLL, then we will
307 // create this here.
308 pGmmLibContext->pHeapObj = NULL;
309 pGmmLibContext->ProcessHeapCounter = 0;
310
311 // TBD: ProcessVA Gfx partition should be created here using VirtualAlloc at the time of SingletonContext
312 // creation. But untill all UMD clients have moved to GMM DLL, then we will
313 // create this here.
314 pGmmLibContext->ProcessVA = {0};
315 pGmmLibContext->ProcessVACounter = 0;
316
317 pGmmLibContext->IsSVMReserved = 0;
318 pGmmLibContext->NullCCSTileAddress = 0;
319 #endif
320
321 pGmmLibContext->sBdf = sBdf;
322
323 pNode->pGmmLibContext = pGmmLibContext;
324
325
326 UnLockMAContextSyncMutex();
327
328 return GMM_SUCCESS;
329 }
330
331 /////////////////////////////////////////////////////////////////////////////////////
332 /// GMM lib DLL function for deleting the Singleton Context.
333 /// Reference Count will be decremented and once the reference count reaches 0,
334 /// Singleton Context will be freed in memory
335 /// This function is thread safe for the MultiAdapterContext object.
336 ///
337 /// @param[in] sbdf: Adapter's BDF info that needs its SingletonContext to be freed
338 /////////////////////////////////////////////////////////////////////////////////////
RemoveContext(ADAPTER_BDF sBdf)339 GMM_STATUS GMM_STDCALL GmmLib::GmmMultiAdapterContext::RemoveContext(ADAPTER_BDF sBdf)
340 {
341 GMM_STATUS SyncLockStatus = LockMAContextSyncMutex();
342
343 if (SyncLockStatus != GMM_SUCCESS)
344 {
345 return SyncLockStatus;
346 }
347
348 GmmLib::GMM_ADAPTER_INFO *pNode = GetAdapterNodeUnlocked(sBdf);
349 GMM_LIB_ASSERT(pNode);
350 if (!pNode)
351 {
352 UnLockMAContextSyncMutex();
353 return GMM_ERROR;
354 }
355
356 if (pNode->pGmmLibContext)
357 {
358 int32_t ContextRefCount = pNode->pGmmLibContext->DecrementRefCount();
359 // Refount = 0, It means that it the last client on this adapter
360 // Lets free the LibContext and the Adapter Node
361 if (!ContextRefCount)
362 {
363 pNode->pGmmLibContext->DestroyContext();
364 // Delete/free the LibContext object
365 delete pNode->pGmmLibContext;
366
367 // Delete/free the AdapterNode from the Linked List
368 RemoveAdapterNode(pNode);
369 pNode = NULL;
370 }
371 }
372 else
373 {
374 // No context exists for this node. Just remove it.
375 RemoveAdapterNode(pNode);
376 pNode = NULL;
377 }
378
379 UnLockMAContextSyncMutex();
380
381 return GMM_SUCCESS;
382 }
383
384
385
386 /////////////////////////////////////////////////////////////////////////////////////
387 /// Member function of GmmMultiAdapterContext class for returning the AdapterIdx
388 ///
389 /// @param[in] sBdf : Adpater Bus, Device and Fucntion details
390 /// @return Adpater Idx corresponding the given BDF.
391 /////////////////////////////////////////////////////////////////////////////////////
GetAdapterIndex(ADAPTER_BDF sBdf)392 uint32_t GMM_STDCALL GmmLib::GmmMultiAdapterContext::GetAdapterIndex(ADAPTER_BDF sBdf)
393 {
394 return 0;
395 }
396
397
398 /////////////////////////////////////////////////////////////////////////////////////
399 /// Member function of GmmMultiAdapterContext class to add adapter info for a given BDF
400 /// Adds a new node with the given BDF if it is not yet tracked, otherwise returns the
401 /// existing node with a matching BDF
402 /// This function is not thread safe for the MultiAdapterContext object and calls to
403 /// it must be protected with LockMAContextSyncMutex()
404 ///
405 /// @param[in] sBdf : Adpater Bus, Device and Function details
406 /// @return GmmLib::GMM_ADAPTER_INFO pointer for the BDF
407 /////////////////////////////////////////////////////////////////////////////////////
AddAdapterNode()408 GmmLib::GMM_ADAPTER_INFO *GmmLib::GmmMultiAdapterContext::AddAdapterNode()
409 {
410 GMM_ADAPTER_INFO *pNode = NULL, *pPrev = NULL;
411
412 pNode = this->pHeadNode;
413
414 // walk to the end of the list
415 while (pNode)
416 {
417 pPrev = pNode;
418 pNode = pNode->pNext;
419 }
420
421 // create a new node
422 pNode = (GMM_ADAPTER_INFO *)malloc(sizeof(GMM_ADAPTER_INFO));
423 if (!pNode)
424 {
425 // No memory for new node
426 return NULL;
427 }
428
429 pNode->pGmmLibContext = NULL;
430 pNode->pNext = NULL;
431
432 if (this->pHeadNode)
433 {
434 // add it to the end of the list if the list already exists
435 pPrev->pNext = pNode;
436 }
437 else
438 {
439 // nothing in the list, insert it as the head of the list
440 this->pHeadNode = pNode;
441 }
442
443 this->NumAdapters++;
444
445 return pNode;
446 }
447
448 /////////////////////////////////////////////////////////////////////////////////////
449 /// Member function of GmmMultiAdapterContext class to remove a given GMM_ADAPTER_INFO node
450 /// This function is not thread safe for the MultiAdapterContext object and calls to
451 /// it must be protected with LockMAContextSyncMutex()
452 ///
453 /// @param[in] pNode : The node to remove from the list
454 /// @return Void : Removes and deletes the adapter Node from the list
455 /////////////////////////////////////////////////////////////////////////////////////
RemoveAdapterNode(GMM_ADAPTER_INFO * pNode)456 void GmmLib::GmmMultiAdapterContext::RemoveAdapterNode(GMM_ADAPTER_INFO *pNode)
457 {
458 GMM_ADAPTER_INFO *pCur = NULL, *pPrev = NULL;
459
460 // Find the node and remove the node from the list
461 pCur = this->pHeadNode;
462 while (pCur)
463 {
464 if (pCur == pNode)
465 {
466 if (pPrev)
467 {
468 // the node to be removed is in the middle of the list or the tail
469 pPrev->pNext = pNode->pNext;
470 }
471 else if (pNode == this->pHeadNode)
472 {
473 // the node to be removed is the head of the list
474 this->pHeadNode = pNode->pNext;
475 }
476
477 // Decrement the Adapter Node count tracker variable
478 this->NumAdapters--;
479
480 // Free the node that was removed from the list above.
481 free(pNode);
482 break;
483 }
484 pPrev = pCur;
485 pCur = pCur->pNext;
486 }
487 GMM_ASSERTDPF(pCur != NULL, "CRITICAL ERROR: Node to be released does not exist in list");
488 }
489
490 /////////////////////////////////////////////////////////////////////////////////////
491 /// Member function of GmmMultiAdapterContext class for returning the Adapter Node
492 /// This function is thread safe for the MultiAdapterContext object
493 ///
494 /// @param[in] sBdf : Adpater Bus, Device and Fucntion details
495 /// @return Adpater Node corresponding the given BDF or return NULL if not found
496 /////////////////////////////////////////////////////////////////////////////////////
GetAdapterNode(ADAPTER_BDF sBdf)497 GmmLib::GMM_ADAPTER_INFO *GmmLib::GmmMultiAdapterContext::GetAdapterNode(ADAPTER_BDF sBdf)
498 {
499 GMM_ADAPTER_INFO *pNode = NULL;
500
501 GMM_STATUS SyncLockStatus = LockMAContextSyncMutex();
502 if (SyncLockStatus != GMM_SUCCESS)
503 {
504 return NULL;
505 }
506
507 pNode = GetAdapterNodeUnlocked(sBdf);
508
509 UnLockMAContextSyncMutex();
510
511 return pNode;
512 }
513
514 /////////////////////////////////////////////////////////////////////////////////////
515 /// Member function of GmmMultiAdapterContext class for returning the Adapter Node
516 /// This function is not thread safe for the MultiAdapterContext object and calls to
517 /// it must be protected with LockMAContextSyncMutex()
518 ///
519 /// @param[in] sBdf : Adpater Bus, Device and Fucntion details
520 /// @return Adpater Node corresponding the given BDF or return NULL if not found
521 /////////////////////////////////////////////////////////////////////////////////////
GetAdapterNodeUnlocked(ADAPTER_BDF sBdf)522 GmmLib::GMM_ADAPTER_INFO *GmmLib::GmmMultiAdapterContext::GetAdapterNodeUnlocked(ADAPTER_BDF sBdf)
523 {
524 GMM_ADAPTER_INFO *pNode = this->pHeadNode;
525
526 // Search the entire linked list if the Adapter Node with sBdf is found or not
527 while (pNode)
528 {
529 if ((sBdf.Bus == pNode->pGmmLibContext->sBdf.Bus) &&
530 (sBdf.Device == pNode->pGmmLibContext->sBdf.Device) &&
531 (sBdf.Function == pNode->pGmmLibContext->sBdf.Function))
532 {
533 // Yes, Found!. This is the Adapter Node
534 // pNode != NULL, will be valid pointer.
535 return pNode;
536 }
537 else
538 {
539 // Not found, Search Next
540 // pNode = NULL if traversed till the tail and not found
541 pNode = pNode->pNext;
542 }
543 }
544
545 return NULL;
546 }
547
548 ///////////////////////////////////////////////////////////////////////////////////////
549 /// Member function of GmmMultiAdapterContext class for returning the GmmLibContext
550 /// This function is thread safe for the MultiAdapterContext object
551 //
552 /// @param[in] sBdf : Adpater Bus, Device and Fucntion details
553 /// @return GmmLibContext corresponding the given BDF.
554 //////////////////////////////////////////////////////////////////////////////////////
GetAdapterLibContext(ADAPTER_BDF sBdf)555 GmmLib::Context *GMM_STDCALL GmmLib::GmmMultiAdapterContext::GetAdapterLibContext(ADAPTER_BDF sBdf)
556 {
557 GMM_ADAPTER_INFO *pNode = NULL;
558
559 //Search the list and get the Adapter Node
560 pNode = (GMM_ADAPTER_INFO *)GetAdapterNode(sBdf);
561 if(pNode)
562 {
563 return pNode->pGmmLibContext;
564 }
565 else
566 {
567 return NULL; //return Null if not found
568 }
569 }
570
571 /////////////////////////////////////////////////////////////////////////////////////
572 /// Member function of GmmMultiAdapterContext class for returning the NumAdapters
573 /// that are initialized within a process
574 /// This function is thread safe for the MultiAdapterContext object
575 ///
576 /// @return Number of Adpaters that are opened and initialized within a process.
577 /////////////////////////////////////////////////////////////////////////////////////
GetNumAdapters()578 uint32_t GMM_STDCALL GmmLib::GmmMultiAdapterContext::GetNumAdapters()
579 {
580 return this->NumAdapters;
581 }
582
583 #ifdef _WIN32
584 /////////////////////////////////////////////////////////////////////////////////////
585 /// Member function of GmmMultiAdapterContext class for Locking MultiAdapter Mutex
586 /// SyncMutex to protect access of GmmMultiAdpaterContext object
587 ///
588 /// @return GMM_STATUS.
589 /////////////////////////////////////////////////////////////////////////////////////
LockMAContextSyncMutex()590 GMM_STATUS GMM_STDCALL GmmLib::GmmMultiAdapterContext::LockMAContextSyncMutex()
591 {
592 if(MAContextSyncMutex)
593 {
594 while(WAIT_OBJECT_0 != ::WaitForSingleObject(MAContextSyncMutex, INFINITE))
595 ;
596 return GMM_SUCCESS;
597 }
598 else
599 {
600 return GMM_ERROR;
601 }
602 }
603
604 /////////////////////////////////////////////////////////////////////////////////////
605 /// Member function of GmmMultiAdapterContext class for UnLocking MultiAdapter Mutex
606 /// SyncMutex to protect access of GmmMultiAdpaterContext
607 ///
608 /// @return GMM_STATUS.
609 /////////////////////////////////////////////////////////////////////////////////////
UnLockMAContextSyncMutex()610 GMM_STATUS GMM_STDCALL GmmLib::GmmMultiAdapterContext::UnLockMAContextSyncMutex()
611 {
612 if(MAContextSyncMutex)
613 {
614 ::ReleaseMutex(MAContextSyncMutex);
615 return GMM_SUCCESS;
616 }
617 else
618 {
619 return GMM_ERROR;
620 }
621 }
622
623 #else // Non Win OS
624
625 /////////////////////////////////////////////////////////////////////////////////////
626 /// Member function of GmmMultiAdapterContext class for Locking MultiAdapter Mutex
627 ///
628 /// @return GMM_STATUS.
629 /////////////////////////////////////////////////////////////////////////////////////
LockMAContextSyncMutex()630 GMM_STATUS GMM_STDCALL GmmLib::GmmMultiAdapterContext::LockMAContextSyncMutex()
631 {
632 pthread_mutex_lock(&MAContextSyncMutex);
633 return GMM_SUCCESS;
634 }
635
636 /////////////////////////////////////////////////////////////////////////////////////
637 /// Member function of GmmMultiAdapterContext class for UnLocking MultiAdapter Mutex
638 ///
639 /// @return GMM_STATUS.
640 /////////////////////////////////////////////////////////////////////////////////////
UnLockMAContextSyncMutex()641 GMM_STATUS GMM_STDCALL GmmLib::GmmMultiAdapterContext::UnLockMAContextSyncMutex()
642 {
643 pthread_mutex_unlock(&MAContextSyncMutex);
644 return GMM_SUCCESS;
645 }
646 #endif //#ifdef _WIN32
647
648 #ifdef _WIN32
649 /////////////////////////////////////////////////////////////////////////
650 /// Get ProcessHeapVA Singleton HeapObj
651 /////////////////////////////////////////////////////////////////////////
GetSharedHeapObject()652 GMM_HEAP *GmmLib::Context::GetSharedHeapObject()
653 {
654 GMM_HEAP *pHeapObjOut = NULL;
655 // Obtain ProcessSingleton Lock
656 #if GMM_LIB_DLL_MA
657 LockSingletonContextSyncMutex();
658 #else
659 GmmLib::Context::LockSingletonContextSyncMutex();
660 #endif
661
662 //Check if the ProcessHeapCounter is 0 or not, if not 0 increment the counter and return the heapObj
663 // that is stored in the DLL Singleton context
664 if(ProcessHeapCounter)
665 {
666 ProcessHeapCounter++;
667 pHeapObjOut = pHeapObj;
668 }
669
670 // Unlock ProcessSingleton Lock
671 #if GMM_LIB_DLL_MA
672 UnlockSingletonContextSyncMutex();
673 #else
674 GmmLib::Context::UnlockSingletonContextSyncMutex();
675 #endif
676
677 return pHeapObjOut;
678 }
679 /////////////////////////////////////////////////////////////////////////
680 /// Set ProcessHeapVA Singleton HeapObj
681 /////////////////////////////////////////////////////////////////////////
SetSharedHeapObject(GMM_HEAP ** pProcessHeapObj)682 uint32_t GmmLib::Context::SetSharedHeapObject(GMM_HEAP **pProcessHeapObj)
683 {
684 uint32_t DllClientsCount = 0;
685 // Obtain ProcessSingleton Lock
686 #if GMM_LIB_DLL_MA
687 LockSingletonContextSyncMutex();
688 #else
689 GmmLib::Context::LockSingletonContextSyncMutex();
690 #endif
691
692 if(pProcessHeapObj)
693 {
694 if(!ProcessHeapCounter)
695 {
696 // Setting it for the first time
697 ProcessHeapCounter++;
698 pHeapObj = *pProcessHeapObj;
699 }
700 else
701 {
702 ProcessHeapCounter++;
703 *pProcessHeapObj = pHeapObj;
704 }
705 }
706 else // Destroy the HeapObj Handle Case
707 {
708 ProcessHeapCounter--;
709 if(!ProcessHeapCounter)
710 {
711 // When all UMDs clients have called destroy
712 pHeapObj = NULL;
713 }
714 }
715
716 DllClientsCount = ProcessHeapCounter;
717
718 // Unlock ProcessSingleton Lock
719 #if GMM_LIB_DLL_MA
720 UnlockSingletonContextSyncMutex();
721 #else
722 GmmLib::Context::UnlockSingletonContextSyncMutex();
723 #endif
724
725 return DllClientsCount;
726 }
727
728 /////////////////////////////////////////////////////////////////////////
729 /// Get ProcessGfxPartition
730 /////////////////////////////////////////////////////////////////////////
GetProcessGfxPartition(GMM_GFX_PARTITIONING * pProcessVA)731 void GmmLib::Context::GetProcessGfxPartition(GMM_GFX_PARTITIONING *pProcessVA)
732 {
733 // Obtain ProcessSingleton Lock
734 #if GMM_LIB_DLL_MA
735 LockSingletonContextSyncMutex();
736 #else
737 GmmLib::Context::LockSingletonContextSyncMutex();
738 #endif
739
740 //Check if the ProcessVACounter is 0 or not, if not 0 increment the counter and return the ProcessVA
741 // that is stored in the DLL Singleton context
742 if(ProcessVACounter)
743 {
744 ProcessVACounter++;
745 if(pProcessVA)
746 {
747 *pProcessVA = ProcessVA;
748 }
749 }
750
751 // Unlock ProcessSingleton Lock
752 #if GMM_LIB_DLL_MA
753 UnlockSingletonContextSyncMutex();
754 #else
755 GmmLib::Context::UnlockSingletonContextSyncMutex();
756 #endif
757 }
758
759 /////////////////////////////////////////////////////////////////////////
760 /// Set ProcessGfxPartition
761 /////////////////////////////////////////////////////////////////////////
SetProcessGfxPartition(GMM_GFX_PARTITIONING * pProcessVA)762 void GmmLib::Context::SetProcessGfxPartition(GMM_GFX_PARTITIONING *pProcessVA)
763 {
764 // Obtain ProcessSingleton Lock
765 #if GMM_LIB_DLL_MA
766 LockSingletonContextSyncMutex();
767 #else
768 GmmLib::Context::LockSingletonContextSyncMutex();
769 #endif
770
771 if(pProcessVA)
772 {
773 if(!ProcessVACounter)
774 {
775 // Setting it for the first time
776 ProcessVACounter++;
777 ProcessVA = *pProcessVA;
778 }
779 else
780 {
781 ProcessVACounter++;
782 //Add code to return the stored value of ProcessVA when Escapes are removed
783 }
784 }
785 else // Reset the ProcessVA Case
786 {
787 ProcessVACounter--;
788 if(!ProcessVACounter)
789 {
790 // When all UMDs clients have called destroy
791 ProcessVA = {0};
792 }
793 }
794
795 // Unlock ProcessSingleton Lock
796 #if GMM_LIB_DLL_MA
797 UnlockSingletonContextSyncMutex();
798 #else
799 GmmLib::Context::UnlockSingletonContextSyncMutex();
800 #endif
801 }
802
803 #endif // _WIN32
804
805 #endif // GMM_LIB_DLL
806
807 /////////////////////////////////////////////////////////////////////////////////////
808 /// Constructor to zero initialize the GmmLib::Context object
809 /////////////////////////////////////////////////////////////////////////////////////
Context()810 GmmLib::Context::Context()
811 : ClientType(),
812 pPlatformInfo(),
813 pTextureCalc(),
814 SkuTable(),
815 WaTable(),
816 GtSysInfo(),
817 pGmmKmdContext(),
818 pGmmUmdContext(),
819 pKmdHwDev(),
820 pUmdAdapter(),
821 pGmmCachePolicy()
822 {
823 memset(CachePolicy, 0, sizeof(CachePolicy));
824 memset(CachePolicyTbl, 0, sizeof(CachePolicyTbl));
825
826 //Default initialize 64KB Page padding percentage.
827 AllowedPaddingFor64KbPagesPercentage = 10;
828 InternalGpuVaMax = 0;
829 AllowedPaddingFor64KBTileSurf = 10;
830
831 #if(!defined(__GMM_KMD__) && !defined(GMM_UNIFIED_LIB))
832 pGmmGlobalClientContext = NULL;
833 #endif
834
835 #ifdef GMM_LIB_DLL
836 //Protect this adapter context with a sync mutex. Initialize sync mutex
837 #ifdef _WIN32
838 SyncMutex = ::CreateMutex(NULL, FALSE, NULL);
839 #else // !_WIN32
840 SyncMutex = PTHREAD_MUTEX_INITIALIZER;
841 #endif // _WIN32
842
843 #if GMM_LIB_DLL_MA
844 RefCount = 0;
845 #endif //GMM_LIB_DLL_MA
846 #endif //GMM_LIB_DLL
847 }
848
849 /////////////////////////////////////////////////////////////////////////////////////
850 /// Destructor to release GmmLib::Context object memory
851 /////////////////////////////////////////////////////////////////////////////////////
~Context()852 GmmLib::Context::~Context()
853 {
854 #ifdef GMM_LIB_DLL
855 // Close the Mutex protecting this context
856 pthread_mutex_destroy(&SyncMutex);
857 #endif //GMM_LIB_DLL
858 }
859
860 #ifdef _WIN32
861 /////////////////////////////////////////////////////////////////////////////////////
862 /// Member function of Context class for Locking Singleton Context
863 /// SyncMutex to protect access of GmmLibContext
864 ///
865 /// @return GMM_STATUS.
866 /////////////////////////////////////////////////////////////////////////////////////
LockSingletonContextSyncMutex()867 GMM_STATUS GMM_STDCALL GmmLib::Context::LockSingletonContextSyncMutex()
868 {
869 #ifdef GMM_LIB_DLL
870 if(SyncMutex)
871 {
872 while(WAIT_OBJECT_0 != ::WaitForSingleObject(SyncMutex, INFINITE))
873 ;
874 return GMM_SUCCESS;
875 }
876 #endif //GMM_LIB_DLL
877 return GMM_ERROR;
878 }
879
880 /////////////////////////////////////////////////////////////////////////////////////
881 /// Member function of Context class for Unlocking Singleton Context
882 /// SyncMutex to protect access of GmmLibContext
883 ///
884 /// @return GMM_STATUS.
885 /////////////////////////////////////////////////////////////////////////////////////
UnlockSingletonContextSyncMutex()886 GMM_STATUS GMM_STDCALL GmmLib::Context::UnlockSingletonContextSyncMutex()
887 {
888 #ifdef GMM_LIB_DLL
889 if(SyncMutex)
890 {
891 ::ReleaseMutex(SyncMutex);
892 return GMM_SUCCESS;
893 }
894 #endif //GMM_LIB_DLL
895 return GMM_ERROR;
896 }
897
898 #else //_WIN32
899
900 /////////////////////////////////////////////////////////////////////////////////////
901 /// Member function of Context class for Locking Singleton Context
902 ///
903 /// @return GMM_STATUS.
904 /////////////////////////////////////////////////////////////////////////////////////
LockSingletonContextSyncMutex()905 GMM_STATUS GMM_STDCALL GmmLib::Context::LockSingletonContextSyncMutex()
906 {
907 pthread_mutex_lock(&SyncMutex);
908 return GMM_SUCCESS;
909 }
910
911 /////////////////////////////////////////////////////////////////////////////////////
912 /// Member function of Context class for Unlocking Singleton Context
913 ///
914 /// @return GMM_STATUS.
915 /////////////////////////////////////////////////////////////////////////////////////
UnlockSingletonContextSyncMutex()916 GMM_STATUS GMM_STDCALL GmmLib::Context::UnlockSingletonContextSyncMutex()
917 {
918 pthread_mutex_unlock(&SyncMutex);
919 return GMM_SUCCESS;
920 }
921
922 #endif //_WIN32
923
924 #if GMM_LIB_DLL_MA
925
926 /////////////////////////////////////////////////////////////////////////////////////
927 /// Member function of Context class for Incrementing Adpater Ref
928 /// Count
929 /// RefCount indicates the number of UMD clients using a particaluar Adapter.
930 /// RefCount is incremented when a client requests LibContext on already registered
931 /// adapter.
932 /// RefCount = 0, when no clients are using an adapter's LibContext
933 /// RefCount > 0, when at least one client is using the adapter's LibContext
934 ///
935 /// @param1 sBdf Adpater's Bus, Device and Fucntion
936 /// @return Current value of the ref count.
937 /////////////////////////////////////////////////////////////////////////////////////
IncrementRefCount()938 int32_t GmmLib::Context::IncrementRefCount()
939 {
940 int32_t *Ref = &RefCount;
941
942 #if defined(__linux__)
943 // returns 0 only when registering the first client
944 return (__sync_fetch_and_add(Ref, 1));
945 #endif
946 }
947
948 /////////////////////////////////////////////////////////////////////////////////////
949 /// Member function of Context class for Decrementing Adpater's Ref
950 /// Count
951 /// RefCount indicates the number of UMD clients using a particaluar Adapter.
952 /// RefCount is decremented when a clients requests LibContext destroy on already
953 /// registered adapter.
954 /// RefCount = 0, when no clients are using an adapter's LibContext
955 /// RefCount > 0, when at least one client is using the adapter's LibContext
956 ///
957 /// @param1 sBdf Adpater's Bus, Device and Fucntion
958 /// @return Current value of the ref count.
959 /////////////////////////////////////////////////////////////////////////////////////
DecrementRefCount()960 int32_t GmmLib::Context::DecrementRefCount()
961 {
962
963 int32_t *Ref = &RefCount;
964 int CurrentValue = 0;
965 int TargetValue = 0;
966 do
967 {
968 CurrentValue = *Ref;
969 if(CurrentValue > 0)
970 {
971 TargetValue = CurrentValue - 1;
972 }
973 else
974 {
975 break;
976 }
977 #if defined(__linux__)
978 } while(!__sync_bool_compare_and_swap(Ref, CurrentValue, TargetValue));
979 #endif
980 return TargetValue;
981 }
982
983 #endif //GMM_LIB_DLL_MA
984
985 /////////////////////////////////////////////////////////////////////////////////////
986 /// Member function to initialize the GmmLib::Context object with cache policy,
987 /// platform info, Texture calculator etc.
988 /// @param[in] Platform: ref to platform
989 /// @param[in] pSkuTable: ptr to sku table
990 /// @param[in] pWaTable: ptr to workaround table
991 /// @param[in] pGtSysInfo: ptr to gt system info
992 /// @param[in] ClientType: client type such as dx, ogl, ocl etc
993 /// @return GMM_SUCCESS if init is success, GMM_ERROR otherwise
994 /////////////////////////////////////////////////////////////////////////////////////
InitContext(const PLATFORM & Platform,const SKU_FEATURE_TABLE * pSkuTable,const WA_TABLE * pWaTable,const GT_SYSTEM_INFO * pGtSysInfo,GMM_CLIENT ClientType)995 GMM_STATUS GMM_STDCALL GmmLib::Context::InitContext(
996 const PLATFORM & Platform,
997 const SKU_FEATURE_TABLE *pSkuTable,
998 const WA_TABLE * pWaTable,
999 const GT_SYSTEM_INFO * pGtSysInfo,
1000 GMM_CLIENT ClientType)
1001 {
1002 this->ClientType = ClientType;
1003
1004 // Save the SKU and WA
1005 this->SkuTable = *pSkuTable;
1006 this->WaTable = *pWaTable;
1007 this->GtSysInfo = *pGtSysInfo;
1008
1009 this->pPlatformInfo = CreatePlatformInfo(Platform, false);
1010 if(this->pPlatformInfo == NULL)
1011 {
1012 return GMM_ERROR;
1013 }
1014
1015 OverrideSkuWa();
1016
1017
1018 this->pGmmCachePolicy = CreateCachePolicyCommon();
1019 if(this->pGmmCachePolicy == NULL)
1020 {
1021 return GMM_ERROR;
1022 }
1023
1024 this->pGmmCachePolicy->InitCachePolicy();
1025
1026 this->pTextureCalc = CreateTextureCalc(Platform, false);
1027 if(this->pTextureCalc == NULL)
1028 {
1029 return GMM_ERROR;
1030 }
1031
1032 return GMM_SUCCESS;
1033 }
1034
1035 /////////////////////////////////////////////////////////////////////////////////////
1036 /// Member function to deallcoate the GmmLib::Context's cache policy, platform info,
1037 /// Texture calculator etc.
1038 /////////////////////////////////////////////////////////////////////////////////////
DestroyContext()1039 void GMM_STDCALL GmmLib::Context::DestroyContext()
1040 {
1041 if(this->pGmmCachePolicy)
1042 {
1043 delete this->pGmmCachePolicy;
1044 this->pGmmCachePolicy = NULL;
1045 }
1046
1047 if(this->pTextureCalc)
1048 {
1049 delete this->pTextureCalc;
1050 this->pTextureCalc = NULL;
1051 }
1052
1053 if(this->pPlatformInfo)
1054 {
1055 delete this->pPlatformInfo;
1056 this->pPlatformInfo = NULL;
1057 }
1058 }
1059
OverrideSkuWa()1060 void GMM_STDCALL GmmLib::Context::OverrideSkuWa()
1061 {
1062 if((GFX_GET_CURRENT_PRODUCT(this->GetPlatformInfo().Platform) < IGFX_XE_HP_SDV))
1063 {
1064 SkuTable.FtrTileY = true;
1065 }
1066
1067 if(GFX_GET_CURRENT_PRODUCT(this->GetPlatformInfo().Platform) == IGFX_PVC)
1068 {
1069 SkuTable.Ftr57bGPUAddressing = true;
1070 }
1071
1072 if (GFX_GET_CURRENT_PRODUCT(this->GetPlatformInfo().Platform) >= IGFX_BMG)
1073 {
1074 // FtrL3TransientDataFlush is always enabled for XE2 adding GMM Override if UMDs might have reset this.
1075 SkuTable.FtrL3TransientDataFlush = true;
1076 }
1077 }
1078
CreateCachePolicyCommon()1079 GMM_CACHE_POLICY *GMM_STDCALL GmmLib::Context::CreateCachePolicyCommon()
1080 {
1081 GMM_CACHE_POLICY * pGmmCachePolicy = NULL;
1082 GMM_CACHE_POLICY_ELEMENT *CachePolicy = NULL;
1083 CachePolicy = GetCachePolicyUsage();
1084 PRODUCT_FAMILY ProductFamily = GFX_GET_CURRENT_PRODUCT(GetPlatformInfo().Platform);
1085
1086 if(GetCachePolicyObj())
1087 {
1088 return GetCachePolicyObj();
1089 }
1090
1091 if(ProductFamily >= IGFX_BMG)
1092 {
1093 pGmmCachePolicy = new GmmLib::GmmXe2_LPGCachePolicy(CachePolicy, this);
1094 }
1095 else if((ProductFamily == IGFX_METEORLAKE) || (ProductFamily == IGFX_ARROWLAKE))
1096 {
1097 pGmmCachePolicy = new GmmLib::GmmXe_LPGCachePolicy(CachePolicy, this);
1098 }
1099 else
1100 {
1101 switch(GFX_GET_CURRENT_RENDERCORE(this->GetPlatformInfo().Platform))
1102 {
1103 case IGFX_XE2_HPG_CORE:
1104 pGmmCachePolicy = new GmmLib::GmmXe2_LPGCachePolicy(CachePolicy, this);
1105 break;
1106 case IGFX_GEN12LP_CORE:
1107 case IGFX_GEN12_CORE:
1108 case IGFX_XE_HP_CORE:
1109 case IGFX_XE_HPG_CORE:
1110 case IGFX_XE_HPC_CORE:
1111 if(GetSkuTable().FtrLocalMemory)
1112 {
1113 pGmmCachePolicy = new GmmLib::GmmGen12dGPUCachePolicy(CachePolicy, this);
1114 }
1115 else
1116 {
1117 pGmmCachePolicy = new GmmLib::GmmGen12CachePolicy(CachePolicy, this);
1118 }
1119 break;
1120 case IGFX_GEN11_CORE:
1121 pGmmCachePolicy = new GmmLib::GmmGen11CachePolicy(CachePolicy, this);
1122 break;
1123 case IGFX_GEN10_CORE:
1124 pGmmCachePolicy = new GmmLib::GmmGen10CachePolicy(CachePolicy, this);
1125 break;
1126 case IGFX_GEN9_CORE:
1127 pGmmCachePolicy = new GmmLib::GmmGen9CachePolicy(CachePolicy, this);
1128 break;
1129 default:
1130 pGmmCachePolicy = new GmmLib::GmmGen8CachePolicy(CachePolicy, this);
1131 break;
1132 }
1133 }
1134 if(!pGmmCachePolicy)
1135 {
1136 GMM_DPF_CRITICAL("unable to allocate memory for CachePolicy Object");
1137 }
1138
1139 return pGmmCachePolicy;
1140 }
1141
CreateTextureCalc(PLATFORM Platform,bool Override)1142 GMM_TEXTURE_CALC *GMM_STDCALL GmmLib::Context::CreateTextureCalc(PLATFORM Platform, bool Override)
1143 {
1144 if(!Override)
1145 {
1146 if(GetTextureCalc())
1147 {
1148 return GetTextureCalc();
1149 }
1150 }
1151
1152 if(GFX_GET_CURRENT_PRODUCT(GetPlatformInfo().Platform) >= IGFX_METEORLAKE)
1153 {
1154 return new GmmXe_LPGTextureCalc(this);
1155 }
1156 else
1157 {
1158 switch(GFX_GET_CURRENT_RENDERCORE(Platform))
1159 {
1160 case IGFX_GEN7_CORE:
1161 case IGFX_GEN7_5_CORE:
1162 return new GmmGen7TextureCalc(this);
1163 break;
1164 case IGFX_GEN8_CORE:
1165 return new GmmGen8TextureCalc(this);
1166 break;
1167 case IGFX_GEN9_CORE:
1168 return new GmmGen9TextureCalc(this);
1169 break;
1170 case IGFX_GEN10_CORE:
1171 return new GmmGen10TextureCalc(this);
1172 break;
1173 case IGFX_GEN11_CORE:
1174 return new GmmGen11TextureCalc(this);
1175 break;
1176 case IGFX_GEN12LP_CORE:
1177 case IGFX_GEN12_CORE:
1178 case IGFX_XE_HP_CORE:
1179 case IGFX_XE_HPG_CORE:
1180 case IGFX_XE_HPC_CORE:
1181 return new GmmGen12TextureCalc(this);
1182 break;
1183 case IGFX_XE2_HPG_CORE:
1184 default:
1185 return new GmmXe_LPGTextureCalc(this);
1186 break;
1187 }
1188 }
1189 }
1190
CreatePlatformInfo(PLATFORM Platform,bool Override)1191 GMM_PLATFORM_INFO_CLASS *GMM_STDCALL GmmLib::Context::CreatePlatformInfo(PLATFORM Platform, bool Override)
1192 {
1193 GMM_DPF_ENTER;
1194
1195 PRODUCT_FAMILY ProductFamily = GFX_GET_CURRENT_PRODUCT(Platform);
1196
1197 if(Override == false)
1198 {
1199 if(pPlatformInfo != NULL)
1200 {
1201 return pPlatformInfo;
1202 }
1203 }
1204
1205 if (ProductFamily >= IGFX_LUNARLAKE)
1206 {
1207 return new GmmLib::PlatformInfoGen12(Platform, (GMM_LIB_CONTEXT *)this);
1208 }
1209 else
1210 {
1211 switch (GFX_GET_CURRENT_RENDERCORE(Platform))
1212 {
1213 case IGFX_GEN12LP_CORE:
1214 case IGFX_GEN12_CORE:
1215 case IGFX_XE_HP_CORE:
1216 case IGFX_XE_HPG_CORE:
1217 case IGFX_XE_HPC_CORE:
1218 case IGFX_XE2_HPG_CORE:
1219 return new GmmLib::PlatformInfoGen12(Platform, (GMM_LIB_CONTEXT *)this);
1220 break;
1221 case IGFX_GEN11_CORE:
1222 return new GmmLib::PlatformInfoGen11(Platform, (GMM_LIB_CONTEXT *)this);
1223 break;
1224 case IGFX_GEN10_CORE:
1225 return new GmmLib::PlatformInfoGen10(Platform, (GMM_LIB_CONTEXT *)this);
1226 break;
1227 case IGFX_GEN9_CORE:
1228 return new GmmLib::PlatformInfoGen9(Platform, (GMM_LIB_CONTEXT *)this);
1229 break;
1230 default:
1231 return new GmmLib::PlatformInfoGen8(Platform, (GMM_LIB_CONTEXT *)this);
1232 break;
1233 }
1234 }
1235 }
1236
1237 //C - Wrappers
1238 /////////////////////////////////////////////////////////////////////////
1239 /// C-wrapper to get the PlatformInfo ptr
1240 /// @param[in] pGmmLibContext: ptr to GMM_GLOBAL_CONTEXT
1241 /// @return const PlatformInfo ptr
1242 /////////////////////////////////////////////////////////////////////////
GmmGetPlatformInfo(GMM_LIB_CONTEXT * pGmmLibContext)1243 const GMM_PLATFORM_INFO *GMM_STDCALL GmmGetPlatformInfo(GMM_LIB_CONTEXT *pGmmLibContext)
1244 {
1245 return (&pGmmLibContext->GetPlatformInfo());
1246 }
1247
1248 /////////////////////////////////////////////////////////////////////////
1249 /// C-wrapper to get the cache policy element array ptr
1250 /// @param[in] pGmmLibContext: ptr to GMM_GLOBAL_CONTEXT
1251 /// @return const cache policy elment ptr
1252 /////////////////////////////////////////////////////////////////////////
GmmGetCachePolicyUsage(GMM_LIB_CONTEXT * pGmmLibContext)1253 const GMM_CACHE_POLICY_ELEMENT *GmmGetCachePolicyUsage(GMM_LIB_CONTEXT *pGmmLibContext)
1254 {
1255 return (pGmmLibContext->GetCachePolicyUsage());
1256 }
1257
1258 /////////////////////////////////////////////////////////////////////////
1259 /// C-wrapper to get the texture calculation object ptr
1260 /// @param[in] pGmmLibContext: ptr to GMM_GLOBAL_CONTEXT
1261 /// @return TextureCalc ptr
1262 /////////////////////////////////////////////////////////////////////////
GmmGetTextureCalc(GMM_LIB_CONTEXT * pGmmLibContext)1263 GMM_TEXTURE_CALC *GmmGetTextureCalc(GMM_LIB_CONTEXT *pGmmLibContext)
1264 {
1265 return (pGmmLibContext->GetTextureCalc());
1266 }
1267
1268 /////////////////////////////////////////////////////////////////////////
1269 /// C-wrapper to get the sku table ptr
1270 /// @param[in] pGmmLibContext: ptr to GMM_GLOBAL_CONTEXT
1271 /// @return const SkuTable ptr
1272 /////////////////////////////////////////////////////////////////////////
GmmGetSkuTable(GMM_LIB_CONTEXT * pGmmLibContext)1273 const SKU_FEATURE_TABLE *GmmGetSkuTable(GMM_LIB_CONTEXT *pGmmLibContext)
1274 {
1275 return (&pGmmLibContext->GetSkuTable());
1276 }
1277
1278 /////////////////////////////////////////////////////////////////////////
1279 /// C-wrapper to get the Wa table ptr
1280 /// @param[in] pGmmLibContext: ptr to GMM_GLOBAL_CONTEXT
1281 /// @return const WaTable ptr
1282 /////////////////////////////////////////////////////////////////////////
GmmGetWaTable(GMM_LIB_CONTEXT * pGmmLibContext)1283 const WA_TABLE *GmmGetWaTable(GMM_LIB_CONTEXT *pGmmLibContext)
1284 {
1285 return (&pGmmLibContext->GetWaTable());
1286 }
1287
1288 /////////////////////////////////////////////////////////////////////////
1289 /// C-wrapper to get the GT system info ptr
1290 /// @param[in] pGmmLibContext: ptr to GMM_GLOBAL_CONTEXT
1291 /// @return const GtSysInfo ptr
1292 /////////////////////////////////////////////////////////////////////////
GmmGetGtSysInfo(GMM_LIB_CONTEXT * pGmmLibContext)1293 const GT_SYSTEM_INFO *GmmGetGtSysInfo(GMM_LIB_CONTEXT *pGmmLibContext)
1294 {
1295 return (pGmmLibContext->GetGtSysInfoPtr());
1296 }
1297
1298