@@ -21,6 +21,105 @@ struct FFNvmlData {
2121 bool inited ;
2222} nvmlData ;
2323
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+
24123const char * ffDetectNvidiaGpuInfo (const FFGpuDriverCondition * cond , FFGpuDriverResult result , const char * soName )
25124{
26125#ifndef FF_DISABLE_DLOPEN
@@ -113,7 +212,13 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
113212 {
114213 unsigned int value ;
115214 if (nvmlData .ffnvmlDeviceGetIndex (device , & value ) == NVML_SUCCESS )
215+ {
116216 * result .index = value ;
217+ #ifdef _WIN32
218+ if (result .memoryType )
219+ detectMemTypeByNvapi (& result );
220+ #endif
221+ }
117222 }
118223
119224
0 commit comments