Improved the support for Nvidia GPUs.

This commit is contained in:
Michael Möller
2010-06-27 10:24:27 +00:00
parent 22ead80405
commit e30e42ebf0
3 changed files with 504 additions and 30 deletions

View File

@@ -125,16 +125,16 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
[StructLayout(LayoutKind.Sequential, Pack = 8)] [StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvSensor { public struct NvSensor {
public NvThermalController Controller; public NvThermalController Controller;
public int DefaultMinTemp; public uint DefaultMinTemp;
public int DefaultMaxTemp; public uint DefaultMaxTemp;
public int CurrentTemp; public uint CurrentTemp;
public NvThermalTarget Target; public NvThermalTarget Target;
} }
[StructLayout(LayoutKind.Sequential, Pack = 8)] [StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvGPUThermalSettings { public struct NvGPUThermalSettings {
public int Version; public uint Version;
public int Count; public uint Count;
[MarshalAs(UnmanagedType.ByValArray, [MarshalAs(UnmanagedType.ByValArray,
SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)] SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)]
public NvSensor[] Sensor; public NvSensor[] Sensor;
@@ -150,15 +150,104 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
private IntPtr ptr; private IntPtr ptr;
} }
public class NVAPI { [StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvClocks {
private const int SHORT_STRING_MAX = 64; public uint Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_CLOCKS_PER_GPU)]
public uint[] Clock;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvPState {
public bool Present;
public int Percentage;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvPStates {
public uint Version;
public uint Flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_PSTATES_PER_GPU)]
public NvPState[] PStates;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvUsages {
public uint Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_USAGES_PER_GPU)]
public uint[] Usage;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvCooler {
public int Type;
public int Controller;
public int DefaultMin;
public int DefaultMax;
public int CurrentMin;
public int CurrentMax;
public int CurrentLevel;
public int DefaultPolicy;
public int CurrentPolicy;
public int Target;
public int ControlType;
public int Active;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvGPUCoolerSettings {
public uint Version;
public uint Count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
public NvCooler[] Cooler;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvMemoryInfo {
public uint Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst =
NVAPI.MAX_MEMORY_VALUES_PER_GPU)]
public uint[] Values;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvDisplayDriverVersion {
public uint Version;
public uint DriverVersion;
public uint BldChangeListNum;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
public string BuildBranch;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
public string Adapter;
}
public class NVAPI {
public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
public const int MAX_PHYSICAL_GPUS = 64; public const int MAX_PHYSICAL_GPUS = 64;
public static readonly int GPU_THERMAL_SETTINGS_VER = public const int SHORT_STRING_MAX = 64;
public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
public const int MAX_CLOCKS_PER_GPU = 0x120;
public const int MAX_PSTATES_PER_GPU = 8;
public const int MAX_USAGES_PER_GPU = 33;
public const int MAX_COOLER_PER_GPU = 20;
public const int MAX_MEMORY_VALUES_PER_GPU = 5;
public static readonly uint GPU_THERMAL_SETTINGS_VER = (uint)
Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000; Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000;
public static readonly uint GPU_CLOCKS_VER = (uint)
Marshal.SizeOf(typeof(NvClocks)) | 0x20000;
public static readonly uint GPU_PSTATES_VER = (uint)
Marshal.SizeOf(typeof(NvPStates)) | 0x10000;
public static readonly uint GPU_USAGES_VER = (uint)
Marshal.SizeOf(typeof(NvUsages)) | 0x10000;
public static readonly uint GPU_COOLER_SETTINGS_VER = (uint)
Marshal.SizeOf(typeof(NvGPUCoolerSettings)) | 0x20000;
public static readonly uint GPU_MEMORY_INFO_VER = (uint)
Marshal.SizeOf(typeof(NvMemoryInfo)) | 0x20000;
public static readonly uint DISPLAY_DRIVER_VERSION_VER = (uint)
Marshal.SizeOf(typeof(NvDisplayDriverVersion)) | 0x10000;
private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id); private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id);
private delegate NvStatus NvAPI_InitializeDelegate(); private delegate NvStatus NvAPI_InitializeDelegate();
private delegate NvStatus NvAPI_GPU_GetFullNameDelegate( private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(
@@ -171,27 +260,57 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
ref NvDisplayHandle displayHandle); ref NvDisplayHandle displayHandle);
public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate( public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(
NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles, NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles,
out int gpuCount); out uint gpuCount);
public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate( public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
[Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount); [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate( public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(
NvPhysicalGpuHandle gpuHandle, out int value); NvPhysicalGpuHandle gpuHandle, out int value);
public delegate NvStatus NvAPI_GPU_GetAllClocksDelegate(
NvPhysicalGpuHandle gpuHandle, ref NvClocks nvClocks);
public delegate NvStatus NvAPI_GPU_GetPStatesDelegate(
NvPhysicalGpuHandle gpuHandle, ref NvPStates nvPStates);
public delegate NvStatus NvAPI_GPU_GetUsagesDelegate(
NvPhysicalGpuHandle gpuHandle, ref NvUsages nvUsages);
public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate(
NvPhysicalGpuHandle gpuHandle, int coolerIndex,
ref NvGPUCoolerSettings nvGPUCoolerSettings);
public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate(
NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo);
public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate(
NvDisplayHandle displayHandle, [In, Out] ref NvDisplayDriverVersion
nvDisplayDriverVersion);
public delegate NvStatus NvAPI_GetInterfaceVersionStringDelegate(
StringBuilder version);
private static bool available = false; private static bool available = false;
private static nvapi_QueryInterfaceDelegate nvapi_QueryInterface; private static nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
private static NvAPI_InitializeDelegate NvAPI_Initialize; private static NvAPI_InitializeDelegate NvAPI_Initialize;
private static NvAPI_GPU_GetFullNameDelegate _NvAPI_GPU_GetFullName; private static NvAPI_GPU_GetFullNameDelegate _NvAPI_GPU_GetFullName;
private static NvAPI_GetInterfaceVersionStringDelegate
_NvAPI_GetInterfaceVersionString;
public static NvAPI_GPU_GetThermalSettingsDelegate public static readonly NvAPI_GPU_GetThermalSettingsDelegate
NvAPI_GPU_GetThermalSettings; NvAPI_GPU_GetThermalSettings;
public static NvAPI_EnumNvidiaDisplayHandleDelegate public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate
NvAPI_EnumNvidiaDisplayHandle; NvAPI_EnumNvidiaDisplayHandle;
public static NvAPI_GetPhysicalGPUsFromDisplayDelegate public static readonly NvAPI_GetPhysicalGPUsFromDisplayDelegate
NvAPI_GetPhysicalGPUsFromDisplay; NvAPI_GetPhysicalGPUsFromDisplay;
public static NvAPI_EnumPhysicalGPUsDelegate public static readonly NvAPI_EnumPhysicalGPUsDelegate
NvAPI_EnumPhysicalGPUs; NvAPI_EnumPhysicalGPUs;
public static NvAPI_GPU_GetTachReadingDelegate public static readonly NvAPI_GPU_GetTachReadingDelegate
NvAPI_GPU_GetTachReading; NvAPI_GPU_GetTachReading;
public static readonly NvAPI_GPU_GetAllClocksDelegate
NvAPI_GPU_GetAllClocks;
public static readonly NvAPI_GPU_GetPStatesDelegate
NvAPI_GPU_GetPStates;
public static readonly NvAPI_GPU_GetUsagesDelegate
NvAPI_GPU_GetUsages;
public static readonly NvAPI_GPU_GetCoolerSettingsDelegate
NvAPI_GPU_GetCoolerSettings;
public static readonly NvAPI_GPU_GetMemoryInfoDelegate
NvAPI_GPU_GetMemoryInfo;
public static readonly NvAPI_GetDisplayDriverVersionDelegate
NvAPI_GetDisplayDriverVersion;
public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle, public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
out string name) { out string name) {
@@ -205,6 +324,17 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
return status; return status;
} }
public static NvStatus NvAPI_GetInterfaceVersionString(out string version) {
StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
NvStatus status;
if (_NvAPI_GetInterfaceVersionString != null)
status = _NvAPI_GetInterfaceVersionString(builder);
else
status = NvStatus.FUNCTION_NOT_FOUND;
version = builder.ToString();
return status;
}
private static string GetDllName() { private static string GetDllName() {
if (IntPtr.Size == 4) { if (IntPtr.Size == 4) {
return "nvapi.dll"; return "nvapi.dll";
@@ -245,7 +375,15 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle); GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay); GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs); GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading); GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);
GetDelegate(0x1BD69F49, out NvAPI_GPU_GetAllClocks);
GetDelegate(0x60DED2ED, out NvAPI_GPU_GetPStates);
GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings);
GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
available = true; available = true;
} }
} }

