Improved the support for Nvidia GPUs.
3 Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 The contents of this file are subject to the Mozilla Public License Version
6 1.1 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
9 http://www.mozilla.org/MPL/
11 Software distributed under the License is distributed on an "AS IS" basis,
12 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 for the specific language governing rights and limitations under the License.
15 The Original Code is the Open Hardware Monitor code.
17 The Initial Developer of the Original Code is
18 Michael Möller <m.moeller@gmx.ch>.
19 Portions created by the Initial Developer are Copyright (C) 2009-2010
20 the Initial Developer. All Rights Reserved.
24 Alternatively, the contents of this file may be used under the terms of
25 either the GNU General Public License Version 2 or later (the "GPL"), or
26 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 in which case the provisions of the GPL or the LGPL are applicable instead
28 of those above. If you wish to allow use of your version of this file only
29 under the terms of either the GPL or the LGPL, and not to allow others to
30 use your version of this file under the terms of the MPL, indicate your
31 decision by deleting the provisions above and replace them with the notice
32 and other provisions required by the GPL or the LGPL. If you do not delete
33 the provisions above, a recipient may use your version of this file under
34 the terms of any one of the MPL, the GPL or the LGPL.
39 using System.Collections.Generic;
40 using System.Runtime.InteropServices;
43 namespace OpenHardwareMonitor.Hardware.Nvidia {
45 public enum NvStatus {
48 LIBRARY_NOT_FOUND = -2,
49 NO_IMPLEMENTATION = -3,
50 API_NOT_INTIALIZED = -4,
51 INVALID_ARGUMENT = -5,
52 NVIDIA_DEVICE_NOT_FOUND = -6,
55 INCOMPATIBLE_STRUCT_VERSION = -9,
56 HANDLE_INVALIDATED = -10,
57 OPENGL_CONTEXT_NOT_CURRENT = -11,
59 INSTRUMENTATION_DISABLED = -13,
60 EXPECTED_LOGICAL_GPU_HANDLE = -100,
61 EXPECTED_PHYSICAL_GPU_HANDLE = -101,
62 EXPECTED_DISPLAY_HANDLE = -102,
63 INVALID_COMBINATION = -103,
65 PORTID_NOT_FOUND = -105,
66 EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106,
67 INVALID_PERF_LEVEL = -107,
69 NV_PERSIST_FILE_NOT_FOUND = -109,
70 PERSIST_DATA_NOT_FOUND = -110,
71 EXPECTED_TV_DISPLAY = -111,
72 EXPECTED_TV_DISPLAY_ON_DCONNECTOR = -112,
73 NO_ACTIVE_SLI_TOPOLOGY = -113,
74 SLI_RENDERING_MODE_NOTALLOWED = -114,
75 EXPECTED_DIGITAL_FLAT_PANEL = -115,
76 ARGUMENT_EXCEED_MAX_SIZE = -116,
77 DEVICE_SWITCHING_NOT_ALLOWED = -117,
78 TESTING_CLOCKS_NOT_SUPPORTED = -118,
79 UNKNOWN_UNDERSCAN_CONFIG = -119,
80 TIMEOUT_RECONFIGURING_GPU_TOPO = -120,
81 DATA_NOT_FOUND = -121,
82 EXPECTED_ANALOG_DISPLAY = -122,
84 REQUIRES_REBOOT = -124,
85 INVALID_HYBRID_MODE = -125,
86 MIXED_TARGET_TYPES = -126,
87 SYSWOW64_NOT_SUPPORTED = -127,
88 IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED = -128,
89 REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS = -129,
91 WAS_STILL_DRAWING = -131,
92 FILE_NOT_FOUND = -132,
93 TOO_MANY_UNIQUE_STATE_OBJECTS = -133,
95 D3D10_1_LIBRARY_NOT_FOUND = -135,
96 FUNCTION_NOT_FOUND = -136
99 public enum NvThermalController {
115 public enum NvThermalTarget {
125 [StructLayout(LayoutKind.Sequential, Pack = 8)]
126 public struct NvSensor {
127 public NvThermalController Controller;
128 public uint DefaultMinTemp;
129 public uint DefaultMaxTemp;
130 public uint CurrentTemp;
131 public NvThermalTarget Target;
134 [StructLayout(LayoutKind.Sequential, Pack = 8)]
135 public struct NvGPUThermalSettings {
138 [MarshalAs(UnmanagedType.ByValArray,
139 SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)]
140 public NvSensor[] Sensor;
143 [StructLayout(LayoutKind.Sequential)]
144 public struct NvDisplayHandle {
148 [StructLayout(LayoutKind.Sequential)]
149 public struct NvPhysicalGpuHandle {
153 [StructLayout(LayoutKind.Sequential, Pack = 8)]
154 public struct NvClocks {
156 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_CLOCKS_PER_GPU)]
160 [StructLayout(LayoutKind.Sequential, Pack = 8)]
161 public struct NvPState {
163 public int Percentage;
166 [StructLayout(LayoutKind.Sequential, Pack = 8)]
167 public struct NvPStates {
170 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_PSTATES_PER_GPU)]
171 public NvPState[] PStates;
174 [StructLayout(LayoutKind.Sequential, Pack = 8)]
175 public struct NvUsages {
177 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_USAGES_PER_GPU)]
181 [StructLayout(LayoutKind.Sequential, Pack = 8)]
182 public struct NvCooler {
184 public int Controller;
185 public int DefaultMin;
186 public int DefaultMax;
187 public int CurrentMin;
188 public int CurrentMax;
189 public int CurrentLevel;
190 public int DefaultPolicy;
191 public int CurrentPolicy;
193 public int ControlType;
197 [StructLayout(LayoutKind.Sequential, Pack = 8)]
198 public struct NvGPUCoolerSettings {
201 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
202 public NvCooler[] Cooler;
205 [StructLayout(LayoutKind.Sequential, Pack = 8)]
206 public struct NvMemoryInfo {
208 [MarshalAs(UnmanagedType.ByValArray, SizeConst =
209 NVAPI.MAX_MEMORY_VALUES_PER_GPU)]
210 public uint[] Values;
213 [StructLayout(LayoutKind.Sequential, Pack = 8)]
214 public struct NvDisplayDriverVersion {
216 public uint DriverVersion;
217 public uint BldChangeListNum;
218 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
219 public string BuildBranch;
220 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
221 public string Adapter;
226 public const int MAX_PHYSICAL_GPUS = 64;
227 public const int SHORT_STRING_MAX = 64;
229 public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
230 public const int MAX_CLOCKS_PER_GPU = 0x120;
231 public const int MAX_PSTATES_PER_GPU = 8;
232 public const int MAX_USAGES_PER_GPU = 33;
233 public const int MAX_COOLER_PER_GPU = 20;
234 public const int MAX_MEMORY_VALUES_PER_GPU = 5;
236 public static readonly uint GPU_THERMAL_SETTINGS_VER = (uint)
237 Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000;
238 public static readonly uint GPU_CLOCKS_VER = (uint)
239 Marshal.SizeOf(typeof(NvClocks)) | 0x20000;
240 public static readonly uint GPU_PSTATES_VER = (uint)
241 Marshal.SizeOf(typeof(NvPStates)) | 0x10000;
242 public static readonly uint GPU_USAGES_VER = (uint)
243 Marshal.SizeOf(typeof(NvUsages)) | 0x10000;
244 public static readonly uint GPU_COOLER_SETTINGS_VER = (uint)
245 Marshal.SizeOf(typeof(NvGPUCoolerSettings)) | 0x20000;
246 public static readonly uint GPU_MEMORY_INFO_VER = (uint)
247 Marshal.SizeOf(typeof(NvMemoryInfo)) | 0x20000;
248 public static readonly uint DISPLAY_DRIVER_VERSION_VER = (uint)
249 Marshal.SizeOf(typeof(NvDisplayDriverVersion)) | 0x10000;
251 private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id);
252 private delegate NvStatus NvAPI_InitializeDelegate();
253 private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(
254 NvPhysicalGpuHandle gpuHandle, StringBuilder name);
256 public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(
257 NvPhysicalGpuHandle gpuHandle, int sensorIndex,
258 ref NvGPUThermalSettings nvGPUThermalSettings);
259 public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum,
260 ref NvDisplayHandle displayHandle);
261 public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(
262 NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles,
264 public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
265 [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
266 public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(
267 NvPhysicalGpuHandle gpuHandle, out int value);
268 public delegate NvStatus NvAPI_GPU_GetAllClocksDelegate(
269 NvPhysicalGpuHandle gpuHandle, ref NvClocks nvClocks);
270 public delegate NvStatus NvAPI_GPU_GetPStatesDelegate(
271 NvPhysicalGpuHandle gpuHandle, ref NvPStates nvPStates);
272 public delegate NvStatus NvAPI_GPU_GetUsagesDelegate(
273 NvPhysicalGpuHandle gpuHandle, ref NvUsages nvUsages);
274 public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate(
275 NvPhysicalGpuHandle gpuHandle, int coolerIndex,
276 ref NvGPUCoolerSettings nvGPUCoolerSettings);
277 public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate(
278 NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo);
279 public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate(
280 NvDisplayHandle displayHandle, [In, Out] ref NvDisplayDriverVersion
281 nvDisplayDriverVersion);
282 public delegate NvStatus NvAPI_GetInterfaceVersionStringDelegate(
283 StringBuilder version);
285 private static bool available = false;
286 private static nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
287 private static NvAPI_InitializeDelegate NvAPI_Initialize;
288 private static NvAPI_GPU_GetFullNameDelegate _NvAPI_GPU_GetFullName;
289 private static NvAPI_GetInterfaceVersionStringDelegate
290 _NvAPI_GetInterfaceVersionString;
292 public static readonly NvAPI_GPU_GetThermalSettingsDelegate
293 NvAPI_GPU_GetThermalSettings;
294 public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate
295 NvAPI_EnumNvidiaDisplayHandle;
296 public static readonly NvAPI_GetPhysicalGPUsFromDisplayDelegate
297 NvAPI_GetPhysicalGPUsFromDisplay;
298 public static readonly NvAPI_EnumPhysicalGPUsDelegate
299 NvAPI_EnumPhysicalGPUs;
300 public static readonly NvAPI_GPU_GetTachReadingDelegate
301 NvAPI_GPU_GetTachReading;
302 public static readonly NvAPI_GPU_GetAllClocksDelegate
303 NvAPI_GPU_GetAllClocks;
304 public static readonly NvAPI_GPU_GetPStatesDelegate
305 NvAPI_GPU_GetPStates;
306 public static readonly NvAPI_GPU_GetUsagesDelegate
308 public static readonly NvAPI_GPU_GetCoolerSettingsDelegate
309 NvAPI_GPU_GetCoolerSettings;
310 public static readonly NvAPI_GPU_GetMemoryInfoDelegate
311 NvAPI_GPU_GetMemoryInfo;
312 public static readonly NvAPI_GetDisplayDriverVersionDelegate
313 NvAPI_GetDisplayDriverVersion;
315 public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
317 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
319 if (_NvAPI_GPU_GetFullName != null)
320 status = _NvAPI_GPU_GetFullName(gpuHandle, builder);
322 status = NvStatus.FUNCTION_NOT_FOUND;
323 name = builder.ToString();
327 public static NvStatus NvAPI_GetInterfaceVersionString(out string version) {
328 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
330 if (_NvAPI_GetInterfaceVersionString != null)
331 status = _NvAPI_GetInterfaceVersionString(builder);
333 status = NvStatus.FUNCTION_NOT_FOUND;
334 version = builder.ToString();
338 private static string GetDllName() {
339 if (IntPtr.Size == 4) {
342 return "nvapi64.dll";
346 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(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
384 GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
385 GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
391 public static bool IsAvailable {
392 get { return available; }