Added fan control for Nvidia GPUs based on a patch by Christian Vallières.

This commit is contained in:
Michael Möller
2011-07-07 21:53:09 +00:00
parent 938263fef2
commit 58f6092983
2 changed files with 139 additions and 53 deletions
+44 -23
View File
@@ -16,10 +16,11 @@
The Initial Developer of the Original Code is The Initial Developer of the Original Code is
Michael Möller <m.moeller@gmx.ch>. Michael Möller <m.moeller@gmx.ch>.
Portions created by the Initial Developer are Copyright (C) 2009-2010 Portions created by the Initial Developer are Copyright (C) 2009-2011
the Initial Developer. All Rights Reserved. the Initial Developer. All Rights Reserved.
Contributor(s): Contributor(s):
Christian Vallières
Alternatively, the contents of this file may be used under the terms of Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -97,17 +98,17 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
internal enum NvThermalController { internal enum NvThermalController {
NONE = 0, NONE = 0,
GPU_INTERNAL, GPU_INTERNAL,
ADM1032, ADM1032,
MAX6649, MAX6649,
MAX1617, MAX1617,
LM99, LM99,
LM89, LM89,
LM64, LM64,
ADT7473, ADT7473,
SBMAX6649, SBMAX6649,
VBIOSEVT, VBIOSEVT,
OS, OS,
UNKNOWN = -1, UNKNOWN = -1,
} }
@@ -127,14 +128,14 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
public uint DefaultMinTemp; public uint DefaultMinTemp;
public uint DefaultMaxTemp; public uint DefaultMaxTemp;
public uint CurrentTemp; public uint CurrentTemp;
public NvThermalTarget Target; public NvThermalTarget Target;
} }
[StructLayout(LayoutKind.Sequential, Pack = 8)] [StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvGPUThermalSettings { internal struct NvGPUThermalSettings {
public uint Version; public uint Version;
public uint 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;
} }
@@ -201,10 +202,23 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
public NvCooler[] Cooler; public NvCooler[] Cooler;
} }
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvLevel {
public int Level;
public int Policy;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvGPUCoolerLevels {
public uint Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
public NvLevel[] Levels;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)] [StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvMemoryInfo { internal struct NvMemoryInfo {
public uint Version; public uint Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = [MarshalAs(UnmanagedType.ByValArray, SizeConst =
NVAPI.MAX_MEMORY_VALUES_PER_GPU)] NVAPI.MAX_MEMORY_VALUES_PER_GPU)]
public uint[] Values; public uint[] Values;
} }
@@ -225,7 +239,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
public const int MAX_PHYSICAL_GPUS = 64; public const int MAX_PHYSICAL_GPUS = 64;
public const int SHORT_STRING_MAX = 64; public const int SHORT_STRING_MAX = 64;
public const int MAX_THERMAL_SENSORS_PER_GPU = 3; public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
public const int MAX_CLOCKS_PER_GPU = 0x120; public const int MAX_CLOCKS_PER_GPU = 0x120;
public const int MAX_PSTATES_PER_GPU = 8; public const int MAX_PSTATES_PER_GPU = 8;
public const int MAX_USAGES_PER_GPU = 33; public const int MAX_USAGES_PER_GPU = 33;
@@ -242,23 +256,25 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
Marshal.SizeOf(typeof(NvUsages)) | 0x10000; Marshal.SizeOf(typeof(NvUsages)) | 0x10000;
public static readonly uint GPU_COOLER_SETTINGS_VER = (uint) public static readonly uint GPU_COOLER_SETTINGS_VER = (uint)
Marshal.SizeOf(typeof(NvGPUCoolerSettings)) | 0x20000; Marshal.SizeOf(typeof(NvGPUCoolerSettings)) | 0x20000;
public static readonly uint GPU_MEMORY_INFO_VER = (uint) public static readonly uint GPU_MEMORY_INFO_VER = (uint)
Marshal.SizeOf(typeof(NvMemoryInfo)) | 0x20000; Marshal.SizeOf(typeof(NvMemoryInfo)) | 0x20000;
public static readonly uint DISPLAY_DRIVER_VERSION_VER = (uint) public static readonly uint DISPLAY_DRIVER_VERSION_VER = (uint)
Marshal.SizeOf(typeof(NvDisplayDriverVersion)) | 0x10000; Marshal.SizeOf(typeof(NvDisplayDriverVersion)) | 0x10000;
public static readonly uint GPU_COOLER_LEVELS_VER = (uint)
Marshal.SizeOf(typeof(NvGPUCoolerLevels)) | 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(
NvPhysicalGpuHandle gpuHandle, StringBuilder name); NvPhysicalGpuHandle gpuHandle, StringBuilder name);
public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate( public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(
NvPhysicalGpuHandle gpuHandle, int sensorIndex, NvPhysicalGpuHandle gpuHandle, int sensorIndex,
ref NvGPUThermalSettings nvGPUThermalSettings); ref NvGPUThermalSettings nvGPUThermalSettings);
public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum, public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum,
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 uint 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);
@@ -273,6 +289,9 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate( public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate(
NvPhysicalGpuHandle gpuHandle, int coolerIndex, NvPhysicalGpuHandle gpuHandle, int coolerIndex,
ref NvGPUCoolerSettings nvGPUCoolerSettings); ref NvGPUCoolerSettings nvGPUCoolerSettings);
public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(
NvPhysicalGpuHandle gpuHandle, int coolerIndex,
ref NvGPUCoolerLevels NvGPUCoolerLevels);
public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate( public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate(
NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo); NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo);
public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate( public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate(
@@ -284,12 +303,12 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
private static readonly bool available; private static readonly bool available;
private static readonly nvapi_QueryInterfaceDelegate nvapi_QueryInterface; private static readonly nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
private static readonly NvAPI_InitializeDelegate NvAPI_Initialize; private static readonly NvAPI_InitializeDelegate NvAPI_Initialize;
private static readonly NvAPI_GPU_GetFullNameDelegate private static readonly NvAPI_GPU_GetFullNameDelegate
_NvAPI_GPU_GetFullName; _NvAPI_GPU_GetFullName;
private static readonly NvAPI_GetInterfaceVersionStringDelegate private static readonly NvAPI_GetInterfaceVersionStringDelegate
_NvAPI_GetInterfaceVersionString; _NvAPI_GetInterfaceVersionString;
public static readonly NvAPI_GPU_GetThermalSettingsDelegate public static readonly NvAPI_GPU_GetThermalSettingsDelegate
NvAPI_GPU_GetThermalSettings; NvAPI_GPU_GetThermalSettings;
public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate
NvAPI_EnumNvidiaDisplayHandle; NvAPI_EnumNvidiaDisplayHandle;
@@ -307,6 +326,8 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
NvAPI_GPU_GetUsages; NvAPI_GPU_GetUsages;
public static readonly NvAPI_GPU_GetCoolerSettingsDelegate public static readonly NvAPI_GPU_GetCoolerSettingsDelegate
NvAPI_GPU_GetCoolerSettings; NvAPI_GPU_GetCoolerSettings;
public static readonly NvAPI_GPU_SetCoolerLevelsDelegate
NvAPI_GPU_SetCoolerLevels;
public static readonly NvAPI_GPU_GetMemoryInfoDelegate public static readonly NvAPI_GPU_GetMemoryInfoDelegate
NvAPI_GPU_GetMemoryInfo; NvAPI_GPU_GetMemoryInfo;
public static readonly NvAPI_GetDisplayDriverVersionDelegate public static readonly NvAPI_GetDisplayDriverVersionDelegate
@@ -345,9 +366,8 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
} }
} }
private static void GetDelegate<T>(uint id, out T newDelegate) private static void GetDelegate<T>(uint id, out T newDelegate)
where T : class where T : class {
{
IntPtr ptr = nvapi_QueryInterface(id); IntPtr ptr = nvapi_QueryInterface(id);
if (ptr != IntPtr.Zero) { if (ptr != IntPtr.Zero) {
newDelegate = newDelegate =
@@ -357,7 +377,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
} }
} }
static NVAPI() { static NVAPI() {
DllImportAttribute attribute = new DllImportAttribute(GetDllName()); DllImportAttribute attribute = new DllImportAttribute(GetDllName());
attribute.CallingConvention = CallingConvention.Cdecl; attribute.CallingConvention = CallingConvention.Cdecl;
attribute.PreserveSig = true; attribute.PreserveSig = true;
@@ -382,6 +402,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
GetDelegate(0x60DED2ED, out NvAPI_GPU_GetPStates); GetDelegate(0x60DED2ED, out NvAPI_GPU_GetPStates);
GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages); GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings); GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings);
GetDelegate(0x891FA0AE, out NvAPI_GPU_SetCoolerLevels);
GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo); GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion); GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString); GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
+95 -30
View File
@@ -20,6 +20,7 @@
the Initial Developer. All Rights Reserved. the Initial Developer. All Rights Reserved.
Contributor(s): Contributor(s):
Christian Vallières
Alternatively, the contents of this file may be used under the terms of Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -52,12 +53,15 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
private readonly Sensor[] loads; private readonly Sensor[] loads;
private readonly Sensor control; private readonly Sensor control;
private readonly Sensor memoryLoad; private readonly Sensor memoryLoad;
private readonly Control fanControl;
public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle, private bool restoreDefaultFanSpeedRequired;
NvDisplayHandle? displayHandle, ISettings settings) private NvLevel initialFanSpeedValue;
: base(GetName(handle), new Identifier("nvidiagpu",
adapterIndex.ToString(CultureInfo.InvariantCulture)), settings) public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle,
{ NvDisplayHandle? displayHandle, ISettings settings)
: base(GetName(handle), new Identifier("nvidiagpu",
adapterIndex.ToString(CultureInfo.InvariantCulture)), settings) {
this.adapterIndex = adapterIndex; this.adapterIndex = adapterIndex;
this.handle = handle; this.handle = handle;
this.displayHandle = displayHandle; this.displayHandle = displayHandle;
@@ -103,6 +107,18 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
memoryLoad = new Sensor("GPU Memory", 3, SensorType.Load, this, settings); memoryLoad = new Sensor("GPU Memory", 3, SensorType.Load, this, settings);
control = new Sensor("GPU Fan", 0, SensorType.Control, this, settings); control = new Sensor("GPU Fan", 0, SensorType.Control, this, settings);
NvGPUCoolerSettings coolerSettings = GetCoolerSettings();
if (coolerSettings.Count > 0) {
fanControl = new Control(control, settings,
coolerSettings.Cooler[0].DefaultMin,
coolerSettings.Cooler[0].DefaultMax);
fanControl.ControlModeChanged += ControlModeChanged;
fanControl.SoftwareControlValueChanged += SoftwareControlValueChanged;
ControlModeChanged(fanControl);
control.Control = fanControl;
}
Update();
} }
private static string GetName(NvPhysicalGpuHandle handle) { private static string GetName(NvPhysicalGpuHandle handle) {
@@ -123,12 +139,26 @@ 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 != null && if (!(NVAPI.NvAPI_GPU_GetThermalSettings != null &&
NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL, NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
ref settings) != NvStatus.OK) { ref settings) == NvStatus.OK))
settings.Count = 0; {
settings.Count = 0;
}
return settings;
}
private NvGPUCoolerSettings GetCoolerSettings() {
NvGPUCoolerSettings settings = new NvGPUCoolerSettings();
settings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
settings.Cooler = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
if (!(NVAPI.NvAPI_GPU_GetCoolerSettings != null &&
NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0,
ref settings) == NvStatus.OK))
{
settings.Count = 0;
} }
return settings; return settings;
} }
private uint[] GetClocks() { private uint[] GetClocks() {
@@ -144,7 +174,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
public override void Update() { public override void Update() {
NvGPUThermalSettings settings = GetThermalSettings(); NvGPUThermalSettings settings = GetThermalSettings();
foreach (Sensor sensor in temperatures) foreach (Sensor sensor in temperatures)
sensor.Value = settings.Sensor[sensor.Index].CurrentTemp; sensor.Value = settings.Sensor[sensor.Index].CurrentTemp;
if (fan != null) { if (fan != null) {
@@ -167,7 +197,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
NvPStates states = new NvPStates(); NvPStates states = new NvPStates();
states.Version = NVAPI.GPU_PSTATES_VER; states.Version = NVAPI.GPU_PSTATES_VER;
states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU]; states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
if (NVAPI.NvAPI_GPU_GetPStates != null && if (NVAPI.NvAPI_GPU_GetPStates != null &&
NVAPI.NvAPI_GPU_GetPStates(handle, ref states) == NvStatus.OK) { NVAPI.NvAPI_GPU_GetPStates(handle, ref states) == NvStatus.OK) {
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
if (states.PStates[i].Present) { if (states.PStates[i].Present) {
@@ -188,12 +218,9 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
} }
} }
NvGPUCoolerSettings coolerSettings = new NvGPUCoolerSettings();
coolerSettings.Version = NVAPI.GPU_COOLER_SETTINGS_VER; NvGPUCoolerSettings coolerSettings = GetCoolerSettings();
coolerSettings.Cooler = new NvCooler[NVAPI.MAX_COOLER_PER_GPU]; if (coolerSettings.Count > 0) {
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; control.Value = coolerSettings.Cooler[0].CurrentLevel;
ActivateSensor(control); ActivateSensor(control);
} }
@@ -202,9 +229,8 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER; memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU]; memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue && if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue &&
NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value, ref memoryInfo) == NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value, ref memoryInfo) ==
NvStatus.OK) NvStatus.OK) {
{
uint totalMemory = memoryInfo.Values[0]; uint totalMemory = memoryInfo.Values[0];
uint freeMemory = memoryInfo.Values[4]; uint freeMemory = memoryInfo.Values[4];
float usedMemory = Math.Max(totalMemory - freeMemory, 0); float usedMemory = Math.Max(totalMemory - freeMemory, 0);
@@ -221,9 +247,8 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
r.AppendFormat("Name: {0}{1}", name, Environment.NewLine); r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
r.AppendFormat("Index: {0}{1}", adapterIndex, Environment.NewLine); r.AppendFormat("Index: {0}{1}", adapterIndex, Environment.NewLine);
if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null) if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null) {
{
NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion(); NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();
driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER; driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value, if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value,
@@ -231,7 +256,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
r.Append("Driver Version: "); r.Append("Driver Version: ");
r.Append(driverVersion.DriverVersion / 100); r.Append(driverVersion.DriverVersion / 100);
r.Append("."); r.Append(".");
r.Append((driverVersion.DriverVersion % 100).ToString("00", r.Append((driverVersion.DriverVersion % 100).ToString("00",
CultureInfo.InvariantCulture)); CultureInfo.InvariantCulture));
r.AppendLine(); r.AppendLine();
r.Append("Driver Branch: "); r.Append("Driver Branch: ");
@@ -269,7 +294,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
r.AppendLine(status.ToString()); r.AppendLine(status.ToString());
} }
r.AppendLine(); r.AppendLine();
} }
if (NVAPI.NvAPI_GPU_GetAllClocks != null) { if (NVAPI.NvAPI_GPU_GetAllClocks != null) {
NvClocks allClocks = new NvClocks(); NvClocks allClocks = new NvClocks();
@@ -290,10 +315,10 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
r.AppendLine(status.ToString()); r.AppendLine(status.ToString());
} }
r.AppendLine(); r.AppendLine();
} }
if (NVAPI.NvAPI_GPU_GetTachReading != null) { if (NVAPI.NvAPI_GPU_GetTachReading != null) {
int tachValue; int tachValue;
NvStatus status = NVAPI.NvAPI_GPU_GetTachReading(handle, out tachValue); NvStatus status = NVAPI.NvAPI_GPU_GetTachReading(handle, out tachValue);
r.AppendLine("Tachometer"); r.AppendLine("Tachometer");
@@ -332,7 +357,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
usages.Version = NVAPI.GPU_USAGES_VER; usages.Version = NVAPI.GPU_USAGES_VER;
usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU]; usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU];
NvStatus status = NVAPI.NvAPI_GPU_GetUsages(handle, ref usages); NvStatus status = NVAPI.NvAPI_GPU_GetUsages(handle, ref usages);
r.AppendLine("Usages"); r.AppendLine("Usages");
r.AppendLine(); r.AppendLine();
if (status == NvStatus.OK) { if (status == NvStatus.OK) {
@@ -394,7 +419,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
NvMemoryInfo memoryInfo = new NvMemoryInfo(); NvMemoryInfo memoryInfo = new NvMemoryInfo();
memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER; memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU]; memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
NvStatus status = NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value, NvStatus status = NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value,
ref memoryInfo); ref memoryInfo);
r.AppendLine("Memory Info"); r.AppendLine("Memory Info");
@@ -412,5 +437,45 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
return r.ToString(); return r.ToString();
} }
private void SoftwareControlValueChanged(IControl control) {
SaveDefaultFanSpeed();
NvGPUCoolerLevels coolerLevels = new NvGPUCoolerLevels();
coolerLevels.Version = NVAPI.GPU_COOLER_LEVELS_VER;
coolerLevels.Levels = new NvLevel[NVAPI.MAX_COOLER_PER_GPU];
coolerLevels.Levels[0].Level = (int)control.SoftwareValue;
coolerLevels.Levels[0].Policy = 1;
NVAPI.NvAPI_GPU_SetCoolerLevels(handle, 0, ref coolerLevels);
}
private void SaveDefaultFanSpeed() {
if (!restoreDefaultFanSpeedRequired) {
NvGPUCoolerSettings coolerSettings = GetCoolerSettings();
if (coolerSettings.Count > 0) {
restoreDefaultFanSpeedRequired = true;
initialFanSpeedValue.Level = coolerSettings.Cooler[0].CurrentLevel;
initialFanSpeedValue.Policy = coolerSettings.Cooler[0].CurrentPolicy;
}
}
}
private void ControlModeChanged(IControl control) {
if (control.ControlMode == ControlMode.Default) {
RestoreDefaultFanSpeed();
} else {
SoftwareControlValueChanged(control);
}
}
private void RestoreDefaultFanSpeed() {
if (restoreDefaultFanSpeedRequired) {
NvGPUCoolerLevels coolerLevels = new NvGPUCoolerLevels();
coolerLevels.Version = NVAPI.GPU_COOLER_LEVELS_VER;
coolerLevels.Levels = new NvLevel[NVAPI.MAX_COOLER_PER_GPU];
coolerLevels.Levels[0] = initialFanSpeedValue;
NVAPI.NvAPI_GPU_SetCoolerLevels(handle, 0, ref coolerLevels);
restoreDefaultFanSpeedRequired = false;
}
}
} }
} }