11#include  "gpu_driver_specific.h" 
22
3- // Everything detected in this file is static. 
4- // The real time monitoring requires ADLX, whose interface is much more complicated than AGS 
5- // Whoever has AMD graphic cards interested in this may contribute 
6- // * ADLX (AMD Device Library eXtra): https://github.com/GPUOpen-LibrariesAndSDKs/ADLX 
7- 
8- #include  "3rdparty/ags/amd_ags.h" 
3+ #include  "adl.h" 
94#include  "common/library.h" 
105#include  "util/mallocHelper.h" 
116
12- const  char *  ffDetectAmdGpuInfo (const  FFGpuDriverCondition *  cond , FFGpuDriverResult  result , const  char *  soName )
7+ // Memory allocation function 
8+ void *  __attribute__ (__stdcall__ )) ADL_Main_Memory_Alloc (int  iSize )
139{
14-     static   bool   inited   =  false ;
15-      static   AGSGPUInfo   gpuInfo ; 
10+     return   malloc (( size_t )  iSize ) ;
11+ } 
1612
17-     if  (!inited )
13+ struct  FFAdlData  {
14+     FF_LIBRARY_SYMBOL (ADL2_Main_Control_Destroy )
15+     FF_LIBRARY_SYMBOL (ADL2_Adapter_AdapterInfoX3_Get )
16+     FF_LIBRARY_SYMBOL (ADL2_Adapter_Graphic_Core_Info_Get )
17+     FF_LIBRARY_SYMBOL (ADL2_Adapter_MemoryInfo2_Get )
18+     FF_LIBRARY_SYMBOL (ADL2_Adapter_DedicatedVRAMUsage_Get )
19+     FF_LIBRARY_SYMBOL (ADL2_Adapter_VRAMUsage_Get )
20+     FF_LIBRARY_SYMBOL (ADL2_Adapter_ASICFamilyType_Get )
21+     FF_LIBRARY_SYMBOL (ADL2_Overdrive6_CurrentStatus_Get )
22+     FF_LIBRARY_SYMBOL (ADL2_Overdrive6_Temperature_Get )
23+     FF_LIBRARY_SYMBOL (ADL2_Overdrive6_StateInfo_Get )
24+ 
25+     bool  inited ;
26+     ADL_CONTEXT_HANDLE  apiHandle ;
27+ } adlData ;
28+ 
29+ static  void  shutdownAdl ()
30+ {
31+     if  (adlData .apiHandle )
1832    {
19-         inited  =  true;
20-         FF_LIBRARY_LOAD (libags , "dlopen amd_ags failed" , soName  , 1 );
21-         FF_LIBRARY_LOAD_SYMBOL_MESSAGE (libags , agsInitialize )
22- 
23-         struct  AGSContext *  apiHandle ;
24-         if  (ffagsInitialize (AGS_CURRENT_VERSION , NULL , & apiHandle , & gpuInfo ) !=  AGS_SUCCESS )
25-             return  "loading ags library failed" ;
33+         adlData .ffADL2_Main_Control_Destroy (adlData .apiHandle );
34+         adlData .apiHandle  =  NULL ;
35+     }
36+ }
2637
27-         // agsDeInitialize will free pointers allocated in gpuInfo. Just leak them. 
38+ const  char *  ffDetectAmdGpuInfo (const  FFGpuDriverCondition *  cond , FFGpuDriverResult  result , const  char *  soName )
39+ {
40+     if  (!adlData .inited )
41+     {
42+         adlData .inited  =  true;
43+         FF_LIBRARY_LOAD (atiadl , "dlopen atiadlxx failed" , soName  , 1 );
44+         FF_LIBRARY_LOAD_SYMBOL_MESSAGE (atiadl , ADL2_Main_Control_Create )
45+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Main_Control_Destroy )
46+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Adapter_AdapterInfoX3_Get )
47+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Adapter_Graphic_Core_Info_Get )
48+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Adapter_MemoryInfo2_Get )
49+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Adapter_DedicatedVRAMUsage_Get )
50+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Adapter_VRAMUsage_Get )
51+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Adapter_ASICFamilyType_Get )
52+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Overdrive6_CurrentStatus_Get )
53+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Overdrive6_Temperature_Get )
54+         FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE (atiadl , adlData , ADL2_Overdrive6_StateInfo_Get )
55+ 
56+         if  (ffADL2_Main_Control_Create (ADL_Main_Memory_Alloc , 1  /*iEnumConnectedAdapters*/ , & adlData .apiHandle ) !=  ADL_OK )
57+             return  "ffADL2_Main_Control_Create() failed" ;
58+ 
59+         atexit (shutdownAdl );
60+         atiadl  =  NULL ; // don't close atiadl 
2861    }
2962
30-     if  (gpuInfo . numDevices   ==   0 )
31-         return  "loading ags library  failed or no AMD gpus found " ;
63+     if  (! adlData . apiHandle )
64+         return  "ffADL2_Main_Control_Create()  failed" ;
3265
33-     AGSDeviceInfo *  device  =  NULL ;
66+     FF_AUTO_FREE  AdapterInfo *  devices  =  NULL ;
67+     int  numDevices  =  0 ;
68+     if  (adlData .ffADL2_Adapter_AdapterInfoX3_Get (adlData .apiHandle , -1 , & numDevices , & devices ) ==  0 )
69+         return  "ffADL2_Adapter_AdapterInfoX3_Get() failed" ;
3470
35-     for  (int  iDev  =  0 ; iDev  <  gpuInfo .numDevices ; iDev ++ )
71+     const  AdapterInfo *  device  =  NULL ;
72+     for  (int  iDev  =  0 ; iDev  <  numDevices ; iDev ++ )
3673    {
37-         if  (cond -> type  &  FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID )
74+         if  (cond -> type  &  FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID )
3875        {
3976            if  (
40-                 cond -> pciDeviceId . deviceId  ==  (uint32_t ) gpuInfo . devices [iDev ].deviceId  && 
41-                 cond -> pciDeviceId . vendorId  ==  (uint32_t ) gpuInfo . devices [iDev ].vendorId  && 
42-                 cond -> pciDeviceId . revId  ==  (uint32_t ) gpuInfo . devices [iDev ].revisionId )
77+                 cond -> pciBusId . bus  ==  (uint32_t ) devices [iDev ].iBusNumber  && 
78+                 cond -> pciBusId . device  ==  (uint32_t ) devices [iDev ].iDeviceNumber  && 
79+                 cond -> pciBusId . func  ==  (uint32_t ) devices [iDev ].iFunctionNumber )
4380            {
44-                 device  =  & gpuInfo . devices [iDev ];
81+                 device  =  & devices [iDev ];
4582                break ;
4683            }
4784        }
@@ -51,25 +88,80 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
5188        return  "Device not found" ;
5289
5390    if  (result .coreCount )
54-         * result .coreCount  =  (uint32_t ) device -> numCUs ;
91+     {
92+         ADLGraphicCoreInfo  coreInfo ;
93+         if  (adlData .ffADL2_Adapter_Graphic_Core_Info_Get (adlData .apiHandle , device -> iAdapterIndex , & coreInfo ) ==  ADL_OK )
94+             * result .coreCount  =  (uint32_t ) coreInfo .iNumCUs ;
95+     }
5596
5697    if  (result .memory )
5798    {
58-         result .memory -> total  =  device -> localMemoryInBytes ;
59-         result .memory -> used  =  FF_GPU_VMEM_SIZE_UNSET ;
99+         int  vramUsage  =  0 ;
100+         if  (adlData .ffADL2_Adapter_DedicatedVRAMUsage_Get (adlData .apiHandle , device -> iAdapterIndex , & vramUsage ) ==  ADL_OK )
101+             result .memory -> used  =  (uint64_t ) vramUsage  *  1024  *  1024 ;
102+         if  (result .sharedMemory )
103+         {
104+             vramUsage  =  0 ;
105+             if  (adlData .ffADL2_Adapter_VRAMUsage_Get (adlData .apiHandle , device -> iAdapterIndex , & vramUsage ) ==  ADL_OK )
106+                 result .sharedMemory -> used  =  (uint64_t ) vramUsage  *  1024  *  1024  -  result .memory -> used ;
107+         }
108+     }
109+ 
110+     if  (result .memoryType )
111+     {
112+         ADLMemoryInfo2  memoryInfo ;
113+         if  (adlData .ffADL2_Adapter_MemoryInfo2_Get (adlData .apiHandle , device -> iAdapterIndex , & memoryInfo ) ==  ADL_OK )
114+             ffStrbufSetS (result .memoryType , memoryInfo .strMemoryType );
60115    }
61116
62117    if  (result .frequency )
63-         * result .frequency  =  (uint32_t ) device -> coreClock ; // Maximum frequency 
118+     {
119+         ADLOD6StateInfo  stateInfo ;
120+         if  (adlData .ffADL2_Overdrive6_StateInfo_Get (adlData .apiHandle , device -> iAdapterIndex , ADL_OD6_GETSTATEINFO_CUSTOM_PERFORMANCE , & stateInfo ) ==  ADL_OK )
121+         {
122+             int  clock  =  0 ; // assume in 10 kHz 
123+             for  (int  i  =  0 ; i  <  stateInfo .iNumberOfPerformanceLevels ; i ++ )
124+             {
125+                 if  (stateInfo .aLevels [i ].iEngineClock  >  clock )
126+                     clock  =  stateInfo .aLevels [i ].iEngineClock ;
127+             }
128+             * result .frequency  =  (uint32_t ) clock  / 100 ;
129+         }
130+     }
131+ 
132+     if  (result .coreUsage )
133+     {
134+         ADLOD6CurrentStatus  status ;
135+         if  (adlData .ffADL2_Overdrive6_CurrentStatus_Get (adlData .apiHandle , device -> iAdapterIndex , & status ) ==  ADL_OK )
136+         {
137+             if  (result .coreUsage )
138+                 * result .coreUsage  =  status .iActivityPercent ;
139+         }
140+     }
64141
65142    if  (result .type )
66-         * result .type  =  device -> isAPU  ? FF_GPU_TYPE_INTEGRATED  : FF_GPU_TYPE_DISCRETE ;
143+     {
144+         int  asicTypes  =  0 ;
145+         int  valids  =  0 ;
146+         if  (adlData .ffADL2_Adapter_ASICFamilyType_Get (adlData .apiHandle , device -> iAdapterIndex , & asicTypes , & valids ) ==  ADL_OK )
147+         {
148+             asicTypes  &= valids ; // This design is strange 
149+             * result .type  =  asicTypes  &  ADL_ASIC_INTEGRATED  ? FF_GPU_TYPE_INTEGRATED  : FF_GPU_TYPE_DISCRETE ;
150+         }
151+     }
67152
68153    if  (result .index )
69-         * result .index  =  (uint32_t ) device -> adlAdapterIndex ;
154+         * result .index  =  (uint32_t ) device -> iAdapterIndex ;
70155
71156    if  (result .name )
72-         ffStrbufSetS (result .name , device -> adapterString );
157+         ffStrbufSetS (result .name , device -> strAdapterName );
158+ 
159+     if  (result .temp )
160+     {
161+         int  milliDegrees  =  0 ;
162+         if  (adlData .ffADL2_Overdrive6_Temperature_Get (adlData .apiHandle , device -> iAdapterIndex , & milliDegrees ) ==  ADL_OK )
163+             * result .temp  =  milliDegrees  / 1000.0 ;
164+     }
73165
74166    return  NULL ;
75167}
0 commit comments