xref: /aosp_15_r20/external/gmmlib/Source/GmmLib/GlobalInfo/GmmInfo.cpp (revision 35ffd701415c9e32e53136d61a677a8d0a8fc4a5)
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