1515
1616#include <inttypes.h>
1717
18- FF_MAYBE_UNUSED static void pciDetectTemp (FFGPUResult * gpu , uint32_t deviceClass )
19- {
20- const FFlist * tempsResult = ffDetectTemps ();
21-
22- FF_LIST_FOR_EACH (FFTempValue , tempValue , * tempsResult )
23- {
24- // https://www.kernel.org/doc/html/v5.10/gpu/amdgpu.html#hwmon-interfaces
25- // FIXME: this code doesn't take multiGPUs into count
26- // The kernel exposes the device class multiplied by 256 for some reason
27- if (tempValue -> deviceClass == deviceClass * 256 )
28- {
29- gpu -> temperature = tempValue -> value ;
30- return ;
31- }
32- }
33- }
34-
3518static void pciDetectDriver (FFGPUResult * gpu , FFstrbuf * pciDir , FFstrbuf * buffer )
3619{
3720 ffStrbufAppendS (pciDir , "/driver" );
@@ -56,33 +39,59 @@ static void pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer
5639 }
5740}
5841
59- static void pciDetectVmem ( FFGPUResult * gpu , FFstrbuf * pciDir , FFstrbuf * buffer )
42+ static void pciDetectAmdSpecific ( const FFGPUOptions * options , FFGPUResult * gpu , FFstrbuf * pciDir , FFstrbuf * buffer )
6043{
61- // Works for AMD GPUs
6244 // https://www.kernel.org/doc/html/v5.10/gpu/amdgpu.html#mem-info-vis-vram-total
63- ffStrbufAppendS (pciDir , "/mem_info_vis_vram_total" );
64- uint64_t size = 0 ;
65- if (ffReadFileBuffer (pciDir -> chars , buffer ) && (size = ffStrbufToUInt (buffer , 0 )))
45+ const uint32_t pciDirLen = pciDir -> length ;
46+
47+ ffStrbufAppendS (pciDir , "/hwmon/" );
48+ FF_AUTO_CLOSE_DIR DIR * dirp = opendir (pciDir -> chars );
49+ struct dirent * entry = readdir (dirp );
50+ if (!entry ) return ;
51+ ffStrbufAppendS (pciDir , entry -> d_name );
52+ ffStrbufAppendC (pciDir , '/' );
53+
54+ const uint32_t hwmonLen = pciDir -> length ;
55+ ffStrbufAppendS (pciDir , "in1_input" ); // Northbridge voltage in millivolts (APUs only)
56+ if (ffPathExists (pciDir -> chars , FF_PATHTYPE_FILE ))
57+ gpu -> type = FF_GPU_TYPE_INTEGRATED ;
58+ else
59+ gpu -> type = FF_GPU_TYPE_DISCRETE ;
60+
61+ uint64_t value = 0 ;
62+ if (options -> temp )
63+ {
64+ ffStrbufSubstrBefore (pciDir , hwmonLen );
65+ ffStrbufAppendS (pciDir , "temp1_input" ); // The on die GPU temperature in millidegrees Celsius
66+ if (ffReadFileBuffer (pciDir -> chars , buffer ) && (value = ffStrbufToUInt (buffer , 0 )))
67+ gpu -> frequency = (double ) value / 1000 ;
68+ }
69+
70+ ffStrbufSubstrBefore (pciDir , hwmonLen );
71+ ffStrbufAppendS (pciDir , "freq1_input" ); // The gfx/compute clock in hertz
72+ if (ffReadFileBuffer (pciDir -> chars , buffer ) && (value = ffStrbufToUInt (buffer , 0 )))
73+ gpu -> frequency = (double ) value / (1000 * 1000 * 1000 );
74+
75+ if (options -> driverSpecific )
6676 {
67- gpu -> type = size > 1024UL * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED ;
68- if (gpu -> type == FF_GPU_TYPE_DISCRETE )
69- gpu -> dedicated .total = size ;
70- else
71- gpu -> shared .total = size ;
72-
73- ffStrbufSubstrBefore (pciDir , pciDir -> length - (uint32_t ) strlen ("/mem_info_vis_vram_total" ));
74- ffStrbufAppendS (pciDir , "/mem_info_vram_used" );
75- if (ffReadFileBuffer (pciDir -> chars , buffer ) && (size = ffStrbufToUInt (buffer , 0 )))
77+ ffStrbufSubstrBefore (pciDir , pciDirLen );
78+ ffStrbufAppendS (pciDir , "/mem_info_vis_vram_total" );
79+ if (ffReadFileBuffer (pciDir -> chars , buffer ) && (value = ffStrbufToUInt (buffer , 0 )))
7680 {
77- if (gpu -> type == FF_GPU_TYPE_DISCRETE )
78- gpu -> dedicated .used = size ;
79- else
80- gpu -> shared .used = size ;
81+ ffStrbufSubstrBefore (pciDir , pciDir -> length - (uint32_t ) strlen ("/mem_info_vis_vram_total" ));
82+ ffStrbufAppendS (pciDir , "/mem_info_vram_used" );
83+ if (ffReadFileBuffer (pciDir -> chars , buffer ) && (value = ffStrbufToUInt (buffer , 0 )))
84+ {
85+ if (gpu -> type == FF_GPU_TYPE_DISCRETE )
86+ gpu -> dedicated .used = value ;
87+ else
88+ gpu -> shared .used = value ;
89+ }
8190 }
8291 }
8392}
8493
85- static void pciDetectVfreq (FFGPUResult * gpu , FFstrbuf * pciDir , FFstrbuf * buffer )
94+ static void pciDetectIntelSpecific (FFGPUResult * gpu , FFstrbuf * pciDir , FFstrbuf * buffer )
8695{
8796 if (!ffStrbufEndsWithS (pciDir , "/device" )) // Must be in `/sys/class/drm/cardN/device`
8897 return ;
@@ -98,6 +107,10 @@ static void pciDetectVfreq(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
98107 str [len ] = '\0' ;
99108 gpu -> frequency = (double ) strtoul (str , NULL , 10 ) / 1000.0 ;
100109 }
110+
111+ if (ffStrbufStartsWithS (& gpu -> name , "Intel " ))
112+ ffStrbufSubstrAfter (& gpu -> name , (uint32_t ) strlen ("Intel " ));
113+ gpu -> type = ffStrbufStartsWithIgnCaseS (& gpu -> name , "Arc " ) ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED ;
101114}
102115
103116static bool loadPciIds (FFstrbuf * pciids )
@@ -186,47 +199,50 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
186199 ffGPUParsePciIds (& pciids , subclassId , (uint16_t ) vendorId , (uint16_t ) deviceId , gpu );
187200 }
188201
189- // Temporarily disabled for now #816
190- if (false)
191- {
192- pciDetectVmem (gpu , drmDir , buffer );
193- ffStrbufSubstrBefore (drmDir , drmDirPathLength );
194- }
195-
196- pciDetectVfreq (gpu , drmDir , buffer );
197- ffStrbufSubstrBefore (drmDir , drmDirPathLength );
198-
199202 pciDetectDriver (gpu , drmDir , buffer );
200203 ffStrbufSubstrBefore (drmDir , drmDirPathLength );
201204
202- #ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
203- if (gpu -> vendor .chars == FF_GPU_VENDOR_NAME_NVIDIA && (options -> temp || options -> driverSpecific ))
205+ if (gpu -> vendor .chars == FF_GPU_VENDOR_NAME_AMD )
204206 {
205- ffDetectNvidiaGpuInfo (& (FFGpuDriverCondition ) {
206- .type = FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID ,
207- .pciBusId = {
208- .domain = pciDomain ,
209- .bus = pciBus ,
210- .device = pciDevice ,
211- .func = pciFunc ,
212- },
213- }, (FFGpuDriverResult ) {
214- .temp = options -> temp ? & gpu -> temperature : NULL ,
215- .memory = options -> driverSpecific ? & gpu -> dedicated : NULL ,
216- .coreCount = options -> driverSpecific ? (uint32_t * ) & gpu -> coreCount : NULL ,
217- .type = & gpu -> type ,
218- .frequency = & gpu -> frequency ,
219- }, "libnvidia-ml.so" );
220-
221- if (gpu -> dedicated .total != FF_GPU_VMEM_SIZE_UNSET )
222- gpu -> type = gpu -> dedicated .total > (uint64_t )1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED ;
207+ pciDetectAmdSpecific (options , gpu , drmDir , buffer );
208+ ffStrbufSubstrBefore (drmDir , drmDirPathLength );
223209 }
224- #endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
210+ else if (gpu -> vendor .chars == FF_GPU_VENDOR_NAME_INTEL )
211+ {
212+ pciDetectIntelSpecific (gpu , drmDir , buffer );
213+ ffStrbufSubstrBefore (drmDir , drmDirPathLength );
214+ }
215+ else if (gpu -> vendor .chars == FF_GPU_VENDOR_NAME_NVIDIA )
216+ {
217+ #ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
218+ if (options -> temp || options -> driverSpecific )
219+ {
220+ ffDetectNvidiaGpuInfo (& (FFGpuDriverCondition ) {
221+ .type = FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID ,
222+ .pciBusId = {
223+ .domain = pciDomain ,
224+ .bus = pciBus ,
225+ .device = pciDevice ,
226+ .func = pciFunc ,
227+ },
228+ }, (FFGpuDriverResult ) {
229+ .temp = options -> temp ? & gpu -> temperature : NULL ,
230+ .memory = options -> driverSpecific ? & gpu -> dedicated : NULL ,
231+ .coreCount = options -> driverSpecific ? (uint32_t * ) & gpu -> coreCount : NULL ,
232+ .type = & gpu -> type ,
233+ .frequency = & gpu -> frequency ,
234+ }, "libnvidia-ml.so" );
235+ }
236+ #endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
225237
226- #ifdef __linux__
227- if (options -> temp && gpu -> temperature != gpu -> temperature )
228- pciDetectTemp (gpu , ((uint32_t ) classId << 8 ) + subclassId );
229- #endif
238+ if (gpu -> type == FF_GPU_TYPE_UNKNOWN )
239+ {
240+ if (ffStrbufStartsWithIgnCaseS (& gpu -> name , "GeForce" ) ||
241+ ffStrbufStartsWithIgnCaseS (& gpu -> name , "Quadro" ) ||
242+ ffStrbufStartsWithIgnCaseS (& gpu -> name , "Tesla" ))
243+ gpu -> type = FF_GPU_TYPE_DISCRETE ;
244+ }
245+ }
230246
231247 return NULL ;
232248}
0 commit comments