mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-08-22 09:57:20 +00:00
Added support for the NVML (NVIDIA Management Library). Added support for power and PCIE throughput sensors on NVIDIA GPUs.
This commit is contained in:
parent
0a8923a998
commit
8e9bea8b6c
@ -8,11 +8,9 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using OpenHardwareMonitor.Hardware;
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Collections.Generic;
|
|
||||||
using OpenHardwareMonitor.Hardware;
|
|
||||||
using OpenHardwareMonitor.Utilities;
|
|
||||||
|
|
||||||
namespace OpenHardwareMonitor.GUI {
|
namespace OpenHardwareMonitor.GUI {
|
||||||
public class SensorNode : Node {
|
public class SensorNode : Node {
|
||||||
@ -20,18 +18,26 @@ namespace OpenHardwareMonitor.GUI {
|
|||||||
private ISensor sensor;
|
private ISensor sensor;
|
||||||
private PersistentSettings settings;
|
private PersistentSettings settings;
|
||||||
private UnitManager unitManager;
|
private UnitManager unitManager;
|
||||||
private string format;
|
private string fixedFormat;
|
||||||
private bool plot = false;
|
private bool plot = false;
|
||||||
private Color? penColor = null;
|
private Color? penColor = null;
|
||||||
|
|
||||||
public string ValueToString(float? value) {
|
public string ValueToString(float? value) {
|
||||||
if (value.HasValue) {
|
if (value.HasValue) {
|
||||||
if (sensor.SensorType == SensorType.Temperature &&
|
switch (sensor.SensorType) {
|
||||||
unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit) {
|
case SensorType.Temperature:
|
||||||
return string.Format("{0:F1} °F", value * 1.8 + 32);
|
if (unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
|
||||||
} else {
|
return string.Format("{0:F1} °F", value * 1.8 + 32);
|
||||||
return string.Format(format, value);
|
else
|
||||||
}
|
return string.Format("{0:F1} °C", value);
|
||||||
|
case SensorType.Throughput:
|
||||||
|
if (value < 1)
|
||||||
|
return string.Format("{0:F1} KB/s", value * 0x400);
|
||||||
|
else
|
||||||
|
return string.Format("{0:F1} MB/s", value);
|
||||||
|
default:
|
||||||
|
return string.Format(fixedFormat, value);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
@ -42,18 +48,18 @@ namespace OpenHardwareMonitor.GUI {
|
|||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.unitManager = unitManager;
|
this.unitManager = unitManager;
|
||||||
switch (sensor.SensorType) {
|
switch (sensor.SensorType) {
|
||||||
case SensorType.Voltage: format = "{0:F3} V"; break;
|
case SensorType.Voltage: fixedFormat = "{0:F3} V"; break;
|
||||||
case SensorType.Clock: format = "{0:F1} MHz"; break;
|
case SensorType.Clock: fixedFormat = "{0:F1} MHz"; break;
|
||||||
case SensorType.Load: format = "{0:F1} %"; break;
|
case SensorType.Load: fixedFormat = "{0:F1} %"; break;
|
||||||
case SensorType.Temperature: format = "{0:F1} °C"; break;
|
case SensorType.Fan: fixedFormat = "{0:F0} RPM"; break;
|
||||||
case SensorType.Fan: format = "{0:F0} RPM"; break;
|
case SensorType.Flow: fixedFormat = "{0:F0} L/h"; break;
|
||||||
case SensorType.Flow: format = "{0:F0} L/h"; break;
|
case SensorType.Control: fixedFormat = "{0:F1} %"; break;
|
||||||
case SensorType.Control: format = "{0:F1} %"; break;
|
case SensorType.Level: fixedFormat = "{0:F1} %"; break;
|
||||||
case SensorType.Level: format = "{0:F1} %"; break;
|
case SensorType.Power: fixedFormat = "{0:F1} W"; break;
|
||||||
case SensorType.Power: format = "{0:F1} W"; break;
|
case SensorType.Data: fixedFormat = "{0:F1} GB"; break;
|
||||||
case SensorType.Data: format = "{0:F1} GB"; break;
|
case SensorType.SmallData: fixedFormat = "{0:F1} MB"; break;
|
||||||
case SensorType.SmallData: format = "{0:F1} MB"; break;
|
case SensorType.Factor: fixedFormat = "{0:F3}"; break;
|
||||||
case SensorType.Factor: format = "{0:F3}"; break;
|
default: fixedFormat = ""; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hidden = settings.GetValue(new Identifier(sensor.Identifier,
|
bool hidden = settings.GetValue(new Identifier(sensor.Identifier,
|
||||||
|
@ -69,6 +69,10 @@ namespace OpenHardwareMonitor.GUI {
|
|||||||
this.Image = Utilities.EmbeddedResources.GetImage("factor.png");
|
this.Image = Utilities.EmbeddedResources.GetImage("factor.png");
|
||||||
this.Text = "Factors";
|
this.Text = "Factors";
|
||||||
break;
|
break;
|
||||||
|
case SensorType.Throughput:
|
||||||
|
this.Image = Utilities.EmbeddedResources.GetImage("throughput.png");
|
||||||
|
this.Text = "Throughput";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeAdded += new NodeEventHandler(TypeNode_NodeAdded);
|
NodeAdded += new NodeEventHandler(TypeNode_NodeAdded);
|
||||||
|
@ -27,6 +27,7 @@ namespace OpenHardwareMonitor.Hardware {
|
|||||||
Power, // W
|
Power, // W
|
||||||
Data, // GB = 2^30 Bytes
|
Data, // GB = 2^30 Bytes
|
||||||
SmallData, // MB = 2^20 Bytes
|
SmallData, // MB = 2^20 Bytes
|
||||||
|
Throughput, // MB/s = 2^20 Bytes/s
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct SensorValue {
|
public struct SensorValue {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
|
Copyright (C) 2009-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||||
Copyright (C) 2011 Christian Vallières
|
Copyright (C) 2011 Christian Vallières
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -307,6 +307,10 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
NvPhysicalGpuHandle gpuHandle, out uint deviceId, out uint subSystemId,
|
NvPhysicalGpuHandle gpuHandle, out uint deviceId, out uint subSystemId,
|
||||||
out uint revisionId, out uint extDeviceId);
|
out uint revisionId, out uint extDeviceId);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
public delegate NvStatus NvAPI_GPU_GetBusIdDelegate(
|
||||||
|
NvPhysicalGpuHandle gpuHandle, out uint busId);
|
||||||
|
|
||||||
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;
|
||||||
@ -341,6 +345,8 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
NvAPI_GetDisplayDriverVersion;
|
NvAPI_GetDisplayDriverVersion;
|
||||||
public static readonly NvAPI_GPU_GetPCIIdentifiersDelegate
|
public static readonly NvAPI_GPU_GetPCIIdentifiersDelegate
|
||||||
NvAPI_GPU_GetPCIIdentifiers;
|
NvAPI_GPU_GetPCIIdentifiers;
|
||||||
|
public static readonly NvAPI_GPU_GetBusIdDelegate
|
||||||
|
NvAPI_GPU_GetBusId;
|
||||||
|
|
||||||
private NVAPI() { }
|
private NVAPI() { }
|
||||||
|
|
||||||
@ -416,6 +422,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
|
GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
|
||||||
GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
|
GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
|
||||||
GetDelegate(0x2DDFB66E, out NvAPI_GPU_GetPCIIdentifiers);
|
GetDelegate(0x2DDFB66E, out NvAPI_GPU_GetPCIIdentifiers);
|
||||||
|
GetDelegate(0x1BE0B8E5, out NvAPI_GPU_GetBusId);
|
||||||
|
|
||||||
available = true;
|
available = true;
|
||||||
}
|
}
|
||||||
|
243
Hardware/Nvidia/NVML.cs
Normal file
243
Hardware/Nvidia/NVML.cs
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
Copyright (C) 2020 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace OpenHardwareMonitor.Hardware.Nvidia {
|
||||||
|
internal class NVML {
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
private delegate NvmlReturn nvmlInitDelegate();
|
||||||
|
private static readonly nvmlInitDelegate nvmlInit;
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
private delegate NvmlReturn nvmlInit_v2Delegate();
|
||||||
|
private static readonly nvmlInit_v2Delegate nvmlInit_v2;
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
public delegate NvmlReturn nvmlShutdownDelegate();
|
||||||
|
public static readonly nvmlShutdownDelegate NvmlShutdown;
|
||||||
|
|
||||||
|
public delegate NvmlReturn nvmlDeviceGetHandleByPciBusIdDelegate(
|
||||||
|
string pciBusId, out NvmlDevice device);
|
||||||
|
public static readonly nvmlDeviceGetHandleByPciBusIdDelegate
|
||||||
|
NvmlDeviceGetHandleByPciBusId;
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
public delegate NvmlReturn nvmlDeviceGetPowerUsageDelegate(
|
||||||
|
NvmlDevice device, out int power);
|
||||||
|
public static readonly nvmlDeviceGetPowerUsageDelegate
|
||||||
|
NvmlDeviceGetPowerUsage;
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
public delegate NvmlReturn nvmlDeviceGetPcieThroughputDelegate(
|
||||||
|
NvmlDevice devicee, NvmlPcieUtilCounter counter, out uint value);
|
||||||
|
public static readonly nvmlDeviceGetPcieThroughputDelegate
|
||||||
|
NvmlDeviceGetPcieThroughput;
|
||||||
|
|
||||||
|
|
||||||
|
public static NvmlReturn NvmlInit() {
|
||||||
|
try {
|
||||||
|
var result = nvmlInit_v2();
|
||||||
|
initialized = result == NvmlReturn.Success;
|
||||||
|
return result;
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
var result = nvmlInit();
|
||||||
|
initialized = result == NvmlReturn.Success;
|
||||||
|
return result;
|
||||||
|
} catch {
|
||||||
|
return NvmlReturn.ErrorLibraryNotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetDllName() {
|
||||||
|
int p = (int)Environment.OSVersion.Platform;
|
||||||
|
if ((p == 4) || (p == 128))
|
||||||
|
return "libnvidia-ml.so";
|
||||||
|
else
|
||||||
|
return "nvml.dll";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T CreateDelegate<T>(string entryPoint) where T : Delegate {
|
||||||
|
var attribute = new DllImportAttribute(GetDllName()) {
|
||||||
|
CallingConvention = CallingConvention.Cdecl,
|
||||||
|
PreserveSig = true,
|
||||||
|
EntryPoint = entryPoint
|
||||||
|
};
|
||||||
|
PInvokeDelegateFactory.CreateDelegate(attribute, out T newDelegate);
|
||||||
|
return newDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NVML() {
|
||||||
|
nvmlInit =
|
||||||
|
CreateDelegate<nvmlInitDelegate>(
|
||||||
|
"nvmlInit");
|
||||||
|
nvmlInit_v2 =
|
||||||
|
CreateDelegate<nvmlInit_v2Delegate>(
|
||||||
|
"nvmlInit_v2");
|
||||||
|
NvmlShutdown =
|
||||||
|
CreateDelegate<nvmlShutdownDelegate>(
|
||||||
|
"nvmlShutdown");
|
||||||
|
NvmlDeviceGetHandleByPciBusId =
|
||||||
|
CreateDelegate<nvmlDeviceGetHandleByPciBusIdDelegate>(
|
||||||
|
"nvmlDeviceGetHandleByPciBusId_v2");
|
||||||
|
NvmlDeviceGetPowerUsage =
|
||||||
|
CreateDelegate<nvmlDeviceGetPowerUsageDelegate>(
|
||||||
|
"nvmlDeviceGetPowerUsage");
|
||||||
|
NvmlDeviceGetPcieThroughput =
|
||||||
|
CreateDelegate<nvmlDeviceGetPcieThroughputDelegate>(
|
||||||
|
"nvmlDeviceGetPcieThroughput");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool initialized;
|
||||||
|
public static bool IsInitialized {
|
||||||
|
get { return initialized; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct NvmlDevice {
|
||||||
|
private readonly IntPtr ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum NvmlPcieUtilCounter {
|
||||||
|
TxBytes = 0,
|
||||||
|
RxBytes = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum NvmlReturn {
|
||||||
|
/// <summary>
|
||||||
|
/// The operation was successful
|
||||||
|
/// </summary>
|
||||||
|
Success = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// NVML was not first initialized with nvmlInit()
|
||||||
|
/// </summary>
|
||||||
|
ErrorUninitialized = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A supplied argument is invalid
|
||||||
|
/// </summary>
|
||||||
|
ErrorInvalidArgument = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The requested operation is not available on target device
|
||||||
|
/// </summary>
|
||||||
|
ErrorNotSupported = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current user does not have permission for operation
|
||||||
|
/// </summary>
|
||||||
|
ErrorNoPermission = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deprecated: Multiple initializations are now allowed through ref
|
||||||
|
/// counting
|
||||||
|
/// </summary>
|
||||||
|
ErrorAlreadyInitialized = 5,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A query to find an object was unsuccessful
|
||||||
|
/// </summary>
|
||||||
|
ErrorNotFound = 6,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An input argument is not large enough
|
||||||
|
/// </summary>
|
||||||
|
ErrorInsufficientSize = 7,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A device's external power cables are not properly attached
|
||||||
|
/// </summary>
|
||||||
|
ErrorInsufficientPower = 8,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// NVIDIA driver is not loaded
|
||||||
|
/// </summary>
|
||||||
|
ErrorDriverNotLoaded = 9,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// User provided timeout passed
|
||||||
|
/// </summary>
|
||||||
|
ErrorTimeout = 10,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// NVIDIA Kernel detected an interrupt issue with a GPU
|
||||||
|
/// </summary>
|
||||||
|
ErrorIrqIssue = 11,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// NVML Shared Library couldn't be found or loaded
|
||||||
|
/// </summary>
|
||||||
|
ErrorLibraryNotFound = 12,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Local version of NVML doesn't implement this function
|
||||||
|
/// </summary>
|
||||||
|
ErrorFunctionNotFound = 13,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// infoROM is corruptedinfoROM is corrupted
|
||||||
|
/// </summary>
|
||||||
|
ErrorCorruptedInforom = 14,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The GPU has fallen off the bus or has otherwise become inaccessible
|
||||||
|
/// </summary>
|
||||||
|
ErrorGpuIsLost = 15,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The GPU requires a reset before it can be used again
|
||||||
|
/// </summary>
|
||||||
|
ErrorResetRequired = 16,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The GPU control device has been blocked by the operating
|
||||||
|
/// system/cgroups
|
||||||
|
/// </summary>
|
||||||
|
ErrorOperatingSystem = 17,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// RM detects a driver/library version mismatch
|
||||||
|
/// </summary>
|
||||||
|
ErrorLibRmVersionMismatch = 18,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An operation cannot be performed because the GPU is currently in use
|
||||||
|
/// </summary>
|
||||||
|
ErrorInUse = 19,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Insufficient memory
|
||||||
|
/// </summary>
|
||||||
|
ErrorMemory = 20,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// No data
|
||||||
|
/// </summary>
|
||||||
|
ErrorNoData = 21,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The requested vgpu operation is not available on target device,
|
||||||
|
/// becasue ECC is enabled
|
||||||
|
/// </summary>
|
||||||
|
ErrorvGpuEccNotSupported = 22,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An internal driver error occurred
|
||||||
|
/// </summary>
|
||||||
|
ErrorUnknown = 999
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
Copyright (C) 2009-2015 Michael Möller <mmoeller@openhardwaremonitor.org>
|
Copyright (C) 2009-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||||
Copyright (C) 2011 Christian Vallières
|
Copyright (C) 2011 Christian Vallières
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -19,6 +19,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
private readonly int adapterIndex;
|
private readonly int adapterIndex;
|
||||||
private readonly NvPhysicalGpuHandle handle;
|
private readonly NvPhysicalGpuHandle handle;
|
||||||
private readonly NvDisplayHandle? displayHandle;
|
private readonly NvDisplayHandle? displayHandle;
|
||||||
|
private readonly NVML.NvmlDevice? device;
|
||||||
|
|
||||||
private readonly Sensor[] temperatures;
|
private readonly Sensor[] temperatures;
|
||||||
private readonly Sensor fan;
|
private readonly Sensor fan;
|
||||||
@ -29,12 +30,16 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
private readonly Sensor memoryUsed;
|
private readonly Sensor memoryUsed;
|
||||||
private readonly Sensor memoryFree;
|
private readonly Sensor memoryFree;
|
||||||
private readonly Sensor memoryAvail;
|
private readonly Sensor memoryAvail;
|
||||||
|
private readonly Sensor power;
|
||||||
|
private readonly Sensor pcieThroughputRx;
|
||||||
|
private readonly Sensor pcieThroughputTx;
|
||||||
private readonly Control fanControl;
|
private readonly Control fanControl;
|
||||||
|
|
||||||
public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle,
|
public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle,
|
||||||
NvDisplayHandle? displayHandle, ISettings settings)
|
NvDisplayHandle? displayHandle, ISettings settings)
|
||||||
: base(GetName(handle), new Identifier("nvidiagpu",
|
: base(GetName(handle), new Identifier("nvidiagpu",
|
||||||
adapterIndex.ToString(CultureInfo.InvariantCulture)), settings) {
|
adapterIndex.ToString(CultureInfo.InvariantCulture)), settings)
|
||||||
|
{
|
||||||
this.adapterIndex = adapterIndex;
|
this.adapterIndex = adapterIndex;
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
this.displayHandle = displayHandle;
|
this.displayHandle = displayHandle;
|
||||||
@ -57,13 +62,11 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
ActivateSensor(temperatures[i]);
|
ActivateSensor(temperatures[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int value;
|
|
||||||
if (NVAPI.NvAPI_GPU_GetTachReading != null &&
|
if (NVAPI.NvAPI_GPU_GetTachReading != null &&
|
||||||
NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) {
|
NVAPI.NvAPI_GPU_GetTachReading(handle, out _) == NvStatus.OK)
|
||||||
if (value >= 0) {
|
{
|
||||||
fan = new Sensor("GPU", 0, SensorType.Fan, this, settings);
|
fan = new Sensor("GPU", 0, SensorType.Fan, this, settings);
|
||||||
ActivateSensor(fan);
|
ActivateSensor(fan);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clocks = new Sensor[3];
|
clocks = new Sensor[3];
|
||||||
@ -93,6 +96,24 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
ControlModeChanged(fanControl);
|
ControlModeChanged(fanControl);
|
||||||
control.Control = fanControl;
|
control.Control = fanControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NVML.IsInitialized) {
|
||||||
|
if (NVAPI.NvAPI_GPU_GetBusId != null &&
|
||||||
|
NVAPI.NvAPI_GPU_GetBusId(handle, out uint busId) == NvStatus.OK) {
|
||||||
|
if (NVML.NvmlDeviceGetHandleByPciBusId(
|
||||||
|
"0000:" + busId.ToString("X2") + ":00.0", out var result)
|
||||||
|
== NVML.NvmlReturn.Success)
|
||||||
|
{
|
||||||
|
device = result;
|
||||||
|
power = new Sensor("GPU Power", 0, SensorType.Power, this, settings);
|
||||||
|
pcieThroughputRx = new Sensor("GPU PCIE Rx", 0,
|
||||||
|
SensorType.Throughput, this, settings);
|
||||||
|
pcieThroughputTx = new Sensor("GPU PCIE Tx", 1,
|
||||||
|
SensorType.Throughput, this, settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,10 +173,10 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
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 && NVAPI.NvAPI_GPU_GetTachReading(handle, out int fanValue)
|
||||||
int value = 0;
|
== NvStatus.OK)
|
||||||
NVAPI.NvAPI_GPU_GetTachReading(handle, out value);
|
{
|
||||||
fan.Value = value;
|
fan.Value = fanValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint[] values = GetClocks();
|
uint[] values = GetClocks();
|
||||||
@ -219,6 +240,34 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
ActivateSensor(memoryFree);
|
ActivateSensor(memoryFree);
|
||||||
ActivateSensor(memoryLoad);
|
ActivateSensor(memoryLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (power != null) {
|
||||||
|
if (NVML.NvmlDeviceGetPowerUsage(device.Value, out int powerValue)
|
||||||
|
== NVML.NvmlReturn.Success)
|
||||||
|
{
|
||||||
|
power.Value = powerValue * 0.001f;
|
||||||
|
ActivateSensor(power);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcieThroughputRx != null) {
|
||||||
|
if (NVML.NvmlDeviceGetPcieThroughput(device.Value,
|
||||||
|
NVML.NvmlPcieUtilCounter.RxBytes, out uint value)
|
||||||
|
== NVML.NvmlReturn.Success)
|
||||||
|
{
|
||||||
|
pcieThroughputRx.Value = value * (1.0f / 0x400);
|
||||||
|
ActivateSensor(pcieThroughputRx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcieThroughputTx != null) {
|
||||||
|
if (NVML.NvmlDeviceGetPcieThroughput(device.Value,
|
||||||
|
NVML.NvmlPcieUtilCounter.TxBytes, out uint value)
|
||||||
|
== NVML.NvmlReturn.Success) {
|
||||||
|
pcieThroughputTx.Value = value * (1.0f / 0x400);
|
||||||
|
ActivateSensor(pcieThroughputTx);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetReport() {
|
public override string GetReport() {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
|
Copyright (C) 2009-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
|
|
||||||
string version;
|
string version;
|
||||||
if (NVAPI.NvAPI_GetInterfaceVersionString(out version) == NvStatus.OK) {
|
if (NVAPI.NvAPI_GetInterfaceVersionString(out version) == NvStatus.OK) {
|
||||||
report.Append("Version: ");
|
report.Append(" Version: ");
|
||||||
report.AppendLine(version);
|
report.AppendLine(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,18 +36,26 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
new NvPhysicalGpuHandle[NVAPI.MAX_PHYSICAL_GPUS];
|
new NvPhysicalGpuHandle[NVAPI.MAX_PHYSICAL_GPUS];
|
||||||
int count;
|
int count;
|
||||||
if (NVAPI.NvAPI_EnumPhysicalGPUs == null) {
|
if (NVAPI.NvAPI_EnumPhysicalGPUs == null) {
|
||||||
report.AppendLine("Error: NvAPI_EnumPhysicalGPUs not available");
|
report.AppendLine(" Error: NvAPI_EnumPhysicalGPUs not available");
|
||||||
report.AppendLine();
|
report.AppendLine();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
NvStatus status = NVAPI.NvAPI_EnumPhysicalGPUs(handles, out count);
|
NvStatus status = NVAPI.NvAPI_EnumPhysicalGPUs(handles, out count);
|
||||||
if (status != NvStatus.OK) {
|
if (status != NvStatus.OK) {
|
||||||
report.AppendLine("Status: " + status);
|
report.AppendLine(" Status: " + status);
|
||||||
report.AppendLine();
|
report.AppendLine();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var result = NVML.NvmlInit();
|
||||||
|
|
||||||
|
report.AppendLine();
|
||||||
|
report.AppendLine("NVML");
|
||||||
|
report.AppendLine();
|
||||||
|
report.AppendLine(" Status: " + result);
|
||||||
|
report.AppendLine();
|
||||||
|
|
||||||
IDictionary<NvPhysicalGpuHandle, NvDisplayHandle> displayHandles =
|
IDictionary<NvPhysicalGpuHandle, NvDisplayHandle> displayHandles =
|
||||||
new Dictionary<NvPhysicalGpuHandle, NvDisplayHandle>();
|
new Dictionary<NvPhysicalGpuHandle, NvDisplayHandle>();
|
||||||
|
|
||||||
@ -100,7 +108,11 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
|||||||
|
|
||||||
public void Close() {
|
public void Close() {
|
||||||
foreach (Hardware gpu in hardware)
|
foreach (Hardware gpu in hardware)
|
||||||
gpu.Close();
|
gpu.Close();
|
||||||
|
|
||||||
|
if (NVML.IsInitialized) {
|
||||||
|
NVML.NvmlShutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,6 +295,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Resources\ram.png" />
|
<EmbeddedResource Include="Resources\ram.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Resources\throughput.png" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio AllowExistingFolder="true" />
|
<VisualStudio AllowExistingFolder="true" />
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
<Compile Include="Hardware\LPC\NCT677X.cs" />
|
<Compile Include="Hardware\LPC\NCT677X.cs" />
|
||||||
<Compile Include="Hardware\Mainboard\GigabyteTAMG.cs" />
|
<Compile Include="Hardware\Mainboard\GigabyteTAMG.cs" />
|
||||||
<Compile Include="Hardware\Mainboard\Identification.cs" />
|
<Compile Include="Hardware\Mainboard\Identification.cs" />
|
||||||
|
<Compile Include="Hardware\Nvidia\NVML.cs" />
|
||||||
<Compile Include="Hardware\Opcode.cs" />
|
<Compile Include="Hardware\Opcode.cs" />
|
||||||
<Compile Include="Hardware\OperatingSystem.cs" />
|
<Compile Include="Hardware\OperatingSystem.cs" />
|
||||||
<Compile Include="Hardware\RAM\GenericRAM.cs" />
|
<Compile Include="Hardware\RAM\GenericRAM.cs" />
|
||||||
|
BIN
Resources/throughput.png
Normal file
BIN
Resources/throughput.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 369 B |
Loading…
x
Reference in New Issue
Block a user