@@ -21,6 +21,105 @@ struct FFNvmlData {
21
21
bool inited ;
22
22
} nvmlData ;
23
23
24
+ #if defined(_WIN32 ) && !defined(FF_DISABLE_DLOPEN )
25
+
26
+ #include "nvapi.h"
27
+
28
+ struct FFNvapiData {
29
+ FF_LIBRARY_SYMBOL (nvapi_Unload )
30
+ FF_LIBRARY_SYMBOL (nvapi_EnumPhysicalGPUs )
31
+ FF_LIBRARY_SYMBOL (nvapi_GPU_GetRamType )
32
+
33
+ bool inited ;
34
+ } nvapiData ;
35
+
36
+ const char * detectMemTypeByNvapi (FFGpuDriverResult * result )
37
+ {
38
+ if (!nvapiData .inited )
39
+ {
40
+ nvapiData .inited = true;
41
+
42
+ FF_LIBRARY_LOAD (libnvapi , "dlopen nvapi failed" ,
43
+ #ifdef _WIN64
44
+ "nvapi64.dll"
45
+ #else
46
+ "nvapi.dll"
47
+ #endif
48
+ , 1 );
49
+ FF_LIBRARY_LOAD_SYMBOL_MESSAGE (libnvapi , nvapi_QueryInterface )
50
+ #define FF_NVAPI_INTERFACE (iName , iOffset ) \
51
+ __typeof__(&iName) ff ## iName = ffnvapi_QueryInterface(iOffset); \
52
+ if (ff ## iName == NULL) return "nvapi_QueryInterface " #iName " failed";
53
+
54
+ FF_NVAPI_INTERFACE (nvapi_Initialize , NVAPI_INTERFACE_OFFSET_INITIALIZE )
55
+ FF_NVAPI_INTERFACE (nvapi_Unload , NVAPI_INTERFACE_OFFSET_UNLOAD )
56
+ FF_NVAPI_INTERFACE (nvapi_EnumPhysicalGPUs , NVAPI_INTERFACE_OFFSET_ENUM_PHYSICAL_GPUS )
57
+ FF_NVAPI_INTERFACE (nvapi_GPU_GetRamType , NVAPI_INTERFACE_OFFSET_GPU_GET_RAM_TYPE )
58
+ #undef FF_NVAPI_INTERFACE
59
+
60
+ if (ffnvapi_Initialize () < 0 )
61
+ return "NvAPI_Initialize() failed" ;
62
+
63
+ nvapiData .ffnvapi_EnumPhysicalGPUs = ffnvapi_EnumPhysicalGPUs ;
64
+ nvapiData .ffnvapi_GPU_GetRamType = ffnvapi_GPU_GetRamType ;
65
+ nvapiData .ffnvapi_Unload = ffnvapi_Unload ;
66
+
67
+ atexit ((void * ) ffnvapi_Unload );
68
+ libnvapi = NULL ; // don't close nvapi
69
+ }
70
+
71
+ if (nvapiData .ffnvapi_EnumPhysicalGPUs == NULL )
72
+ return "loading nvapi library failed" ;
73
+
74
+ NvPhysicalGpuHandle handles [32 ];
75
+ int gpuCount = 0 ;
76
+
77
+ if (nvapiData .ffnvapi_EnumPhysicalGPUs (handles , & gpuCount ) < 0 )
78
+ return "NvAPI_EnumPhysicalGPUs() failed" ;
79
+
80
+ uint32_t gpuIndex = * result -> index ;
81
+
82
+ if ((uint32_t ) gpuCount < gpuIndex )
83
+ return "GPU index out of range" ;
84
+
85
+ NvApiGPUMemoryType memType ;
86
+ if (nvapiData .ffnvapi_GPU_GetRamType (handles [gpuIndex ], & memType ) < 0 )
87
+ return "NvAPI_GPU_GetRamType() failed" ;
88
+
89
+ switch (memType )
90
+ {
91
+ #define FF_NVAPI_MEMORY_TYPE (type ) \
92
+ case NVAPI_GPU_MEMORY_TYPE_##type: \
93
+ ffStrbufSetStatic(result->memoryType, #type); \
94
+ break;
95
+ FF_NVAPI_MEMORY_TYPE (UNKNOWN )
96
+ FF_NVAPI_MEMORY_TYPE (SDRAM )
97
+ FF_NVAPI_MEMORY_TYPE (DDR1 )
98
+ FF_NVAPI_MEMORY_TYPE (DDR2 )
99
+ FF_NVAPI_MEMORY_TYPE (GDDR2 )
100
+ FF_NVAPI_MEMORY_TYPE (GDDR3 )
101
+ FF_NVAPI_MEMORY_TYPE (GDDR4 )
102
+ FF_NVAPI_MEMORY_TYPE (DDR3 )
103
+ FF_NVAPI_MEMORY_TYPE (GDDR5 )
104
+ FF_NVAPI_MEMORY_TYPE (LPDDR2 )
105
+ FF_NVAPI_MEMORY_TYPE (GDDR5X )
106
+ FF_NVAPI_MEMORY_TYPE (LPDDR3 )
107
+ FF_NVAPI_MEMORY_TYPE (LPDDR4 )
108
+ FF_NVAPI_MEMORY_TYPE (LPDDR5 )
109
+ FF_NVAPI_MEMORY_TYPE (GDDR6 )
110
+ FF_NVAPI_MEMORY_TYPE (GDDR6X )
111
+ FF_NVAPI_MEMORY_TYPE (GDDR7 )
112
+ #undef FF_NVAPI_MEMORY_TYPE
113
+ default :
114
+ ffStrbufSetF (result - > memoryType , "Unknown (%d)" , memType );
115
+ break ;
116
+ }
117
+
118
+ return NULL ;
119
+ }
120
+
121
+ #endif
122
+
24
123
const char * ffDetectNvidiaGpuInfo (const FFGpuDriverCondition * cond , FFGpuDriverResult result , const char * soName )
25
124
{
26
125
#ifndef FF_DISABLE_DLOPEN
@@ -113,7 +212,13 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
113
212
{
114
213
unsigned int value ;
115
214
if (nvmlData .ffnvmlDeviceGetIndex (device , & value ) == NVML_SUCCESS )
215
+ {
116
216
* result .index = value ;
217
+ #ifdef _WIN32
218
+ if (result .memoryType )
219
+ detectMemTypeByNvapi (& result );
220
+ #endif
221
+ }
117
222
}
118
223
119
224
0 commit comments