# HG changeset patch # User moel.mich # Date 1277634267 0 # Node ID 04a5155c9c1a06dd8139b7325b77ce5a3be5d0b7 # Parent 9611b4d9d898807929b8bf13debe1789fdb1f912 Improved the support for Nvidia GPUs. diff -r 9611b4d9d898 -r 04a5155c9c1a Hardware/Nvidia/NVAPI.cs --- a/Hardware/Nvidia/NVAPI.cs Sat Jun 12 12:15:00 2010 +0000 +++ b/Hardware/Nvidia/NVAPI.cs Sun Jun 27 10:24:27 2010 +0000 @@ -125,16 +125,16 @@ [StructLayout(LayoutKind.Sequential, Pack = 8)] public struct NvSensor { public NvThermalController Controller; - public int DefaultMinTemp; - public int DefaultMaxTemp; - public int CurrentTemp; + public uint DefaultMinTemp; + public uint DefaultMaxTemp; + public uint CurrentTemp; public NvThermalTarget Target; } [StructLayout(LayoutKind.Sequential, Pack = 8)] public struct NvGPUThermalSettings { - public int Version; - public int Count; + public uint Version; + public uint Count; [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)] public NvSensor[] Sensor; @@ -150,15 +150,104 @@ private IntPtr ptr; } + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct NvClocks { + 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 { - - private const int SHORT_STRING_MAX = 64; - public const int MAX_THERMAL_SENSORS_PER_GPU = 3; 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; - + 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 NvStatus NvAPI_InitializeDelegate(); private delegate NvStatus NvAPI_GPU_GetFullNameDelegate( @@ -171,27 +260,57 @@ ref NvDisplayHandle displayHandle); public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate( NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles, - out int gpuCount); + out uint gpuCount); public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate( [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount); public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate( 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 nvapi_QueryInterfaceDelegate nvapi_QueryInterface; private static NvAPI_InitializeDelegate NvAPI_Initialize; 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; - public static NvAPI_EnumNvidiaDisplayHandleDelegate + public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate NvAPI_EnumNvidiaDisplayHandle; - public static NvAPI_GetPhysicalGPUsFromDisplayDelegate + public static readonly NvAPI_GetPhysicalGPUsFromDisplayDelegate NvAPI_GetPhysicalGPUsFromDisplay; - public static NvAPI_EnumPhysicalGPUsDelegate + public static readonly NvAPI_EnumPhysicalGPUsDelegate NvAPI_EnumPhysicalGPUs; - public static NvAPI_GPU_GetTachReadingDelegate + public static readonly NvAPI_GPU_GetTachReadingDelegate 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, out string name) { @@ -205,6 +324,17 @@ 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() { if (IntPtr.Size == 4) { return "nvapi.dll"; @@ -245,7 +375,15 @@ GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle); GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay); 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; } } diff -r 9611b4d9d898 -r 04a5155c9c1a Hardware/Nvidia/NvidiaGPU.cs --- a/Hardware/Nvidia/NvidiaGPU.cs Sat Jun 12 12:15:00 2010 +0000 +++ b/Hardware/Nvidia/NvidiaGPU.cs Sun Jun 27 10:24:27 2010 +0000 @@ -38,6 +38,7 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.Text; namespace OpenHardwareMonitor.Hardware.Nvidia { public class NvidiaGPU : Hardware, IHardware { @@ -46,11 +47,18 @@ private Image icon; private int adapterIndex; private NvPhysicalGpuHandle handle; + private NvDisplayHandle? displayHandle; private Sensor[] temperatures; 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; if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) { this.name = "NVIDIA " + gpuName.Trim(); @@ -60,6 +68,7 @@ this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png"); this.adapterIndex = adapterIndex; this.handle = handle; + this.displayHandle = displayHandle; NvGPUThermalSettings settings = GetThermalSettings(); temperatures = new Sensor[settings.Count]; @@ -87,6 +96,21 @@ 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 { @@ -106,13 +130,25 @@ 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]; - 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) { settings.Count = 0; } 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() { NvGPUThermalSettings settings = GetThermalSettings(); foreach (Sensor sensor in temperatures) @@ -123,6 +159,264 @@ NVAPI.NvAPI_GPU_GetTachReading(handle, out 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(); } } } diff -r 9611b4d9d898 -r 04a5155c9c1a Hardware/Nvidia/NvidiaGroup.cs --- a/Hardware/Nvidia/NvidiaGroup.cs Sat Jun 12 12:15:00 2010 +0000 +++ b/Hardware/Nvidia/NvidiaGroup.cs Sun Jun 27 10:24:27 2010 +0000 @@ -53,25 +53,68 @@ report.AppendLine("NVAPI"); report.AppendLine(); + string version; + if (NVAPI.NvAPI_GetInterfaceVersionString(out version) == NvStatus.OK) { + report.Append("Version: "); + report.AppendLine(version); + } + NvPhysicalGpuHandle[] handles = new NvPhysicalGpuHandle[NVAPI.MAX_PHYSICAL_GPUS]; - + int count; if (NVAPI.NvAPI_EnumPhysicalGPUs == null) { report.AppendLine("Error: NvAPI_EnumPhysicalGPUs not available"); report.AppendLine(); return; + } else { + NvStatus status = NVAPI.NvAPI_EnumPhysicalGPUs(handles, out count); + if (status != NvStatus.OK) { + report.AppendLine("Status: " + status.ToString()); + report.AppendLine(); + return; + } } - int count; - if (NVAPI.NvAPI_EnumPhysicalGPUs(handles, out count) != NvStatus.OK) - return; + IDictionary displayHandles = + new Dictionary(); + + 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.AppendLine(count.ToString()); + report.AppendLine(count.ToString()); + + 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)); + } + report.AppendLine(); - - for (int i = 0; i < count; i++) - hardware.Add(new NvidiaGPU(i, handles[i])); } public IHardware[] Hardware { @@ -84,7 +127,6 @@ return report.ToString(); } - public void Close() { - } + public void Close() { } } }