Skip to content

Commit 3a7ea82

Browse files
committed
Add core voltage for NVIDIA GPU
1 parent 3f6b9b1 commit 3a7ea82

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

OpenHardwareMonitorLib/Hardware/Gpu/NvidiaGpu.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ internal sealed class NvidiaGpu : GenericGpu
3636
private readonly Sensor _pcieThroughputTx;
3737
private readonly Sensor[] _powers;
3838
private readonly Sensor _powerUsage;
39+
private readonly Sensor _coreVoltage;
3940
private readonly Sensor[] _temperatures;
4041
private readonly uint _thermalSensorsMask;
4142

@@ -301,6 +302,15 @@ public NvidiaGpu(int adapterIndex, NvApi.NvPhysicalGpuHandle handle, NvApi.NvDis
301302
}
302303
}
303304

305+
// Voltage
306+
var voltageSensor = GetVoltRailsStatus(out status);
307+
if (status == NvApi.NvStatus.OK)
308+
{
309+
_coreVoltage = new Sensor("GPU Core Voltage", 0, SensorType.Voltage, this, settings);
310+
311+
ActivateSensor(_coreVoltage);
312+
}
313+
304314
if (NvidiaML.IsAvailable || NvidiaML.Initialize())
305315
{
306316
if (hasBusId)
@@ -608,6 +618,17 @@ public override void Update()
608618
}
609619
}
610620

621+
if (_coreVoltage != null)
622+
{
623+
var voltageSensor = GetVoltRailsStatus(out status);
624+
if (status == NvApi.NvStatus.OK)
625+
{
626+
var microvolts = ((ulong)voltageSensor.CoreMicrovoltsHigh << 32) | voltageSensor.CoreMicrovolts;
627+
628+
_coreVoltage.Value = microvolts == 0 ? 0 : microvolts / 1_000_000f;
629+
}
630+
}
631+
611632
if (_displayHandle != null)
612633
{
613634
NvApi.NvMemoryInfo memoryInfo = GetMemoryInfo(out status);
@@ -1032,6 +1053,23 @@ private NvApi.NvThermalSensors GetThermalSensors(uint mask, out NvApi.NvStatus s
10321053
return status == NvApi.NvStatus.OK ? thermalSensors : default;
10331054
}
10341055

1056+
private NvApi.NvGpuClientVoltRailsStatus GetVoltRailsStatus(out NvApi.NvStatus status)
1057+
{
1058+
if (NvApi.NvAPI_GPU_ClientVoltRailsGetStatus == null)
1059+
{
1060+
status = NvApi.NvStatus.Error;
1061+
return default;
1062+
}
1063+
1064+
var voltRails = new NvApi.NvGpuClientVoltRailsStatus
1065+
{
1066+
Version = (uint)NvApi.MAKE_NVAPI_VERSION<NvApi.NvGpuClientVoltRailsStatus>(1),
1067+
};
1068+
1069+
status = NvApi.NvAPI_GPU_ClientVoltRailsGetStatus(_handle, ref voltRails);
1070+
return status == NvApi.NvStatus.OK ? voltRails : default;
1071+
}
1072+
10351073
private NvApi.NvFanCoolersStatus GetFanCoolersStatus(out NvApi.NvStatus status)
10361074
{
10371075
if (NvApi.NvAPI_GPU_ClientFanCoolersGetStatus == null)

OpenHardwareMonitorLib/Interop/NvApi.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ internal static class NvApi
4545
public static NvAPI_GPU_GetUsagesDelegate NvAPI_GPU_GetUsages { get; internal set; }
4646
public static NvAPI_GPU_SetCoolerLevelsDelegate NvAPI_GPU_SetCoolerLevels { get; internal set; }
4747
public static NvAPI_GPU_GetThermalSensorsDelegate NvAPI_GPU_GetThermalSensors { get; internal set; }
48+
public static NvAPI_GPU_ClientVoltRailsGetStatusDelegate NvAPI_GPU_ClientVoltRailsGetStatus { get; internal set; }
4849

4950
private static NvAPI_GetInterfaceVersionStringDelegate _nvAPI_GetInterfaceVersionString;
5051
private static NvAPI_GPU_GetFullNameDelegate _nvAPI_GPU_GetFullName;
@@ -89,6 +90,7 @@ public static void Initialize()
8990
NvAPI_GPU_ClientFanCoolersSetControl = GetDelegate<NvAPI_GPU_ClientFanCoolersSetControlDelegate>(0xA58971A5);
9091
NvAPI_GPU_ClientPowerTopologyGetStatus = GetDelegate<NvAPI_GPU_ClientPowerTopologyGetStatusDelegate>(0x0EDCF624E);
9192
NvAPI_GPU_GetThermalSensors = GetDelegate<NvAPI_GPU_GetThermalSensorsDelegate>(0x65FE3AAD);
93+
NvAPI_GPU_ClientVoltRailsGetStatus = GetDelegate<NvAPI_GPU_ClientVoltRailsGetStatusDelegate>(0x465F9BCF);
9294

9395
IsAvailable = true;
9496
}
@@ -157,6 +159,9 @@ public static void Initialize()
157159
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
158160
public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(NvPhysicalGpuHandle gpuHandle, int coolerIndex, ref NvCoolerLevels NvCoolerLevels);
159161

162+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
163+
public delegate NvStatus NvAPI_GPU_ClientVoltRailsGetStatusDelegate(NvPhysicalGpuHandle gpuHandle, ref NvGpuClientVoltRailsStatus status);
164+
160165
public enum NvFanControlMode : uint
161166
{
162167
Auto = 0,
@@ -576,6 +581,17 @@ internal struct NvGpuClockFrequencies
576581
public NvGpuClockFrequenciesDomain[] Clocks;
577582
}
578583

584+
[StructLayout(LayoutKind.Explicit, Size = 0x4C)]
585+
internal unsafe struct NvGpuClientVoltRailsStatus
586+
{
587+
[FieldOffset(0x00)] public uint Version;
588+
589+
[FieldOffset(0x04)] public fixed uint _reserved[17]; //Unknown
590+
591+
[FieldOffset(0x28)] public uint CoreMicrovolts;
592+
[FieldOffset(0x2C)] public uint CoreMicrovoltsHigh;
593+
}
594+
579595
internal enum NvGpuPublicClockId
580596
{
581597
Graphics = 0,

0 commit comments

Comments
 (0)