diff --git a/Hardware/Nvidia/NVAPI.cs b/Hardware/Nvidia/NVAPI.cs index 3cc1223..036188e 100644 --- a/Hardware/Nvidia/NVAPI.cs +++ b/Hardware/Nvidia/NVAPI.cs @@ -174,6 +174,8 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { out int gpuCount); public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate( [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount); + public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate( + NvPhysicalGpuHandle gpuHandle, out int value); private static bool available = false; private static nvapi_QueryInterfaceDelegate nvapi_QueryInterface; @@ -188,6 +190,8 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { NvAPI_GetPhysicalGPUsFromDisplay; public static NvAPI_EnumPhysicalGPUsDelegate NvAPI_EnumPhysicalGPUs; + public static NvAPI_GPU_GetTachReadingDelegate + NvAPI_GPU_GetTachReading; public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle, out string name) { @@ -209,7 +213,12 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { where T : class { IntPtr ptr = nvapi_QueryInterface(id); - newDelegate = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T; + if (ptr != IntPtr.Zero) { + newDelegate = + Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T; + } else { + newDelegate = null; + } } static NVAPI() { @@ -231,6 +240,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle); GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay); GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs); + GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading); available = true; } } diff --git a/Hardware/Nvidia/NvidiaGPU.cs b/Hardware/Nvidia/NvidiaGPU.cs index 577d6a9..3b1c090 100644 --- a/Hardware/Nvidia/NvidiaGPU.cs +++ b/Hardware/Nvidia/NvidiaGPU.cs @@ -40,7 +40,7 @@ using System.Collections.Generic; using System.Drawing; namespace OpenHardwareMonitor.Hardware.Nvidia { - public class NvidiaGPU : IHardware { + public class NvidiaGPU : Hardware, IHardware { private string name; private Image icon; @@ -48,12 +48,18 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { private NvPhysicalGpuHandle handle; private Sensor[] temperatures; + private Sensor fan = null; + + private bool available; public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle) { try { string gpuName; - NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName); - this.name = "NVIDIA " + gpuName; + if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) { + this.name = "NVIDIA " + gpuName.Trim(); + } else { + this.name = "NVIDIA"; + } this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png"); this.adapterIndex = adapterIndex; this.handle = handle; @@ -73,12 +79,28 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { } temperatures[i] = new Sensor(name, i, sensor.DefaultMaxTemp, SensorType.Temperature, this); + ActivateSensor(temperatures[i]); } + + int value; + if (NVAPI.NvAPI_GPU_GetTachReading != null && + NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) { + if (value > 0) { + fan = new Sensor("GPU", 0, SensorType.Fan, this); + ActivateSensor(fan); + } + } + + available = temperatures.Length > 0 || fan != null; } catch (Exception e) { System.Windows.Forms.MessageBox.Show(e.Message + "\n" + e.StackTrace); } } + public bool IsAvailable { + get { return available; } + } + public string Name { get { return name; } } @@ -91,12 +113,6 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { get { return icon; } } - public ISensor[] Sensors { - get { - return temperatures; - } - } - public string GetReport() { return null; } @@ -106,21 +122,23 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER; settings.Count = NVAPI.MAX_THERMAL_SENSORS_PER_GPU; settings.Sensor = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU]; - NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL, - ref settings); + if (NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL, + ref settings) != NvStatus.OK) { + settings.Count = 0; + } return settings; } public void Update() { NvGPUThermalSettings settings = GetThermalSettings(); foreach (Sensor sensor in temperatures) - sensor.Value = settings.Sensor[sensor.Index].CurrentTemp; + sensor.Value = settings.Sensor[sensor.Index].CurrentTemp; + + if (fan != null) { + int value = 0; + NVAPI.NvAPI_GPU_GetTachReading(handle, out value); + fan.Value = value; + } } - - #pragma warning disable 67 - public event SensorEventHandler SensorAdded; - public event SensorEventHandler SensorRemoved; - #pragma warning restore 67 - } } diff --git a/Hardware/Nvidia/NvidiaGroup.cs b/Hardware/Nvidia/NvidiaGroup.cs index 3e512ea..eed24a9 100644 --- a/Hardware/Nvidia/NvidiaGroup.cs +++ b/Hardware/Nvidia/NvidiaGroup.cs @@ -65,10 +65,9 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { report.AppendLine(); for (int i = 0; i < count; i++) { - string gpuName; - NVAPI.NvAPI_GPU_GetFullName(handles[i], out gpuName); - if (gpuName != null && gpuName.Trim() != "") - hardware.Add(new NvidiaGPU(i, handles[i])); + NvidiaGPU gpu = new NvidiaGPU(i, handles[i]); + if (gpu.IsAvailable) + hardware.Add(gpu); } } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index a2f2d35..721010f 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -69,5 +69,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.1.16.0")] -[assembly: AssemblyFileVersion("0.1.16.0")] +[assembly: AssemblyVersion("0.1.17.0")] +[assembly: AssemblyFileVersion("0.1.17.0")]