Nvidia Hotspot / VRAM temps (#583)

Thanks to @TimSirmovics
This commit is contained in:
Tim Sirmovics
2021-10-27 16:34:07 +02:00
committed by GitHub
parent f157563c33
commit 1701eb91b2
2 changed files with 93 additions and 2 deletions
@@ -40,6 +40,9 @@ namespace LibreHardwareMonitor.Hardware.Gpu
private readonly Sensor[] _powers;
private readonly Sensor _powerUsage;
private readonly Sensor[] _temperatures;
private uint _thermalSensorsMask;
private readonly Sensor _hotSpotTemperature;
private readonly Sensor _memoryJunctionTemperature;
public NvidiaGpu(int adapterIndex, NvApi.NvPhysicalGpuHandle handle, NvApi.NvDisplayHandle? displayHandle, ISettings settings)
: base(GetName(handle),
@@ -79,6 +82,32 @@ namespace LibreHardwareMonitor.Hardware.Gpu
}
}
// Thermal sensors.
_hotSpotTemperature = new Sensor("GPU Hot Spot", (int)thermalSettings.Count + 1, SensorType.Temperature, this, settings);
_memoryJunctionTemperature = new Sensor("GPU Memory Junction", (int)thermalSettings.Count + 2, SensorType.Temperature, this, settings);
bool hasAnyThermalSensor = false;
for (int thermalSensorsMaxBit = 0; thermalSensorsMaxBit < 32; thermalSensorsMaxBit++)
{
// Find the maximum thermal sensor mask value.
_thermalSensorsMask = 1u << thermalSensorsMaxBit;
GetThermalSensors(_thermalSensorsMask, out NvApi.NvStatus thermalSensorsStatus);
if (thermalSensorsStatus == NvApi.NvStatus.OK)
{
hasAnyThermalSensor = true;
continue;
}
_thermalSensorsMask--;
break;
}
if (!hasAnyThermalSensor)
{
_thermalSensorsMask = 0;
}
// Clock frequencies.
for (int clockVersion = 1; clockVersion <= 3; clockVersion++)
{
@@ -434,6 +463,28 @@ namespace LibreHardwareMonitor.Hardware.Gpu
}
}
if (_thermalSensorsMask > 0)
{
NvApi.NvThermalSensors thermalSensors = GetThermalSensors(_thermalSensorsMask, out status);
if (status == NvApi.NvStatus.OK)
{
_hotSpotTemperature.Value = thermalSensors.Temperatures[1] / 256.0f;
_memoryJunctionTemperature.Value = thermalSensors.Temperatures[9] / 256.0f;
}
if (_hotSpotTemperature.Value != 0)
ActivateSensor(_hotSpotTemperature);
if (_memoryJunctionTemperature.Value != 0)
ActivateSensor(_memoryJunctionTemperature);
}
else
{
_hotSpotTemperature.Value = null;
_memoryJunctionTemperature.Value = null;
}
if (_clocks is { Length: > 0 })
{
NvApi.NvGpuClockFrequencies clockFrequencies = GetClockFrequencies(out status);
@@ -928,6 +979,24 @@ namespace LibreHardwareMonitor.Hardware.Gpu
return status == NvApi.NvStatus.OK ? settings : default;
}
private NvApi.NvThermalSensors GetThermalSensors(uint mask, out NvApi.NvStatus status)
{
if (NvApi.NvAPI_GPU_ThermalGetSensors == null)
{
status = NvApi.NvStatus.Error;
return default;
}
var thermalSensors = new NvApi.NvThermalSensors()
{
Version = (uint)NvApi.MAKE_NVAPI_VERSION<NvApi.NvThermalSensors>(2),
Mask = mask
};
status = NvApi.NvAPI_GPU_ThermalGetSensors(_handle, ref thermalSensors);
return status == NvApi.NvStatus.OK ? thermalSensors : default;
}
private NvApi.NvFanCoolersStatus GetFanCoolersStatus(out NvApi.NvStatus status)
{
if (NvApi.NvAPI_GPU_ClientFanCoolersGetStatus == null)
@@ -938,7 +1007,8 @@ namespace LibreHardwareMonitor.Hardware.Gpu
var coolers = new NvApi.NvFanCoolersStatus
{
Version = (uint)NvApi.MAKE_NVAPI_VERSION<NvApi.NvFanCoolersStatus>(1), Items = new NvApi.NvFanCoolersStatusItem[NvApi.MAX_FAN_COOLERS_STATUS_ITEMS]
Version = (uint)NvApi.MAKE_NVAPI_VERSION<NvApi.NvFanCoolersStatus>(1),
Items = new NvApi.NvFanCoolersStatusItem[NvApi.MAX_FAN_COOLERS_STATUS_ITEMS]
};
status = NvApi.NvAPI_GPU_ClientFanCoolersGetStatus(_handle, ref coolers);
@@ -983,7 +1053,8 @@ namespace LibreHardwareMonitor.Hardware.Gpu
NvApi.NvDynamicPStatesInfo pStatesInfo = new()
{
Version = (uint)NvApi.MAKE_NVAPI_VERSION<NvApi.NvDynamicPStatesInfo>(1), Utilizations = new NvApi.NvDynamicPState[NvApi.MAX_GPU_UTILIZATIONS]
Version = (uint)NvApi.MAKE_NVAPI_VERSION<NvApi.NvDynamicPStatesInfo>(1),
Utilizations = new NvApi.NvDynamicPState[NvApi.MAX_GPU_UTILIZATIONS]
};
status = NvApi.NvAPI_GPU_GetDynamicPstatesInfoEx(_handle, ref pStatesInfo);
+20
View File
@@ -17,6 +17,8 @@ namespace LibreHardwareMonitor.Interop
public const int MAX_POWER_TOPOLOGIES = 4;
public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
public const int MAX_USAGES_PER_GPU = 8;
public const int THERMAL_SENSOR_RESERVED_COUNT = 8;
public const int THERMAL_SENSOR_TEMPERATURE_COUNT = 32;
public const int SHORT_STRING_MAX = 64;
@@ -39,6 +41,7 @@ namespace LibreHardwareMonitor.Interop
public static readonly NvAPI_GPU_GetThermalSettingsDelegate NvAPI_GPU_GetThermalSettings;
public static readonly NvAPI_GPU_GetUsagesDelegate NvAPI_GPU_GetUsages;
public static readonly NvAPI_GPU_SetCoolerLevelsDelegate NvAPI_GPU_SetCoolerLevels;
public static readonly NvAPI_GPU_GetThermalSensorsDelegate NvAPI_GPU_ThermalGetSensors;
private static readonly NvAPI_GetInterfaceVersionStringDelegate _nvAPI_GetInterfaceVersionString;
private static readonly NvAPI_GPU_GetFullNameDelegate _nvAPI_GPU_GetFullName;
@@ -87,6 +90,7 @@ namespace LibreHardwareMonitor.Interop
GetDelegate(0x814B209F, out NvAPI_GPU_ClientFanCoolersGetControl);
GetDelegate(0xA58971A5, out NvAPI_GPU_ClientFanCoolersSetControl);
GetDelegate(0x0EDCF624E, out NvAPI_GPU_ClientPowerTopologyGetStatus);
GetDelegate(0x65FE3AAD, out NvAPI_GPU_ThermalGetSensors);
IsAvailable = true;
}
@@ -152,6 +156,9 @@ namespace LibreHardwareMonitor.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(NvPhysicalGpuHandle gpuHandle, int coolerIndex, ref NvCoolerLevels NvCoolerLevels);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetThermalSensorsDelegate(NvPhysicalGpuHandle gpuHandle, ref NvThermalSensors nvThermalSensors);
public enum NvFanControlMode : uint
{
Auto = 0,
@@ -502,6 +509,19 @@ namespace LibreHardwareMonitor.Interop
public NvLevel[] Levels;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct NvThermalSensors
{
internal uint Version;
internal uint Mask;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = THERMAL_SENSOR_RESERVED_COUNT)]
internal int[] Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = THERMAL_SENSOR_TEMPERATURE_COUNT)]
internal int[] Temperatures;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvMemoryInfo
{