Add core voltage for NVIDIA GPU. (#2175)

This commit is contained in:
Blacktempel
2026-01-20 17:21:06 +01:00
committed by GitHub
parent 4b3ed8bb46
commit 24218b0703
2 changed files with 54 additions and 0 deletions
@@ -42,6 +42,7 @@ internal sealed class NvidiaGpu : GenericGpu
private readonly Sensor _pcieThroughputTx;
private readonly Sensor[] _powers;
private readonly Sensor _powerUsage;
private readonly Sensor _coreVoltage;
private readonly Sensor[] _temperatures;
private readonly uint _thermalSensorsMask;
@@ -307,6 +308,15 @@ internal sealed class NvidiaGpu : GenericGpu
}
}
// Voltage
var voltageSensor = GetVoltRailsStatus(out status);
if (status == NvApi.NvStatus.OK)
{
_coreVoltage = new Sensor("GPU Core Voltage", 0, SensorType.Voltage, this, settings);
ActivateSensor(_coreVoltage);
}
if (NvidiaML.IsAvailable || NvidiaML.Initialize())
{
if (hasBusId)
@@ -614,6 +624,17 @@ internal sealed class NvidiaGpu : GenericGpu
}
}
if (_coreVoltage != null)
{
var voltageSensor = GetVoltRailsStatus(out status);
if (status == NvApi.NvStatus.OK)
{
var microvolts = ((ulong)voltageSensor.CoreMicrovoltsHigh << 32) | voltageSensor.CoreMicrovolts;
_coreVoltage.Value = microvolts == 0 ? 0 : microvolts / 1_000_000f;
}
}
if (_displayHandle != null)
{
NvApi.NvMemoryInfo memoryInfo = GetMemoryInfo(out status);
@@ -1038,6 +1059,23 @@ internal sealed class NvidiaGpu : GenericGpu
return status == NvApi.NvStatus.OK ? thermalSensors : default;
}
private NvApi.NvGpuClientVoltRailsStatus GetVoltRailsStatus(out NvApi.NvStatus status)
{
if (NvApi.NvAPI_GPU_ClientVoltRailsGetStatus == null)
{
status = NvApi.NvStatus.Error;
return default;
}
var voltRails = new NvApi.NvGpuClientVoltRailsStatus
{
Version = (uint)NvApi.MAKE_NVAPI_VERSION<NvApi.NvGpuClientVoltRailsStatus>(1),
};
status = NvApi.NvAPI_GPU_ClientVoltRailsGetStatus(_handle, ref voltRails);
return status == NvApi.NvStatus.OK ? voltRails : default;
}
private NvApi.NvFanCoolersStatus GetFanCoolersStatus(out NvApi.NvStatus status)
{
if (NvApi.NvAPI_GPU_ClientFanCoolersGetStatus == null)
+16
View File
@@ -46,6 +46,7 @@ internal static class NvApi
public static NvAPI_GPU_GetUsagesDelegate NvAPI_GPU_GetUsages { get; internal set; }
public static NvAPI_GPU_SetCoolerLevelsDelegate NvAPI_GPU_SetCoolerLevels { get; internal set; }
public static NvAPI_GPU_GetThermalSensorsDelegate NvAPI_GPU_GetThermalSensors { get; internal set; }
public static NvAPI_GPU_ClientVoltRailsGetStatusDelegate NvAPI_GPU_ClientVoltRailsGetStatus { get; internal set; }
private static NvAPI_GetInterfaceVersionStringDelegate _nvAPI_GetInterfaceVersionString;
private static NvAPI_GPU_GetFullNameDelegate _nvAPI_GPU_GetFullName;
@@ -90,6 +91,7 @@ internal static class NvApi
NvAPI_GPU_ClientFanCoolersSetControl = GetDelegate<NvAPI_GPU_ClientFanCoolersSetControlDelegate>(0xA58971A5);
NvAPI_GPU_ClientPowerTopologyGetStatus = GetDelegate<NvAPI_GPU_ClientPowerTopologyGetStatusDelegate>(0x0EDCF624E);
NvAPI_GPU_GetThermalSensors = GetDelegate<NvAPI_GPU_GetThermalSensorsDelegate>(0x65FE3AAD);
NvAPI_GPU_ClientVoltRailsGetStatus = GetDelegate<NvAPI_GPU_ClientVoltRailsGetStatusDelegate>(0x465F9BCF);
IsAvailable = true;
}
@@ -158,6 +160,9 @@ internal static class NvApi
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(NvPhysicalGpuHandle gpuHandle, int coolerIndex, ref NvCoolerLevels NvCoolerLevels);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_ClientVoltRailsGetStatusDelegate(NvPhysicalGpuHandle gpuHandle, ref NvGpuClientVoltRailsStatus status);
public enum NvFanControlMode : uint
{
Auto = 0,
@@ -577,6 +582,17 @@ internal static class NvApi
public NvGpuClockFrequenciesDomain[] Clocks;
}
[StructLayout(LayoutKind.Explicit, Size = 0x4C)]
internal unsafe struct NvGpuClientVoltRailsStatus
{
[FieldOffset(0x00)] public uint Version;
[FieldOffset(0x04)] public fixed uint _reserved[17]; //Unknown
[FieldOffset(0x28)] public uint CoreMicrovolts;
[FieldOffset(0x2C)] public uint CoreMicrovoltsHigh;
}
internal enum NvGpuPublicClockId
{
Graphics = 0,