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