Changed the license to the Mozilla Public License 2.0 and update the licensing information.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
8 Copyright (C) 2011 Christian Vallières
13 using System.Runtime.InteropServices;
16 namespace OpenHardwareMonitor.Hardware.Nvidia {
18 internal enum NvStatus {
21 LIBRARY_NOT_FOUND = -2,
22 NO_IMPLEMENTATION = -3,
23 API_NOT_INTIALIZED = -4,
24 INVALID_ARGUMENT = -5,
25 NVIDIA_DEVICE_NOT_FOUND = -6,
28 INCOMPATIBLE_STRUCT_VERSION = -9,
29 HANDLE_INVALIDATED = -10,
30 OPENGL_CONTEXT_NOT_CURRENT = -11,
32 INSTRUMENTATION_DISABLED = -13,
33 EXPECTED_LOGICAL_GPU_HANDLE = -100,
34 EXPECTED_PHYSICAL_GPU_HANDLE = -101,
35 EXPECTED_DISPLAY_HANDLE = -102,
36 INVALID_COMBINATION = -103,
38 PORTID_NOT_FOUND = -105,
39 EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106,
40 INVALID_PERF_LEVEL = -107,
42 NV_PERSIST_FILE_NOT_FOUND = -109,
43 PERSIST_DATA_NOT_FOUND = -110,
44 EXPECTED_TV_DISPLAY = -111,
45 EXPECTED_TV_DISPLAY_ON_DCONNECTOR = -112,
46 NO_ACTIVE_SLI_TOPOLOGY = -113,
47 SLI_RENDERING_MODE_NOTALLOWED = -114,
48 EXPECTED_DIGITAL_FLAT_PANEL = -115,
49 ARGUMENT_EXCEED_MAX_SIZE = -116,
50 DEVICE_SWITCHING_NOT_ALLOWED = -117,
51 TESTING_CLOCKS_NOT_SUPPORTED = -118,
52 UNKNOWN_UNDERSCAN_CONFIG = -119,
53 TIMEOUT_RECONFIGURING_GPU_TOPO = -120,
54 DATA_NOT_FOUND = -121,
55 EXPECTED_ANALOG_DISPLAY = -122,
57 REQUIRES_REBOOT = -124,
58 INVALID_HYBRID_MODE = -125,
59 MIXED_TARGET_TYPES = -126,
60 SYSWOW64_NOT_SUPPORTED = -127,
61 IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED = -128,
62 REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS = -129,
64 WAS_STILL_DRAWING = -131,
65 FILE_NOT_FOUND = -132,
66 TOO_MANY_UNIQUE_STATE_OBJECTS = -133,
68 D3D10_1_LIBRARY_NOT_FOUND = -135,
69 FUNCTION_NOT_FOUND = -136
72 internal enum NvThermalController {
88 internal enum NvThermalTarget {
98 [StructLayout(LayoutKind.Sequential, Pack = 8)]
99 internal struct NvSensor {
100 public NvThermalController Controller;
101 public uint DefaultMinTemp;
102 public uint DefaultMaxTemp;
103 public uint CurrentTemp;
104 public NvThermalTarget Target;
107 [StructLayout(LayoutKind.Sequential, Pack = 8)]
108 internal struct NvGPUThermalSettings {
111 [MarshalAs(UnmanagedType.ByValArray,
112 SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)]
113 public NvSensor[] Sensor;
116 [StructLayout(LayoutKind.Sequential)]
117 internal struct NvDisplayHandle {
118 private readonly IntPtr ptr;
121 [StructLayout(LayoutKind.Sequential)]
122 internal struct NvPhysicalGpuHandle {
123 private readonly IntPtr ptr;
126 [StructLayout(LayoutKind.Sequential, Pack = 8)]
127 internal struct NvClocks {
129 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_CLOCKS_PER_GPU)]
133 [StructLayout(LayoutKind.Sequential, Pack = 8)]
134 internal struct NvPState {
136 public int Percentage;
139 [StructLayout(LayoutKind.Sequential, Pack = 8)]
140 internal struct NvPStates {
143 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_PSTATES_PER_GPU)]
144 public NvPState[] PStates;
147 [StructLayout(LayoutKind.Sequential, Pack = 8)]
148 internal struct NvUsages {
150 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_USAGES_PER_GPU)]
154 [StructLayout(LayoutKind.Sequential, Pack = 8)]
155 internal struct NvCooler {
157 public int Controller;
158 public int DefaultMin;
159 public int DefaultMax;
160 public int CurrentMin;
161 public int CurrentMax;
162 public int CurrentLevel;
163 public int DefaultPolicy;
164 public int CurrentPolicy;
166 public int ControlType;
170 [StructLayout(LayoutKind.Sequential, Pack = 8)]
171 internal struct NvGPUCoolerSettings {
174 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
175 public NvCooler[] Cooler;
178 [StructLayout(LayoutKind.Sequential, Pack = 8)]
179 internal struct NvLevel {
184 [StructLayout(LayoutKind.Sequential, Pack = 8)]
185 internal struct NvGPUCoolerLevels {
187 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
188 public NvLevel[] Levels;
191 [StructLayout(LayoutKind.Sequential, Pack = 8)]
192 internal struct NvMemoryInfo {
194 [MarshalAs(UnmanagedType.ByValArray, SizeConst =
195 NVAPI.MAX_MEMORY_VALUES_PER_GPU)]
196 public uint[] Values;
199 [StructLayout(LayoutKind.Sequential, Pack = 8)]
200 internal struct NvDisplayDriverVersion {
202 public uint DriverVersion;
203 public uint BldChangeListNum;
204 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
205 public string BuildBranch;
206 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
207 public string Adapter;
210 internal class NVAPI {
212 public const int MAX_PHYSICAL_GPUS = 64;
213 public const int SHORT_STRING_MAX = 64;
215 public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
216 public const int MAX_CLOCKS_PER_GPU = 0x120;
217 public const int MAX_PSTATES_PER_GPU = 8;
218 public const int MAX_USAGES_PER_GPU = 33;
219 public const int MAX_COOLER_PER_GPU = 20;
220 public const int MAX_MEMORY_VALUES_PER_GPU = 5;
222 public static readonly uint GPU_THERMAL_SETTINGS_VER = (uint)
223 Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000;
224 public static readonly uint GPU_CLOCKS_VER = (uint)
225 Marshal.SizeOf(typeof(NvClocks)) | 0x20000;
226 public static readonly uint GPU_PSTATES_VER = (uint)
227 Marshal.SizeOf(typeof(NvPStates)) | 0x10000;
228 public static readonly uint GPU_USAGES_VER = (uint)
229 Marshal.SizeOf(typeof(NvUsages)) | 0x10000;
230 public static readonly uint GPU_COOLER_SETTINGS_VER = (uint)
231 Marshal.SizeOf(typeof(NvGPUCoolerSettings)) | 0x20000;
232 public static readonly uint GPU_MEMORY_INFO_VER = (uint)
233 Marshal.SizeOf(typeof(NvMemoryInfo)) | 0x20000;
234 public static readonly uint DISPLAY_DRIVER_VERSION_VER = (uint)
235 Marshal.SizeOf(typeof(NvDisplayDriverVersion)) | 0x10000;
236 public static readonly uint GPU_COOLER_LEVELS_VER = (uint)
237 Marshal.SizeOf(typeof(NvGPUCoolerLevels)) | 0x10000;
239 private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id);
240 private delegate NvStatus NvAPI_InitializeDelegate();
241 private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(
242 NvPhysicalGpuHandle gpuHandle, StringBuilder name);
244 public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(
245 NvPhysicalGpuHandle gpuHandle, int sensorIndex,
246 ref NvGPUThermalSettings nvGPUThermalSettings);
247 public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum,
248 ref NvDisplayHandle displayHandle);
249 public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(
250 NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles,
252 public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
253 [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
254 public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(
255 NvPhysicalGpuHandle gpuHandle, out int value);
256 public delegate NvStatus NvAPI_GPU_GetAllClocksDelegate(
257 NvPhysicalGpuHandle gpuHandle, ref NvClocks nvClocks);
258 public delegate NvStatus NvAPI_GPU_GetPStatesDelegate(
259 NvPhysicalGpuHandle gpuHandle, ref NvPStates nvPStates);
260 public delegate NvStatus NvAPI_GPU_GetUsagesDelegate(
261 NvPhysicalGpuHandle gpuHandle, ref NvUsages nvUsages);
262 public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate(
263 NvPhysicalGpuHandle gpuHandle, int coolerIndex,
264 ref NvGPUCoolerSettings nvGPUCoolerSettings);
265 public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(
266 NvPhysicalGpuHandle gpuHandle, int coolerIndex,
267 ref NvGPUCoolerLevels NvGPUCoolerLevels);
268 public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate(
269 NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo);
270 public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate(
271 NvDisplayHandle displayHandle, [In, Out] ref NvDisplayDriverVersion
272 nvDisplayDriverVersion);
273 public delegate NvStatus NvAPI_GetInterfaceVersionStringDelegate(
274 StringBuilder version);
275 public delegate NvStatus NvAPI_GPU_GetPCIIdentifiersDelegate(
276 NvPhysicalGpuHandle gpuHandle, out uint deviceId, out uint subSystemId,
277 out uint revisionId, out uint extDeviceId);
279 private static readonly bool available;
280 private static readonly nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
281 private static readonly NvAPI_InitializeDelegate NvAPI_Initialize;
282 private static readonly NvAPI_GPU_GetFullNameDelegate
283 _NvAPI_GPU_GetFullName;
284 private static readonly NvAPI_GetInterfaceVersionStringDelegate
285 _NvAPI_GetInterfaceVersionString;
287 public static readonly NvAPI_GPU_GetThermalSettingsDelegate
288 NvAPI_GPU_GetThermalSettings;
289 public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate
290 NvAPI_EnumNvidiaDisplayHandle;
291 public static readonly NvAPI_GetPhysicalGPUsFromDisplayDelegate
292 NvAPI_GetPhysicalGPUsFromDisplay;
293 public static readonly NvAPI_EnumPhysicalGPUsDelegate
294 NvAPI_EnumPhysicalGPUs;
295 public static readonly NvAPI_GPU_GetTachReadingDelegate
296 NvAPI_GPU_GetTachReading;
297 public static readonly NvAPI_GPU_GetAllClocksDelegate
298 NvAPI_GPU_GetAllClocks;
299 public static readonly NvAPI_GPU_GetPStatesDelegate
300 NvAPI_GPU_GetPStates;
301 public static readonly NvAPI_GPU_GetUsagesDelegate
303 public static readonly NvAPI_GPU_GetCoolerSettingsDelegate
304 NvAPI_GPU_GetCoolerSettings;
305 public static readonly NvAPI_GPU_SetCoolerLevelsDelegate
306 NvAPI_GPU_SetCoolerLevels;
307 public static readonly NvAPI_GPU_GetMemoryInfoDelegate
308 NvAPI_GPU_GetMemoryInfo;
309 public static readonly NvAPI_GetDisplayDriverVersionDelegate
310 NvAPI_GetDisplayDriverVersion;
311 public static readonly NvAPI_GPU_GetPCIIdentifiersDelegate
312 NvAPI_GPU_GetPCIIdentifiers;
316 public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
318 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
320 if (_NvAPI_GPU_GetFullName != null)
321 status = _NvAPI_GPU_GetFullName(gpuHandle, builder);
323 status = NvStatus.FUNCTION_NOT_FOUND;
324 name = builder.ToString();
328 public static NvStatus NvAPI_GetInterfaceVersionString(out string version) {
329 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
331 if (_NvAPI_GetInterfaceVersionString != null)
332 status = _NvAPI_GetInterfaceVersionString(builder);
334 status = NvStatus.FUNCTION_NOT_FOUND;
335 version = builder.ToString();
339 private static string GetDllName() {
340 if (IntPtr.Size == 4) {
343 return "nvapi64.dll";
347 private static void GetDelegate<T>(uint id, out T newDelegate)
349 IntPtr ptr = nvapi_QueryInterface(id);
350 if (ptr != IntPtr.Zero) {
352 Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
359 DllImportAttribute attribute = new DllImportAttribute(GetDllName());
360 attribute.CallingConvention = CallingConvention.Cdecl;
361 attribute.PreserveSig = true;
362 attribute.EntryPoint = "nvapi_QueryInterface";
363 PInvokeDelegateFactory.CreateDelegate(attribute,
364 out nvapi_QueryInterface);
367 GetDelegate(0x0150E828, out NvAPI_Initialize);
368 } catch (DllNotFoundException) { return; }
369 catch (EntryPointNotFoundException) { return; }
370 catch (ArgumentNullException) { return; }
372 if (NvAPI_Initialize() == NvStatus.OK) {
373 GetDelegate(0xE3640A56, out NvAPI_GPU_GetThermalSettings);
374 GetDelegate(0xCEEE8E9F, out _NvAPI_GPU_GetFullName);
375 GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
376 GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
377 GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
378 GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);
379 GetDelegate(0x1BD69F49, out NvAPI_GPU_GetAllClocks);
380 GetDelegate(0x60DED2ED, out NvAPI_GPU_GetPStates);
381 GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
382 GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings);
383 GetDelegate(0x891FA0AE, out NvAPI_GPU_SetCoolerLevels);
384 GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
385 GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
386 GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
387 GetDelegate(0x2DDFB66E, out NvAPI_GPU_GetPCIIdentifiers);
393 public static bool IsAvailable {
394 get { return available; }