Hardware/Nvidia/NVAPI.cs
author moel.mich
Thu, 28 Jan 2010 23:29:39 +0000
changeset 7 9523a3322777
child 38 0e09d845eb00
permissions -rw-r--r--
Release version 0.1.2. First implementation for Fintek F71882FG chips. Fixed Intel Core i7 temperature reading. Changed Nvidia GPU enumeration.
     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.Collections.Generic;
    40 using System.Runtime.InteropServices;
    41 using System.Text;
    42 
    43 namespace OpenHardwareMonitor.Hardware.Nvidia {
    44 
    45   public enum NvStatus {
    46     OK = 0,
    47     ERROR = -1,
    48     LIBRARY_NOT_FOUND = -2,
    49     NO_IMPLEMENTATION = -3,
    50     API_NOT_INTIALIZED = -4,
    51     INVALID_ARGUMENT = -5,
    52     NVIDIA_DEVICE_NOT_FOUND = -6,
    53     END_ENUMERATION = -7,
    54     INVALID_HANDLE = -8,
    55     INCOMPATIBLE_STRUCT_VERSION = -9,
    56     HANDLE_INVALIDATED = -10,
    57     OPENGL_CONTEXT_NOT_CURRENT = -11,
    58     NO_GL_EXPERT = -12,
    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,
    64     NOT_SUPPORTED = -104,
    65     PORTID_NOT_FOUND = -105,
    66     EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106,
    67     INVALID_PERF_LEVEL = -107,
    68     DEVICE_BUSY = -108,
    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,
    83     NO_VIDLINK = -123,
    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,
    90     OUT_OF_MEMORY = -130,
    91     WAS_STILL_DRAWING = -131,
    92     FILE_NOT_FOUND = -132,
    93     TOO_MANY_UNIQUE_STATE_OBJECTS = -133,
    94     INVALID_CALL = -134,
    95     D3D10_1_LIBRARY_NOT_FOUND = -135,
    96     FUNCTION_NOT_FOUND = -136
    97   }  
    98 
    99   public enum NvThermalController {
   100     NONE = 0,
   101     GPU_INTERNAL,  
   102     ADM1032,
   103     MAX6649,       
   104     MAX1617,      
   105     LM99,      
   106     LM89,         
   107     LM64,         
   108     ADT7473,
   109     SBMAX6649,
   110     VBIOSEVT,  
   111     OS,    
   112     UNKNOWN = -1,
   113   } 
   114 
   115   public enum NvThermalTarget {
   116     NONE = 0,
   117     GPU = 1,
   118     MEMORY = 2,
   119     POWER_SUPPLY = 4,
   120     BOARD = 8,
   121     ALL = 15,
   122     UNKNOWN = -1
   123   };
   124 
   125   [StructLayout(LayoutKind.Sequential)]
   126   public struct NvSensor {
   127     public NvThermalController Controller;
   128     public int DefaultMinTemp;
   129     public int DefaultMaxTemp;
   130     public int CurrentTemp;
   131     public NvThermalTarget Target;     
   132   }
   133 
   134   [StructLayout(LayoutKind.Sequential)]
   135   public struct NvGPUThermalSettings {
   136     public int Version;
   137     public int Count;
   138     [MarshalAs(UnmanagedType.ByValArray, 
   139       SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)]
   140     public NvSensor[] Sensor;
   141   }
   142 
   143   [StructLayout(LayoutKind.Sequential)]
   144   public struct NvDisplayHandle {
   145     private int handle;
   146   }
   147 
   148   [StructLayout(LayoutKind.Sequential)]
   149   public struct NvPhysicalGpuHandle {
   150     private int handle;
   151   }
   152 
   153   public class NVAPI {
   154           
   155     private const int SHORT_STRING_MAX = 64;
   156 
   157     public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
   158     public const int MAX_PHYSICAL_GPUS = 64;
   159     public static readonly int GPU_THERMAL_SETTINGS_VER =
   160       Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000;
   161             
   162     private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id);
   163     private delegate NvStatus NvAPI_InitializeDelegate();
   164     private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(
   165       NvPhysicalGpuHandle gpuHandle, StringBuilder name);
   166 
   167     public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(
   168       NvPhysicalGpuHandle gpuHandle, int sensorIndex, 
   169       ref NvGPUThermalSettings nvGPUThermalSettings);
   170     public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum,
   171       ref NvDisplayHandle displayHandle);
   172     public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(
   173       NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles, 
   174       out int gpuCount);
   175     public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
   176       [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
   177 
   178     private static bool available = false;
   179     private static nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
   180     private static NvAPI_InitializeDelegate NvAPI_Initialize;
   181     private static NvAPI_GPU_GetFullNameDelegate _NvAPI_GPU_GetFullName;
   182 
   183     public static NvAPI_GPU_GetThermalSettingsDelegate 
   184       NvAPI_GPU_GetThermalSettings;
   185     public static NvAPI_EnumNvidiaDisplayHandleDelegate
   186       NvAPI_EnumNvidiaDisplayHandle;
   187     public static NvAPI_GetPhysicalGPUsFromDisplayDelegate
   188       NvAPI_GetPhysicalGPUsFromDisplay;
   189     public static NvAPI_EnumPhysicalGPUsDelegate
   190       NvAPI_EnumPhysicalGPUs;
   191 
   192     public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
   193       out string name) {
   194       StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
   195       NvStatus status = _NvAPI_GPU_GetFullName(gpuHandle, builder);
   196       name = builder.ToString();
   197       return status;
   198     }
   199 
   200     private static string GetDllName() {
   201       if (IntPtr.Size == 4) {
   202         return "nvapi.dll";
   203       } else {
   204         return "nvapi64.dll";
   205       }
   206     }
   207 
   208     private static void GetDelegate<T>(uint id, out T newDelegate) 
   209       where T : class 
   210     {
   211       IntPtr ptr = nvapi_QueryInterface(id);
   212       newDelegate = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;      
   213     }
   214 
   215     static NVAPI() { 
   216       DllImportAttribute attribute = new DllImportAttribute(GetDllName());
   217       attribute.CallingConvention = CallingConvention.Cdecl;
   218       attribute.PreserveSig = true;
   219       attribute.EntryPoint = "nvapi_QueryInterface";
   220       PInvokeDelegateFactory.CreateDelegate(attribute,
   221         out nvapi_QueryInterface);
   222 
   223       try {
   224         GetDelegate(0x0150E828, out NvAPI_Initialize);
   225       } catch (DllNotFoundException) { return; } 
   226         catch (ArgumentNullException) { return; }
   227 
   228       if (NvAPI_Initialize() == NvStatus.OK) {
   229         GetDelegate(0xE3640A56, out NvAPI_GPU_GetThermalSettings);
   230         GetDelegate(0xCEEE8E9F, out _NvAPI_GPU_GetFullName);
   231         GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
   232         GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
   233         GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
   234         available = true;
   235       }
   236     }
   237 
   238     public static bool IsAvailable {
   239       get { return available; }
   240     }
   241 
   242   }
   243 }