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