Small corrections for AMD family 15h CPUs (based on documentation).
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-2011
20 the Initial Developer. All Rights Reserved.
25 Alternatively, the contents of this file may be used under the terms of
26 either the GNU General Public License Version 2 or later (the "GPL"), or
27 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 in which case the provisions of the GPL or the LGPL are applicable instead
29 of those above. If you wish to allow use of your version of this file only
30 under the terms of either the GPL or the LGPL, and not to allow others to
31 use your version of this file under the terms of the MPL, indicate your
32 decision by deleting the provisions above and replace them with the notice
33 and other provisions required by the GPL or the LGPL. If you do not delete
34 the provisions above, a recipient may use your version of this file under
35 the terms of any one of the MPL, the GPL or the LGPL.
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 {
145 private readonly IntPtr ptr;
148 [StructLayout(LayoutKind.Sequential)]
149 internal struct NvPhysicalGpuHandle {
150 private readonly IntPtr ptr;
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 NvLevel {
211 [StructLayout(LayoutKind.Sequential, Pack = 8)]
212 internal struct NvGPUCoolerLevels {
214 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
215 public NvLevel[] Levels;
218 [StructLayout(LayoutKind.Sequential, Pack = 8)]
219 internal struct NvMemoryInfo {
221 [MarshalAs(UnmanagedType.ByValArray, SizeConst =
222 NVAPI.MAX_MEMORY_VALUES_PER_GPU)]
223 public uint[] Values;
226 [StructLayout(LayoutKind.Sequential, Pack = 8)]
227 internal struct NvDisplayDriverVersion {
229 public uint DriverVersion;
230 public uint BldChangeListNum;
231 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
232 public string BuildBranch;
233 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
234 public string Adapter;
237 internal class NVAPI {
239 public const int MAX_PHYSICAL_GPUS = 64;
240 public const int SHORT_STRING_MAX = 64;
242 public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
243 public const int MAX_CLOCKS_PER_GPU = 0x120;
244 public const int MAX_PSTATES_PER_GPU = 8;
245 public const int MAX_USAGES_PER_GPU = 33;
246 public const int MAX_COOLER_PER_GPU = 20;
247 public const int MAX_MEMORY_VALUES_PER_GPU = 5;
249 public static readonly uint GPU_THERMAL_SETTINGS_VER = (uint)
250 Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000;
251 public static readonly uint GPU_CLOCKS_VER = (uint)
252 Marshal.SizeOf(typeof(NvClocks)) | 0x20000;
253 public static readonly uint GPU_PSTATES_VER = (uint)
254 Marshal.SizeOf(typeof(NvPStates)) | 0x10000;
255 public static readonly uint GPU_USAGES_VER = (uint)
256 Marshal.SizeOf(typeof(NvUsages)) | 0x10000;
257 public static readonly uint GPU_COOLER_SETTINGS_VER = (uint)
258 Marshal.SizeOf(typeof(NvGPUCoolerSettings)) | 0x20000;
259 public static readonly uint GPU_MEMORY_INFO_VER = (uint)
260 Marshal.SizeOf(typeof(NvMemoryInfo)) | 0x20000;
261 public static readonly uint DISPLAY_DRIVER_VERSION_VER = (uint)
262 Marshal.SizeOf(typeof(NvDisplayDriverVersion)) | 0x10000;
263 public static readonly uint GPU_COOLER_LEVELS_VER = (uint)
264 Marshal.SizeOf(typeof(NvGPUCoolerLevels)) | 0x10000;
266 private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id);
267 private delegate NvStatus NvAPI_InitializeDelegate();
268 private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(
269 NvPhysicalGpuHandle gpuHandle, StringBuilder name);
271 public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(
272 NvPhysicalGpuHandle gpuHandle, int sensorIndex,
273 ref NvGPUThermalSettings nvGPUThermalSettings);
274 public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum,
275 ref NvDisplayHandle displayHandle);
276 public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(
277 NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles,
279 public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
280 [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
281 public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(
282 NvPhysicalGpuHandle gpuHandle, out int value);
283 public delegate NvStatus NvAPI_GPU_GetAllClocksDelegate(
284 NvPhysicalGpuHandle gpuHandle, ref NvClocks nvClocks);
285 public delegate NvStatus NvAPI_GPU_GetPStatesDelegate(
286 NvPhysicalGpuHandle gpuHandle, ref NvPStates nvPStates);
287 public delegate NvStatus NvAPI_GPU_GetUsagesDelegate(
288 NvPhysicalGpuHandle gpuHandle, ref NvUsages nvUsages);
289 public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate(
290 NvPhysicalGpuHandle gpuHandle, int coolerIndex,
291 ref NvGPUCoolerSettings nvGPUCoolerSettings);
292 public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(
293 NvPhysicalGpuHandle gpuHandle, int coolerIndex,
294 ref NvGPUCoolerLevels NvGPUCoolerLevels);
295 public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate(
296 NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo);
297 public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate(
298 NvDisplayHandle displayHandle, [In, Out] ref NvDisplayDriverVersion
299 nvDisplayDriverVersion);
300 public delegate NvStatus NvAPI_GetInterfaceVersionStringDelegate(
301 StringBuilder version);
303 private static readonly bool available;
304 private static readonly nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
305 private static readonly NvAPI_InitializeDelegate NvAPI_Initialize;
306 private static readonly NvAPI_GPU_GetFullNameDelegate
307 _NvAPI_GPU_GetFullName;
308 private static readonly NvAPI_GetInterfaceVersionStringDelegate
309 _NvAPI_GetInterfaceVersionString;
311 public static readonly NvAPI_GPU_GetThermalSettingsDelegate
312 NvAPI_GPU_GetThermalSettings;
313 public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate
314 NvAPI_EnumNvidiaDisplayHandle;
315 public static readonly NvAPI_GetPhysicalGPUsFromDisplayDelegate
316 NvAPI_GetPhysicalGPUsFromDisplay;
317 public static readonly NvAPI_EnumPhysicalGPUsDelegate
318 NvAPI_EnumPhysicalGPUs;
319 public static readonly NvAPI_GPU_GetTachReadingDelegate
320 NvAPI_GPU_GetTachReading;
321 public static readonly NvAPI_GPU_GetAllClocksDelegate
322 NvAPI_GPU_GetAllClocks;
323 public static readonly NvAPI_GPU_GetPStatesDelegate
324 NvAPI_GPU_GetPStates;
325 public static readonly NvAPI_GPU_GetUsagesDelegate
327 public static readonly NvAPI_GPU_GetCoolerSettingsDelegate
328 NvAPI_GPU_GetCoolerSettings;
329 public static readonly NvAPI_GPU_SetCoolerLevelsDelegate
330 NvAPI_GPU_SetCoolerLevels;
331 public static readonly NvAPI_GPU_GetMemoryInfoDelegate
332 NvAPI_GPU_GetMemoryInfo;
333 public static readonly NvAPI_GetDisplayDriverVersionDelegate
334 NvAPI_GetDisplayDriverVersion;
338 public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
340 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
342 if (_NvAPI_GPU_GetFullName != null)
343 status = _NvAPI_GPU_GetFullName(gpuHandle, builder);
345 status = NvStatus.FUNCTION_NOT_FOUND;
346 name = builder.ToString();
350 public static NvStatus NvAPI_GetInterfaceVersionString(out string version) {
351 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
353 if (_NvAPI_GetInterfaceVersionString != null)
354 status = _NvAPI_GetInterfaceVersionString(builder);
356 status = NvStatus.FUNCTION_NOT_FOUND;
357 version = builder.ToString();
361 private static string GetDllName() {
362 if (IntPtr.Size == 4) {
365 return "nvapi64.dll";
369 private static void GetDelegate<T>(uint id, out T newDelegate)
371 IntPtr ptr = nvapi_QueryInterface(id);
372 if (ptr != IntPtr.Zero) {
374 Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
381 DllImportAttribute attribute = new DllImportAttribute(GetDllName());
382 attribute.CallingConvention = CallingConvention.Cdecl;
383 attribute.PreserveSig = true;
384 attribute.EntryPoint = "nvapi_QueryInterface";
385 PInvokeDelegateFactory.CreateDelegate(attribute,
386 out nvapi_QueryInterface);
389 GetDelegate(0x0150E828, out NvAPI_Initialize);
390 } catch (DllNotFoundException) { return; }
391 catch (EntryPointNotFoundException) { return; }
392 catch (ArgumentNullException) { return; }
394 if (NvAPI_Initialize() == NvStatus.OK) {
395 GetDelegate(0xE3640A56, out NvAPI_GPU_GetThermalSettings);
396 GetDelegate(0xCEEE8E9F, out _NvAPI_GPU_GetFullName);
397 GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
398 GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
399 GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
400 GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);
401 GetDelegate(0x1BD69F49, out NvAPI_GPU_GetAllClocks);
402 GetDelegate(0x60DED2ED, out NvAPI_GPU_GetPStates);
403 GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
404 GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings);
405 GetDelegate(0x891FA0AE, out NvAPI_GPU_SetCoolerLevels);
406 GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
407 GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
408 GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
414 public static bool IsAvailable {
415 get { return available; }