/Hardware/Nvidia/NVAPI.cs

http://open-hardware-monitor.googlecode.com/ · C# · 398 lines · 350 code · 38 blank · 10 comment · 12 complexity · c52c9d618b90357edae585968bf177e4 MD5 · raw file

  1. /*
  2. This Source Code Form is subject to the terms of the Mozilla Public
  3. License, v. 2.0. If a copy of the MPL was not distributed with this
  4. file, You can obtain one at http://mozilla.org/MPL/2.0/.
  5. Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
  6. Copyright (C) 2011 Christian Valličres
  7. */
  8. using System;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. namespace OpenHardwareMonitor.Hardware.Nvidia {
  12. internal enum NvStatus {
  13. OK = 0,
  14. ERROR = -1,
  15. LIBRARY_NOT_FOUND = -2,
  16. NO_IMPLEMENTATION = -3,
  17. API_NOT_INTIALIZED = -4,
  18. INVALID_ARGUMENT = -5,
  19. NVIDIA_DEVICE_NOT_FOUND = -6,
  20. END_ENUMERATION = -7,
  21. INVALID_HANDLE = -8,
  22. INCOMPATIBLE_STRUCT_VERSION = -9,
  23. HANDLE_INVALIDATED = -10,
  24. OPENGL_CONTEXT_NOT_CURRENT = -11,
  25. NO_GL_EXPERT = -12,
  26. INSTRUMENTATION_DISABLED = -13,
  27. EXPECTED_LOGICAL_GPU_HANDLE = -100,
  28. EXPECTED_PHYSICAL_GPU_HANDLE = -101,
  29. EXPECTED_DISPLAY_HANDLE = -102,
  30. INVALID_COMBINATION = -103,
  31. NOT_SUPPORTED = -104,
  32. PORTID_NOT_FOUND = -105,
  33. EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106,
  34. INVALID_PERF_LEVEL = -107,
  35. DEVICE_BUSY = -108,
  36. NV_PERSIST_FILE_NOT_FOUND = -109,
  37. PERSIST_DATA_NOT_FOUND = -110,
  38. EXPECTED_TV_DISPLAY = -111,
  39. EXPECTED_TV_DISPLAY_ON_DCONNECTOR = -112,
  40. NO_ACTIVE_SLI_TOPOLOGY = -113,
  41. SLI_RENDERING_MODE_NOTALLOWED = -114,
  42. EXPECTED_DIGITAL_FLAT_PANEL = -115,
  43. ARGUMENT_EXCEED_MAX_SIZE = -116,
  44. DEVICE_SWITCHING_NOT_ALLOWED = -117,
  45. TESTING_CLOCKS_NOT_SUPPORTED = -118,
  46. UNKNOWN_UNDERSCAN_CONFIG = -119,
  47. TIMEOUT_RECONFIGURING_GPU_TOPO = -120,
  48. DATA_NOT_FOUND = -121,
  49. EXPECTED_ANALOG_DISPLAY = -122,
  50. NO_VIDLINK = -123,
  51. REQUIRES_REBOOT = -124,
  52. INVALID_HYBRID_MODE = -125,
  53. MIXED_TARGET_TYPES = -126,
  54. SYSWOW64_NOT_SUPPORTED = -127,
  55. IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED = -128,
  56. REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS = -129,
  57. OUT_OF_MEMORY = -130,
  58. WAS_STILL_DRAWING = -131,
  59. FILE_NOT_FOUND = -132,
  60. TOO_MANY_UNIQUE_STATE_OBJECTS = -133,
  61. INVALID_CALL = -134,
  62. D3D10_1_LIBRARY_NOT_FOUND = -135,
  63. FUNCTION_NOT_FOUND = -136
  64. }
  65. internal enum NvThermalController {
  66. NONE = 0,
  67. GPU_INTERNAL,
  68. ADM1032,
  69. MAX6649,
  70. MAX1617,
  71. LM99,
  72. LM89,
  73. LM64,
  74. ADT7473,
  75. SBMAX6649,
  76. VBIOSEVT,
  77. OS,
  78. UNKNOWN = -1,
  79. }
  80. internal enum NvThermalTarget {
  81. NONE = 0,
  82. GPU = 1,
  83. MEMORY = 2,
  84. POWER_SUPPLY = 4,
  85. BOARD = 8,
  86. ALL = 15,
  87. UNKNOWN = -1
  88. };
  89. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  90. internal struct NvSensor {
  91. public NvThermalController Controller;
  92. public uint DefaultMinTemp;
  93. public uint DefaultMaxTemp;
  94. public uint CurrentTemp;
  95. public NvThermalTarget Target;
  96. }
  97. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  98. internal struct NvGPUThermalSettings {
  99. public uint Version;
  100. public uint Count;
  101. [MarshalAs(UnmanagedType.ByValArray,
  102. SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)]
  103. public NvSensor[] Sensor;
  104. }
  105. [StructLayout(LayoutKind.Sequential)]
  106. internal struct NvDisplayHandle {
  107. private readonly IntPtr ptr;
  108. }
  109. [StructLayout(LayoutKind.Sequential)]
  110. internal struct NvPhysicalGpuHandle {
  111. private readonly IntPtr ptr;
  112. }
  113. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  114. internal struct NvClocks {
  115. public uint Version;
  116. [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_CLOCKS_PER_GPU)]
  117. public uint[] Clock;
  118. }
  119. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  120. internal struct NvPState {
  121. public bool Present;
  122. public int Percentage;
  123. }
  124. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  125. internal struct NvPStates {
  126. public uint Version;
  127. public uint Flags;
  128. [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_PSTATES_PER_GPU)]
  129. public NvPState[] PStates;
  130. }
  131. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  132. internal struct NvUsages {
  133. public uint Version;
  134. [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_USAGES_PER_GPU)]
  135. public uint[] Usage;
  136. }
  137. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  138. internal struct NvCooler {
  139. public int Type;
  140. public int Controller;
  141. public int DefaultMin;
  142. public int DefaultMax;
  143. public int CurrentMin;
  144. public int CurrentMax;
  145. public int CurrentLevel;
  146. public int DefaultPolicy;
  147. public int CurrentPolicy;
  148. public int Target;
  149. public int ControlType;
  150. public int Active;
  151. }
  152. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  153. internal struct NvGPUCoolerSettings {
  154. public uint Version;
  155. public uint Count;
  156. [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
  157. public NvCooler[] Cooler;
  158. }
  159. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  160. internal struct NvLevel {
  161. public int Level;
  162. public int Policy;
  163. }
  164. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  165. internal struct NvGPUCoolerLevels {
  166. public uint Version;
  167. [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
  168. public NvLevel[] Levels;
  169. }
  170. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  171. internal struct NvMemoryInfo {
  172. public uint Version;
  173. [MarshalAs(UnmanagedType.ByValArray, SizeConst =
  174. NVAPI.MAX_MEMORY_VALUES_PER_GPU)]
  175. public uint[] Values;
  176. }
  177. [StructLayout(LayoutKind.Sequential, Pack = 8)]
  178. internal struct NvDisplayDriverVersion {
  179. public uint Version;
  180. public uint DriverVersion;
  181. public uint BldChangeListNum;
  182. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
  183. public string BuildBranch;
  184. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
  185. public string Adapter;
  186. }
  187. internal class NVAPI {
  188. public const int MAX_PHYSICAL_GPUS = 64;
  189. public const int SHORT_STRING_MAX = 64;
  190. public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
  191. public const int MAX_CLOCKS_PER_GPU = 0x120;
  192. public const int MAX_PSTATES_PER_GPU = 8;
  193. public const int MAX_USAGES_PER_GPU = 33;
  194. public const int MAX_COOLER_PER_GPU = 20;
  195. public const int MAX_MEMORY_VALUES_PER_GPU = 5;
  196. public static readonly uint GPU_THERMAL_SETTINGS_VER = (uint)
  197. Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000;
  198. public static readonly uint GPU_CLOCKS_VER = (uint)
  199. Marshal.SizeOf(typeof(NvClocks)) | 0x20000;
  200. public static readonly uint GPU_PSTATES_VER = (uint)
  201. Marshal.SizeOf(typeof(NvPStates)) | 0x10000;
  202. public static readonly uint GPU_USAGES_VER = (uint)
  203. Marshal.SizeOf(typeof(NvUsages)) | 0x10000;
  204. public static readonly uint GPU_COOLER_SETTINGS_VER = (uint)
  205. Marshal.SizeOf(typeof(NvGPUCoolerSettings)) | 0x20000;
  206. public static readonly uint GPU_MEMORY_INFO_VER = (uint)
  207. Marshal.SizeOf(typeof(NvMemoryInfo)) | 0x20000;
  208. public static readonly uint DISPLAY_DRIVER_VERSION_VER = (uint)
  209. Marshal.SizeOf(typeof(NvDisplayDriverVersion)) | 0x10000;
  210. public static readonly uint GPU_COOLER_LEVELS_VER = (uint)
  211. Marshal.SizeOf(typeof(NvGPUCoolerLevels)) | 0x10000;
  212. private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id);
  213. private delegate NvStatus NvAPI_InitializeDelegate();
  214. private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(
  215. NvPhysicalGpuHandle gpuHandle, StringBuilder name);
  216. public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(
  217. NvPhysicalGpuHandle gpuHandle, int sensorIndex,
  218. ref NvGPUThermalSettings nvGPUThermalSettings);
  219. public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum,
  220. ref NvDisplayHandle displayHandle);
  221. public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(
  222. NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles,
  223. out uint gpuCount);
  224. public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
  225. [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
  226. public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(
  227. NvPhysicalGpuHandle gpuHandle, out int value);
  228. public delegate NvStatus NvAPI_GPU_GetAllClocksDelegate(
  229. NvPhysicalGpuHandle gpuHandle, ref NvClocks nvClocks);
  230. public delegate NvStatus NvAPI_GPU_GetPStatesDelegate(
  231. NvPhysicalGpuHandle gpuHandle, ref NvPStates nvPStates);
  232. public delegate NvStatus NvAPI_GPU_GetUsagesDelegate(
  233. NvPhysicalGpuHandle gpuHandle, ref NvUsages nvUsages);
  234. public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate(
  235. NvPhysicalGpuHandle gpuHandle, int coolerIndex,
  236. ref NvGPUCoolerSettings nvGPUCoolerSettings);
  237. public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(
  238. NvPhysicalGpuHandle gpuHandle, int coolerIndex,
  239. ref NvGPUCoolerLevels NvGPUCoolerLevels);
  240. public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate(
  241. NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo);
  242. public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate(
  243. NvDisplayHandle displayHandle, [In, Out] ref NvDisplayDriverVersion
  244. nvDisplayDriverVersion);
  245. public delegate NvStatus NvAPI_GetInterfaceVersionStringDelegate(
  246. StringBuilder version);
  247. public delegate NvStatus NvAPI_GPU_GetPCIIdentifiersDelegate(
  248. NvPhysicalGpuHandle gpuHandle, out uint deviceId, out uint subSystemId,
  249. out uint revisionId, out uint extDeviceId);
  250. private static readonly bool available;
  251. private static readonly nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
  252. private static readonly NvAPI_InitializeDelegate NvAPI_Initialize;
  253. private static readonly NvAPI_GPU_GetFullNameDelegate
  254. _NvAPI_GPU_GetFullName;
  255. private static readonly NvAPI_GetInterfaceVersionStringDelegate
  256. _NvAPI_GetInterfaceVersionString;
  257. public static readonly NvAPI_GPU_GetThermalSettingsDelegate
  258. NvAPI_GPU_GetThermalSettings;
  259. public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate
  260. NvAPI_EnumNvidiaDisplayHandle;
  261. public static readonly NvAPI_GetPhysicalGPUsFromDisplayDelegate
  262. NvAPI_GetPhysicalGPUsFromDisplay;
  263. public static readonly NvAPI_EnumPhysicalGPUsDelegate
  264. NvAPI_EnumPhysicalGPUs;
  265. public static readonly NvAPI_GPU_GetTachReadingDelegate
  266. NvAPI_GPU_GetTachReading;
  267. public static readonly NvAPI_GPU_GetAllClocksDelegate
  268. NvAPI_GPU_GetAllClocks;
  269. public static readonly NvAPI_GPU_GetPStatesDelegate
  270. NvAPI_GPU_GetPStates;
  271. public static readonly NvAPI_GPU_GetUsagesDelegate
  272. NvAPI_GPU_GetUsages;
  273. public static readonly NvAPI_GPU_GetCoolerSettingsDelegate
  274. NvAPI_GPU_GetCoolerSettings;
  275. public static readonly NvAPI_GPU_SetCoolerLevelsDelegate
  276. NvAPI_GPU_SetCoolerLevels;
  277. public static readonly NvAPI_GPU_GetMemoryInfoDelegate
  278. NvAPI_GPU_GetMemoryInfo;
  279. public static readonly NvAPI_GetDisplayDriverVersionDelegate
  280. NvAPI_GetDisplayDriverVersion;
  281. public static readonly NvAPI_GPU_GetPCIIdentifiersDelegate
  282. NvAPI_GPU_GetPCIIdentifiers;
  283. private NVAPI() { }
  284. public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
  285. out string name) {
  286. StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
  287. NvStatus status;
  288. if (_NvAPI_GPU_GetFullName != null)
  289. status = _NvAPI_GPU_GetFullName(gpuHandle, builder);
  290. else
  291. status = NvStatus.FUNCTION_NOT_FOUND;
  292. name = builder.ToString();
  293. return status;
  294. }
  295. public static NvStatus NvAPI_GetInterfaceVersionString(out string version) {
  296. StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
  297. NvStatus status;
  298. if (_NvAPI_GetInterfaceVersionString != null)
  299. status = _NvAPI_GetInterfaceVersionString(builder);
  300. else
  301. status = NvStatus.FUNCTION_NOT_FOUND;
  302. version = builder.ToString();
  303. return status;
  304. }
  305. private static string GetDllName() {
  306. if (IntPtr.Size == 4) {
  307. return "nvapi.dll";
  308. } else {
  309. return "nvapi64.dll";
  310. }
  311. }
  312. private static void GetDelegate<T>(uint id, out T newDelegate)
  313. where T : class {
  314. IntPtr ptr = nvapi_QueryInterface(id);
  315. if (ptr != IntPtr.Zero) {
  316. newDelegate =
  317. Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
  318. } else {
  319. newDelegate = null;
  320. }
  321. }
  322. static NVAPI() {
  323. DllImportAttribute attribute = new DllImportAttribute(GetDllName());
  324. attribute.CallingConvention = CallingConvention.Cdecl;
  325. attribute.PreserveSig = true;
  326. attribute.EntryPoint = "nvapi_QueryInterface";
  327. PInvokeDelegateFactory.CreateDelegate(attribute,
  328. out nvapi_QueryInterface);
  329. try {
  330. GetDelegate(0x0150E828, out NvAPI_Initialize);
  331. } catch (DllNotFoundException) { return; }
  332. catch (EntryPointNotFoundException) { return; }
  333. catch (ArgumentNullException) { return; }
  334. if (NvAPI_Initialize() == NvStatus.OK) {
  335. GetDelegate(0xE3640A56, out NvAPI_GPU_GetThermalSettings);
  336. GetDelegate(0xCEEE8E9F, out _NvAPI_GPU_GetFullName);
  337. GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
  338. GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
  339. GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
  340. GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);
  341. GetDelegate(0x1BD69F49, out NvAPI_GPU_GetAllClocks);
  342. GetDelegate(0x60DED2ED, out NvAPI_GPU_GetPStates);
  343. GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
  344. GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings);
  345. GetDelegate(0x891FA0AE, out NvAPI_GPU_SetCoolerLevels);
  346. GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
  347. GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
  348. GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
  349. GetDelegate(0x2DDFB66E, out NvAPI_GPU_GetPCIIdentifiers);
  350. available = true;
  351. }
  352. }
  353. public static bool IsAvailable {
  354. get { return available; }
  355. }
  356. }
  357. }