View File

@@ -38,6 +38,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Text;
namespace OpenHardwareMonitor.Hardware.Nvidia { namespace OpenHardwareMonitor.Hardware.Nvidia {
public class NvidiaGPU : Hardware, IHardware { public class NvidiaGPU : Hardware, IHardware {
@@ -46,11 +47,18 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
private Image icon; private Image icon;
private int adapterIndex; private int adapterIndex;
private NvPhysicalGpuHandle handle; private NvPhysicalGpuHandle handle;
private NvDisplayHandle? displayHandle;
private Sensor[] temperatures; private Sensor[] temperatures;
private Sensor fan = null; private Sensor fan = null;
private Sensor[] clocks;
private Sensor[] loads;
private Sensor control;
private Sensor memoryLoad;
public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle) { public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle,
NvDisplayHandle? displayHandle)
{
string gpuName; string gpuName;
if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) { if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) {
this.name = "NVIDIA " + gpuName.Trim(); this.name = "NVIDIA " + gpuName.Trim();
@@ -60,6 +68,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png"); this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png");
this.adapterIndex = adapterIndex; this.adapterIndex = adapterIndex;
this.handle = handle; this.handle = handle;
this.displayHandle = displayHandle;
NvGPUThermalSettings settings = GetThermalSettings(); NvGPUThermalSettings settings = GetThermalSettings();
temperatures = new Sensor[settings.Count]; temperatures = new Sensor[settings.Count];
@@ -87,6 +96,21 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
ActivateSensor(fan); ActivateSensor(fan);
} }
} }
clocks = new Sensor[3];
clocks[0] = new Sensor("GPU Core", 0, SensorType.Clock, this);
clocks[1] = new Sensor("GPU Memory", 1, SensorType.Clock, this);
clocks[2] = new Sensor("GPU Shader", 2, SensorType.Clock, this);
for (int i = 0; i < clocks.Length; i++)
ActivateSensor(clocks[i]);
loads = new Sensor[3];
loads[0] = new Sensor("GPU Core", 0, SensorType.Load, this);
loads[1] = new Sensor("GPU Memory Controller", 1, SensorType.Load, this);
loads[2] = new Sensor("GPU Video Engine", 2, SensorType.Load, this);
memoryLoad = new Sensor("GPU Memory", 3, SensorType.Load, this);
control = new Sensor("GPU Fan", 0, SensorType.Control, this);
} }
public override string Name { public override string Name {
@@ -106,13 +130,25 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER; settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
settings.Count = NVAPI.MAX_THERMAL_SENSORS_PER_GPU; settings.Count = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
settings.Sensor = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU]; settings.Sensor = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
if (NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL, if (NVAPI.NvAPI_GPU_GetThermalSettings != null &&
NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
ref settings) != NvStatus.OK) { ref settings) != NvStatus.OK) {
settings.Count = 0; settings.Count = 0;
} }
return settings; return settings;
} }
private uint[] GetClocks() {
NvClocks clocks = new NvClocks();
clocks.Version = NVAPI.GPU_CLOCKS_VER;
clocks.Clock = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
if (NVAPI.NvAPI_GPU_GetAllClocks != null &&
NVAPI.NvAPI_GPU_GetAllClocks(handle, ref clocks) == NvStatus.OK) {
return clocks.Clock;
}
return null;
}
public override void Update() { public override void Update() {
NvGPUThermalSettings settings = GetThermalSettings(); NvGPUThermalSettings settings = GetThermalSettings();
foreach (Sensor sensor in temperatures) foreach (Sensor sensor in temperatures)
@@ -123,6 +159,264 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
NVAPI.NvAPI_GPU_GetTachReading(handle, out value); NVAPI.NvAPI_GPU_GetTachReading(handle, out value);
fan.Value = value; fan.Value = value;
} }
uint[] values = GetClocks();
if (values != null) {
clocks[0].Value = 0.001f * values[0];
clocks[1].Value = 0.001f * values[8];
clocks[2].Value = 0.001f * values[14];
if (values[30] != 0) {
clocks[0].Value = 0.0005f * values[30];
clocks[2].Value = 0.001f * values[30];
}
}
NvPStates states = new NvPStates();
states.Version = NVAPI.GPU_PSTATES_VER;
states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
if (NVAPI.NvAPI_GPU_GetPStates != null &&
NVAPI.NvAPI_GPU_GetPStates(handle, ref states) == NvStatus.OK) {
for (int i = 0; i < 3; i++)
if (states.PStates[i].Present) {
loads[i].Value = states.PStates[i].Percentage;
ActivateSensor(loads[i]);
}
} else {
NvUsages usages = new NvUsages();
usages.Version = NVAPI.GPU_USAGES_VER;
usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU];
if (NVAPI.NvAPI_GPU_GetUsages != null &&
NVAPI.NvAPI_GPU_GetUsages(handle, ref usages) == NvStatus.OK) {
loads[0].Value = usages.Usage[2];
loads[1].Value = usages.Usage[6];
loads[2].Value = usages.Usage[10];
for (int i = 0; i < 3; i++)
ActivateSensor(loads[i]);
}
}
NvGPUCoolerSettings coolerSettings = new NvGPUCoolerSettings();
coolerSettings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
coolerSettings.Cooler = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
if (NVAPI.NvAPI_GPU_GetCoolerSettings != null &&
NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, ref coolerSettings) ==
NvStatus.OK && coolerSettings.Count > 0) {
control.Value = coolerSettings.Cooler[0].CurrentLevel;
ActivateSensor(control);
}
NvMemoryInfo memoryInfo = new NvMemoryInfo();
memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue &&
NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value, ref memoryInfo) ==
NvStatus.OK)
{
uint totalMemory = memoryInfo.Values[0];
uint freeMemory = memoryInfo.Values[4];
float usedMemory = Math.Max(totalMemory - freeMemory, 0);
memoryLoad.Value = 100f * usedMemory / totalMemory;
ActivateSensor(memoryLoad);
}
}
public override string GetReport() {
StringBuilder r = new StringBuilder();
r.AppendLine("Nvidia GPU");
r.AppendLine();
r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
r.AppendFormat("Index: {0}{1}", adapterIndex, Environment.NewLine);
if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null)
{
NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();
driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value,
ref driverVersion) == NvStatus.OK) {
r.Append("Driver Version: ");
r.Append(driverVersion.DriverVersion / 100);
r.Append(".");
r.Append((driverVersion.DriverVersion % 100).ToString("00"));
r.AppendLine();
r.Append("Driver Branch: ");
r.AppendLine(driverVersion.BuildBranch);
}
}
r.AppendLine();
if (NVAPI.NvAPI_GPU_GetThermalSettings != null) {
NvGPUThermalSettings settings = new NvGPUThermalSettings();
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];
NvStatus status = NVAPI.NvAPI_GPU_GetThermalSettings(handle,
(int)NvThermalTarget.ALL, ref settings);
r.AppendLine("Thermal Settings");
r.AppendLine();
if (status == NvStatus.OK) {
for (int i = 0; i < settings.Count; i++) {
r.AppendFormat(" Sensor[{0}].Controller: {1}{2}", i,
settings.Sensor[i].Controller, Environment.NewLine);
r.AppendFormat(" Sensor[{0}].DefaultMinTemp: {1}{2}", i,
settings.Sensor[i].DefaultMinTemp, Environment.NewLine);
r.AppendFormat(" Sensor[{0}].DefaultMaxTemp: {1}{2}", i,
settings.Sensor[i].DefaultMaxTemp, Environment.NewLine);
r.AppendFormat(" Sensor[{0}].CurrentTemp: {1}{2}", i,
settings.Sensor[i].CurrentTemp, Environment.NewLine);
r.AppendFormat(" Sensor[{0}].Target: {1}{2}", i,
settings.Sensor[i].Target, Environment.NewLine);
}
} else {
r.Append(" Status: ");
r.AppendLine(status.ToString());
}
r.AppendLine();
}
if (NVAPI.NvAPI_GPU_GetAllClocks != null) {
NvClocks clocks = new NvClocks();
clocks.Version = NVAPI.GPU_CLOCKS_VER;
clocks.Clock = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
NvStatus status = NVAPI.NvAPI_GPU_GetAllClocks(handle, ref clocks);
r.AppendLine("Clocks");
r.AppendLine();
if (status == NvStatus.OK) {
for (int i = 0; i < clocks.Clock.Length; i++)
if (clocks.Clock[i] > 0) {
r.AppendFormat(" Clock[{0}]: {1}{2}", i, clocks.Clock[i],
Environment.NewLine);
}
} else {
r.Append(" Status: ");
r.AppendLine(status.ToString());
}
r.AppendLine();
}
if (NVAPI.NvAPI_GPU_GetTachReading != null) {
int tachValue;
NvStatus status = NVAPI.NvAPI_GPU_GetTachReading(handle, out tachValue);
r.AppendLine("Tachometer");
r.AppendLine();
if (status == NvStatus.OK) {
r.AppendFormat(" Value: {0}{1}", tachValue, Environment.NewLine);
} else {
r.Append(" Status: ");
r.AppendLine(status.ToString());
}
r.AppendLine();
}
if (NVAPI.NvAPI_GPU_GetPStates != null) {
NvPStates states = new NvPStates();
states.Version = NVAPI.GPU_PSTATES_VER;
states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
NvStatus status = NVAPI.NvAPI_GPU_GetPStates(handle, ref states);
r.AppendLine("P-States");
r.AppendLine();
if (status == NvStatus.OK) {
for (int i = 0; i < states.PStates.Length; i++)
if (states.PStates[i].Present)
r.AppendFormat(" Percentage[{0}]: {1}{2}", i,
states.PStates[i].Percentage, Environment.NewLine);
} else {
r.Append(" Status: ");
r.AppendLine(status.ToString());
}
r.AppendLine();
}
if (NVAPI.NvAPI_GPU_GetUsages != null) {
NvUsages usages = new NvUsages();
usages.Version = NVAPI.GPU_USAGES_VER;
usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU];
NvStatus status = NVAPI.NvAPI_GPU_GetUsages(handle, ref usages);
r.AppendLine("Usages");
r.AppendLine();
if (status == NvStatus.OK) {
for (int i = 0; i < usages.Usage.Length; i++)
if (usages.Usage[i] > 0)
r.AppendFormat(" Usage[{0}]: {1}{2}", i,
usages.Usage[i], Environment.NewLine);
} else {
r.Append(" Status: ");
r.AppendLine(status.ToString());
}
r.AppendLine();
}
if (NVAPI.NvAPI_GPU_GetCoolerSettings != null) {
NvGPUCoolerSettings settings = new NvGPUCoolerSettings();
settings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
settings.Cooler = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
NvStatus status =
NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, ref settings);
r.AppendLine("Cooler Settings");
r.AppendLine();
if (status == NvStatus.OK) {
for (int i = 0; i < settings.Count; i++) {
r.AppendFormat(" Cooler[{0}].Type: {1}{2}", i,
settings.Cooler[i].Type, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].Controller: {1}{2}", i,
settings.Cooler[i].Controller, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].DefaultMin: {1}{2}", i,
settings.Cooler[i].DefaultMin, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].DefaultMax: {1}{2}", i,
settings.Cooler[i].DefaultMax, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].CurrentMin: {1}{2}", i,
settings.Cooler[i].CurrentMin, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].CurrentMax: {1}{2}", i,
settings.Cooler[i].CurrentMax, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].CurrentLevel: {1}{2}", i,
settings.Cooler[i].CurrentLevel, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].DefaultPolicy: {1}{2}", i,
settings.Cooler[i].DefaultPolicy, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].CurrentPolicy: {1}{2}", i,
settings.Cooler[i].CurrentPolicy, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].Target: {1}{2}", i,
settings.Cooler[i].Target, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].ControlType: {1}{2}", i,
settings.Cooler[i].ControlType, Environment.NewLine);
r.AppendFormat(" Cooler[{0}].Active: {1}{2}", i,
settings.Cooler[i].Active, Environment.NewLine);
}
} else {
r.Append(" Status: ");
r.AppendLine(status.ToString());
}
r.AppendLine();
}
if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue) {
NvMemoryInfo memoryInfo = new NvMemoryInfo();
memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
NvStatus status = NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value,
ref memoryInfo);
r.AppendLine("Memory Info");
r.AppendLine();
if (status == NvStatus.OK) {
for (int i = 0; i < memoryInfo.Values.Length; i++)
r.AppendFormat(" Value[{0}]: {1}{2}", i,
memoryInfo.Values[i], Environment.NewLine);
} else {
r.Append(" Status: ");
r.AppendLine(status.ToString());
}
r.AppendLine();
}
return r.ToString();
} }
} }
} }

