Fixed Issue 97.
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 internal 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 internal enum NvThermalController {
115 internal enum NvThermalTarget {
125 [StructLayout(LayoutKind.Sequential, Pack = 8)]
126 internal 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 internal struct NvGPUThermalSettings {
138 [MarshalAs(UnmanagedType.ByValArray,
139 SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)]
140 public NvSensor[] Sensor;
143 [StructLayout(LayoutKind.Sequential)]
144 internal struct NvDisplayHandle {
148 [StructLayout(LayoutKind.Sequential)]
149 internal struct NvPhysicalGpuHandle {
153 [StructLayout(LayoutKind.Sequential, Pack = 8)]
154 internal struct NvClocks {
156 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_CLOCKS_PER_GPU)]
160 [StructLayout(LayoutKind.Sequential, Pack = 8)]
161 internal struct NvPState {
163 public int Percentage;
166 [StructLayout(LayoutKind.Sequential, Pack = 8)]
167 internal struct NvPStates {
170 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_PSTATES_PER_GPU)]
171 public NvPState[] PStates;
174 [StructLayout(LayoutKind.Sequential, Pack = 8)]
175 internal struct NvUsages {
177 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_USAGES_PER_GPU)]
181 [StructLayout(LayoutKind.Sequential, Pack = 8)]
182 internal 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 internal struct NvGPUCoolerSettings {
201 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
202 public NvCooler[] Cooler;
205 [StructLayout(LayoutKind.Sequential, Pack = 8)]
206 internal 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 internal 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;
224 internal class NVAPI {
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;
317 public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
319 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
321 if (_NvAPI_GPU_GetFullName != null)
322 status = _NvAPI_GPU_GetFullName(gpuHandle, builder);
324 status = NvStatus.FUNCTION_NOT_FOUND;
325 name = builder.ToString();
329 public static NvStatus NvAPI_GetInterfaceVersionString(out string version) {
330 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
332 if (_NvAPI_GetInterfaceVersionString != null)
333 status = _NvAPI_GetInterfaceVersionString(builder);
335 status = NvStatus.FUNCTION_NOT_FOUND;
336 version = builder.ToString();
340 private static string GetDllName() {
341 if (IntPtr.Size == 4) {
344 return "nvapi64.dll";
348 private static void GetDelegate<T>(uint id, out T newDelegate)
351 IntPtr ptr = nvapi_QueryInterface(id);
352 if (ptr != IntPtr.Zero) {
354 Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
361 DllImportAttribute attribute = new DllImportAttribute(GetDllName());
362 attribute.CallingConvention = CallingConvention.Cdecl;
363 attribute.PreserveSig = true;
364 attribute.EntryPoint = "nvapi_QueryInterface";
365 PInvokeDelegateFactory.CreateDelegate(attribute,
366 out nvapi_QueryInterface);
369 GetDelegate(0x0150E828, out NvAPI_Initialize);
370 } catch (DllNotFoundException) { return; }
371 catch (EntryPointNotFoundException) { return; }
372 catch (ArgumentNullException) { return; }
374 if (NvAPI_Initialize() == NvStatus.OK) {
375 GetDelegate(0xE3640A56, out NvAPI_GPU_GetThermalSettings);
376 GetDelegate(0xCEEE8E9F, out _NvAPI_GPU_GetFullName);
377 GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
378 GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
379 GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
380 GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);
381 GetDelegate(0x1BD69F49, out NvAPI_GPU_GetAllClocks);
382 GetDelegate(0x60DED2ED, out NvAPI_GPU_GetPStates);
383 GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
384 GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings);
385 GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
386 GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
387 GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
393 public static bool IsAvailable {
394 get { return available; }