View File

@@ -53,25 +53,68 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
report.AppendLine("NVAPI"); report.AppendLine("NVAPI");
report.AppendLine(); report.AppendLine();
string version;
if (NVAPI.NvAPI_GetInterfaceVersionString(out version) == NvStatus.OK) {
report.Append("Version: ");
report.AppendLine(version);
}
NvPhysicalGpuHandle[] handles = NvPhysicalGpuHandle[] handles =
new NvPhysicalGpuHandle[NVAPI.MAX_PHYSICAL_GPUS]; new NvPhysicalGpuHandle[NVAPI.MAX_PHYSICAL_GPUS];
int count;
if (NVAPI.NvAPI_EnumPhysicalGPUs == null) { if (NVAPI.NvAPI_EnumPhysicalGPUs == null) {
report.AppendLine("Error: NvAPI_EnumPhysicalGPUs not available"); report.AppendLine("Error: NvAPI_EnumPhysicalGPUs not available");
report.AppendLine(); report.AppendLine();
return; return;
} else {
NvStatus status = NVAPI.NvAPI_EnumPhysicalGPUs(handles, out count);
if (status != NvStatus.OK) {
report.AppendLine("Status: " + status.ToString());
report.AppendLine();
return;
}
} }
int count; IDictionary<NvPhysicalGpuHandle, NvDisplayHandle> displayHandles =
if (NVAPI.NvAPI_EnumPhysicalGPUs(handles, out count) != NvStatus.OK) new Dictionary<NvPhysicalGpuHandle, NvDisplayHandle>();
return;
if (NVAPI.NvAPI_EnumNvidiaDisplayHandle != null &&
NVAPI.NvAPI_GetPhysicalGPUsFromDisplay != null)
{
NvStatus status = NvStatus.OK;
int i = 0;
while (status == NvStatus.OK) {
NvDisplayHandle displayHandle = new NvDisplayHandle();
status = NVAPI.NvAPI_EnumNvidiaDisplayHandle(i, ref displayHandle);
i++;
if (status == NvStatus.OK) {
NvPhysicalGpuHandle[] handlesFromDisplay =
new NvPhysicalGpuHandle[NVAPI.MAX_PHYSICAL_GPUS];
uint countFromDisplay;
if (NVAPI.NvAPI_GetPhysicalGPUsFromDisplay(displayHandle,
handlesFromDisplay, out countFromDisplay) == NvStatus.OK) {
for (int j = 0; j < countFromDisplay; j++) {
if (!displayHandles.ContainsKey(handlesFromDisplay[j]))
displayHandles.Add(handlesFromDisplay[j], displayHandle);
}
}
}
}
}
report.Append("Number of GPUs: "); report.Append("Number of GPUs: ");
report.AppendLine(count.ToString()); report.AppendLine(count.ToString());
report.AppendLine();
for (int i = 0; i < count; i++) {
NvDisplayHandle displayHandle;
if (displayHandles.TryGetValue(handles[i], out displayHandle))
hardware.Add(new NvidiaGPU(i, handles[i], displayHandle));
else
hardware.Add(new NvidiaGPU(i, handles[i], null));
}
for (int i = 0; i < count; i++) report.AppendLine();
hardware.Add(new NvidiaGPU(i, handles[i]));
} }
public IHardware[] Hardware { public IHardware[] Hardware {
@@ -84,7 +127,6 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
return report.ToString(); return report.ToString();
} }
public void Close() { public void Close() { }
}
} }
} }