Changed NvApi lifecycle (#1885)
* Changed NvApi lifecycle * Changed from public to internal * Revert unnecessary changes. Reinitialize() -> Initialize(). * Refactor try-catch blocks for NVML device methods --------- Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com>
This commit is contained in:
@@ -25,31 +25,31 @@ internal static class NvApi
|
||||
private const string DllName = "nvapi.dll";
|
||||
private const string DllName64 = "nvapi64.dll";
|
||||
|
||||
public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate NvAPI_EnumNvidiaDisplayHandle;
|
||||
public static readonly NvAPI_EnumPhysicalGPUsDelegate NvAPI_EnumPhysicalGPUs;
|
||||
public static readonly NvAPI_GetDisplayDriverVersionDelegate NvAPI_GetDisplayDriverVersion;
|
||||
public static readonly NvAPI_GetPhysicalGPUsFromDisplayDelegate NvAPI_GetPhysicalGPUsFromDisplay;
|
||||
public static readonly NvAPI_GPU_ClientFanCoolersGetControlDelegate NvAPI_GPU_ClientFanCoolersGetControl;
|
||||
public static readonly NvAPI_GPU_ClientFanCoolersGetStatusDelegate NvAPI_GPU_ClientFanCoolersGetStatus;
|
||||
public static readonly NvAPI_GPU_ClientFanCoolersSetControlDelegate NvAPI_GPU_ClientFanCoolersSetControl;
|
||||
public static readonly NvAPI_GPU_ClientPowerTopologyGetStatusDelegate NvAPI_GPU_ClientPowerTopologyGetStatus;
|
||||
public static readonly NvAPI_GPU_GetAllClockFrequenciesDelegate NvAPI_GPU_GetAllClockFrequencies;
|
||||
public static readonly NvAPI_GPU_GetAllClocksDelegate NvAPI_GPU_GetAllClocks;
|
||||
public static readonly NvAPI_GPU_GetBusIdDelegate NvAPI_GPU_GetBusId;
|
||||
public static readonly NvAPI_GPU_GetCoolerSettingsDelegate NvAPI_GPU_GetCoolerSettings;
|
||||
public static readonly NvAPI_GPU_GetDynamicPstatesInfoExDelegate NvAPI_GPU_GetDynamicPstatesInfoEx;
|
||||
public static readonly NvAPI_GPU_GetMemoryInfoDelegate NvAPI_GPU_GetMemoryInfo;
|
||||
public static readonly NvAPI_GPU_GetPCIIdentifiersDelegate NvAPI_GPU_GetPCIIdentifiers;
|
||||
public static readonly NvAPI_GPU_GetTachReadingDelegate NvAPI_GPU_GetTachReading;
|
||||
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;
|
||||
public static NvAPI_EnumNvidiaDisplayHandleDelegate NvAPI_EnumNvidiaDisplayHandle { get; internal set; }
|
||||
public static NvAPI_EnumPhysicalGPUsDelegate NvAPI_EnumPhysicalGPUs { get; internal set; }
|
||||
public static NvAPI_GetDisplayDriverVersionDelegate NvAPI_GetDisplayDriverVersion { get; internal set; }
|
||||
public static NvAPI_GetPhysicalGPUsFromDisplayDelegate NvAPI_GetPhysicalGPUsFromDisplay { get; internal set; }
|
||||
public static NvAPI_GPU_ClientFanCoolersGetControlDelegate NvAPI_GPU_ClientFanCoolersGetControl { get; internal set; }
|
||||
public static NvAPI_GPU_ClientFanCoolersGetStatusDelegate NvAPI_GPU_ClientFanCoolersGetStatus { get; internal set; }
|
||||
public static NvAPI_GPU_ClientFanCoolersSetControlDelegate NvAPI_GPU_ClientFanCoolersSetControl { get; internal set; }
|
||||
public static NvAPI_GPU_ClientPowerTopologyGetStatusDelegate NvAPI_GPU_ClientPowerTopologyGetStatus { get; internal set; }
|
||||
public static NvAPI_GPU_GetAllClockFrequenciesDelegate NvAPI_GPU_GetAllClockFrequencies { get; internal set; }
|
||||
public static NvAPI_GPU_GetAllClocksDelegate NvAPI_GPU_GetAllClocks { get; internal set; }
|
||||
public static NvAPI_GPU_GetBusIdDelegate NvAPI_GPU_GetBusId { get; internal set; }
|
||||
public static NvAPI_GPU_GetCoolerSettingsDelegate NvAPI_GPU_GetCoolerSettings { get; internal set; }
|
||||
public static NvAPI_GPU_GetDynamicPstatesInfoExDelegate NvAPI_GPU_GetDynamicPstatesInfoEx { get; internal set; }
|
||||
public static NvAPI_GPU_GetMemoryInfoDelegate NvAPI_GPU_GetMemoryInfo { get; internal set; }
|
||||
public static NvAPI_GPU_GetPCIIdentifiersDelegate NvAPI_GPU_GetPCIIdentifiers { get; internal set; }
|
||||
public static NvAPI_GPU_GetTachReadingDelegate NvAPI_GPU_GetTachReading { get; internal set; }
|
||||
public static NvAPI_GPU_GetThermalSettingsDelegate NvAPI_GPU_GetThermalSettings { get; internal set; }
|
||||
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; }
|
||||
|
||||
private static readonly NvAPI_GetInterfaceVersionStringDelegate _nvAPI_GetInterfaceVersionString;
|
||||
private static readonly NvAPI_GPU_GetFullNameDelegate _nvAPI_GPU_GetFullName;
|
||||
private static NvAPI_GetInterfaceVersionStringDelegate _nvAPI_GetInterfaceVersionString;
|
||||
private static NvAPI_GPU_GetFullNameDelegate _nvAPI_GPU_GetFullName;
|
||||
|
||||
static NvApi()
|
||||
public static void Initialize()
|
||||
{
|
||||
NvAPI_InitializeDelegate nvApiInitialize;
|
||||
|
||||
@@ -58,7 +58,7 @@ internal static class NvApi
|
||||
if (!DllExists())
|
||||
return;
|
||||
|
||||
GetDelegate(0x0150E828, out nvApiInitialize);
|
||||
nvApiInitialize = GetDelegate<NvAPI_InitializeDelegate>(0x0150E828);
|
||||
}
|
||||
catch (Exception e) when (e is DllNotFoundException or ArgumentNullException or EntryPointNotFoundException or BadImageFormatException)
|
||||
{
|
||||
@@ -67,28 +67,28 @@ internal static class NvApi
|
||||
|
||||
if (nvApiInitialize() == NvStatus.OK)
|
||||
{
|
||||
GetDelegate(0xE3640A56, out NvAPI_GPU_GetThermalSettings);
|
||||
GetDelegate(0xCEEE8E9F, out _nvAPI_GPU_GetFullName);
|
||||
GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
|
||||
GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
|
||||
GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
|
||||
GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);
|
||||
GetDelegate(0x1BD69F49, out NvAPI_GPU_GetAllClocks);
|
||||
GetDelegate(0x60DED2ED, out NvAPI_GPU_GetDynamicPstatesInfoEx);
|
||||
GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
|
||||
GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings);
|
||||
GetDelegate(0x891FA0AE, out NvAPI_GPU_SetCoolerLevels);
|
||||
GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
|
||||
GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
|
||||
GetDelegate(0x01053FA5, out _nvAPI_GetInterfaceVersionString);
|
||||
GetDelegate(0x2DDFB66E, out NvAPI_GPU_GetPCIIdentifiers);
|
||||
GetDelegate(0x1BE0B8E5, out NvAPI_GPU_GetBusId);
|
||||
GetDelegate(0x35AED5E8, out NvAPI_GPU_ClientFanCoolersGetStatus);
|
||||
GetDelegate(0xDCB616C3, out NvAPI_GPU_GetAllClockFrequencies);
|
||||
GetDelegate(0x814B209F, out NvAPI_GPU_ClientFanCoolersGetControl);
|
||||
GetDelegate(0xA58971A5, out NvAPI_GPU_ClientFanCoolersSetControl);
|
||||
GetDelegate(0x0EDCF624E, out NvAPI_GPU_ClientPowerTopologyGetStatus);
|
||||
GetDelegate(0x65FE3AAD, out NvAPI_GPU_ThermalGetSensors);
|
||||
NvAPI_GPU_GetThermalSettings = GetDelegate<NvAPI_GPU_GetThermalSettingsDelegate>(0xE3640A56);
|
||||
_nvAPI_GPU_GetFullName = GetDelegate<NvAPI_GPU_GetFullNameDelegate>(0xCEEE8E9F);
|
||||
NvAPI_EnumNvidiaDisplayHandle = GetDelegate<NvAPI_EnumNvidiaDisplayHandleDelegate>(0x9ABDD40D);
|
||||
NvAPI_GetPhysicalGPUsFromDisplay = GetDelegate<NvAPI_GetPhysicalGPUsFromDisplayDelegate>(0x34EF9506);
|
||||
NvAPI_EnumPhysicalGPUs = GetDelegate<NvAPI_EnumPhysicalGPUsDelegate>(0xE5AC921F);
|
||||
NvAPI_GPU_GetTachReading = GetDelegate<NvAPI_GPU_GetTachReadingDelegate>(0x5F608315);
|
||||
NvAPI_GPU_GetAllClocks = GetDelegate<NvAPI_GPU_GetAllClocksDelegate>(0x1BD69F49);
|
||||
NvAPI_GPU_GetDynamicPstatesInfoEx = GetDelegate<NvAPI_GPU_GetDynamicPstatesInfoExDelegate>(0x60DED2ED);
|
||||
NvAPI_GPU_GetUsages = GetDelegate<NvAPI_GPU_GetUsagesDelegate>(0x189A1FDF);
|
||||
NvAPI_GPU_GetCoolerSettings = GetDelegate<NvAPI_GPU_GetCoolerSettingsDelegate>(0xDA141340);
|
||||
NvAPI_GPU_SetCoolerLevels = GetDelegate<NvAPI_GPU_SetCoolerLevelsDelegate>(0x891FA0AE);
|
||||
NvAPI_GPU_GetMemoryInfo = GetDelegate<NvAPI_GPU_GetMemoryInfoDelegate>(0x774AA982);
|
||||
NvAPI_GetDisplayDriverVersion = GetDelegate<NvAPI_GetDisplayDriverVersionDelegate>(0xF951A4D1);
|
||||
_nvAPI_GetInterfaceVersionString = GetDelegate<NvAPI_GetInterfaceVersionStringDelegate>(0x01053FA5);
|
||||
NvAPI_GPU_GetPCIIdentifiers = GetDelegate<NvAPI_GPU_GetPCIIdentifiersDelegate>(0x2DDFB66E);
|
||||
NvAPI_GPU_GetBusId = GetDelegate<NvAPI_GPU_GetBusIdDelegate>(0x1BE0B8E5);
|
||||
NvAPI_GPU_ClientFanCoolersGetStatus = GetDelegate<NvAPI_GPU_ClientFanCoolersGetStatusDelegate>(0x35AED5E8);
|
||||
NvAPI_GPU_GetAllClockFrequencies = GetDelegate<NvAPI_GPU_GetAllClockFrequenciesDelegate>(0xDCB616C3);
|
||||
NvAPI_GPU_ClientFanCoolersGetControl = GetDelegate<NvAPI_GPU_ClientFanCoolersGetControlDelegate>(0x814B209F);
|
||||
NvAPI_GPU_ClientFanCoolersSetControl = GetDelegate<NvAPI_GPU_ClientFanCoolersSetControlDelegate>(0xA58971A5);
|
||||
NvAPI_GPU_ClientPowerTopologyGetStatus = GetDelegate<NvAPI_GPU_ClientPowerTopologyGetStatusDelegate>(0x0EDCF624E);
|
||||
NvAPI_GPU_GetThermalSensors = GetDelegate<NvAPI_GPU_GetThermalSensorsDelegate>(0x65FE3AAD);
|
||||
|
||||
IsAvailable = true;
|
||||
}
|
||||
@@ -188,7 +188,7 @@ internal static class NvApi
|
||||
BusInterface // Bus
|
||||
}
|
||||
|
||||
public static bool IsAvailable { get; }
|
||||
public static bool IsAvailable { get; private set; }
|
||||
|
||||
[DllImport(DllName, EntryPoint = "nvapi_QueryInterface", CallingConvention = CallingConvention.Cdecl, PreserveSig = true)]
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
@@ -216,14 +216,18 @@ internal static class NvApi
|
||||
return status;
|
||||
}
|
||||
|
||||
private static void GetDelegate<T>(uint id, out T newDelegate) where T : class
|
||||
private static T GetDelegate<T>(uint id) where T : class
|
||||
{
|
||||
IntPtr ptr = Environment.Is64BitProcess ? NvAPI64_QueryInterface(id) : NvAPI32_QueryInterface(id);
|
||||
|
||||
if (ptr != IntPtr.Zero)
|
||||
newDelegate = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
|
||||
{
|
||||
return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
|
||||
}
|
||||
else
|
||||
newDelegate = null;
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool DllExists()
|
||||
|
||||
@@ -1,325 +1,325 @@
|
||||
// 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) LibreHardwareMonitor and Contributors.
|
||||
// All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LibreHardwareMonitor.Interop;
|
||||
|
||||
internal static class NvidiaML
|
||||
{
|
||||
private const string LinuxDllName = "nvidia-ml";
|
||||
private const string WindowsDllName = "nvml.dll";
|
||||
|
||||
private static readonly object _syncRoot = new();
|
||||
|
||||
private static IntPtr _windowsDll;
|
||||
|
||||
private static WindowsNvmlGetHandleDelegate _windowsNvmlDeviceGetHandleByIndex;
|
||||
private static WindowsNvmlGetHandleByPciBusIdDelegate _windowsNvmlDeviceGetHandleByPciBusId;
|
||||
private static WindowsNvmlDeviceGetPcieThroughputDelegate _windowsNvmlDeviceGetPcieThroughputDelegate;
|
||||
private static WindowsNvmlDeviceGetPciInfo _windowsNvmlDeviceGetPciInfo;
|
||||
private static WindowsNvmlGetPowerUsageDelegate _windowsNvmlDeviceGetPowerUsage;
|
||||
private static WindowsNvmlDelegate _windowsNvmlInit;
|
||||
private static WindowsNvmlDelegate _windowsNvmlShutdown;
|
||||
|
||||
public enum NvmlPcieUtilCounter
|
||||
{
|
||||
TxBytes = 0,
|
||||
RxBytes = 1
|
||||
}
|
||||
|
||||
public enum NvmlReturn
|
||||
{
|
||||
/// <summary>
|
||||
/// The operation was successful
|
||||
/// </summary>
|
||||
Success = 0,
|
||||
|
||||
/// <summary>
|
||||
/// NvidiaML was not first initialized with nvmlInit()
|
||||
/// </summary>
|
||||
Uninitialized = 1,
|
||||
|
||||
/// <summary>
|
||||
/// A supplied argument is invalid
|
||||
/// </summary>
|
||||
InvalidArgument = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The requested operation is not available on target device
|
||||
/// </summary>
|
||||
NotSupported = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The current user does not have permission for operation
|
||||
/// </summary>
|
||||
NoPermission = 4,
|
||||
|
||||
/// <summary>
|
||||
/// A query to find an object was unsuccessful
|
||||
/// </summary>
|
||||
NotFound = 6,
|
||||
|
||||
/// <summary>
|
||||
/// An input argument is not large enough
|
||||
/// </summary>
|
||||
InsufficientSize = 7,
|
||||
|
||||
/// <summary>
|
||||
/// A device's external power cables are not properly attached
|
||||
/// </summary>
|
||||
InsufficientPower = 8,
|
||||
|
||||
/// <summary>
|
||||
/// NVIDIA driver is not loaded
|
||||
/// </summary>
|
||||
DriverNotLoaded = 9,
|
||||
|
||||
/// <summary>
|
||||
/// User provided timeout passed
|
||||
/// </summary>
|
||||
TimeOut = 10,
|
||||
|
||||
/// <summary>
|
||||
/// NVIDIA Kernel detected an interrupt issue with a GPU
|
||||
/// </summary>
|
||||
IRQIssue = 11,
|
||||
|
||||
/// <summary>
|
||||
/// NvidiaML Shared Library couldn't be found or loaded
|
||||
/// </summary>
|
||||
LibraryNotFound = 12,
|
||||
|
||||
/// <summary>
|
||||
/// Local version of NvidiaML doesn't implement this function
|
||||
/// </summary>
|
||||
FunctionNotFound = 13,
|
||||
|
||||
/// <summary>
|
||||
/// infoROM is corrupted
|
||||
/// </summary>
|
||||
CorruptedInfoRom = 14,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU has fallen off the bus or has otherwise become inaccessible
|
||||
/// </summary>
|
||||
GpuIsLost = 15,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU requires a reset before it can be used again
|
||||
/// </summary>
|
||||
ResetRequired = 16,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU control device has been blocked by the operating system/cgroups
|
||||
/// </summary>
|
||||
OperatingSystem = 17,
|
||||
|
||||
/// <summary>
|
||||
/// RM detects a driver/library version mismatch
|
||||
/// </summary>
|
||||
LibRmVersionMismatch = 18,
|
||||
|
||||
/// <summary>
|
||||
/// An operation cannot be performed because the GPU is currently in use
|
||||
/// </summary>
|
||||
InUse = 19,
|
||||
|
||||
/// <summary>
|
||||
/// An public driver error occurred
|
||||
/// </summary>
|
||||
Unknown = 999
|
||||
}
|
||||
|
||||
public static bool IsAvailable { get; private set; }
|
||||
|
||||
public static bool Initialize()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
try
|
||||
{
|
||||
IsAvailable = nvmlInit() == NvmlReturn.Success;
|
||||
}
|
||||
catch (DllNotFoundException)
|
||||
{ }
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
try
|
||||
{
|
||||
IsAvailable = nvmlInitLegacy() == NvmlReturn.Success;
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
else if (IsNvmlCompatibleWindowsVersion())
|
||||
{
|
||||
// Attempt to load the Nvidia Management Library from the
|
||||
// windows standard search order for applications. This will
|
||||
// help installations that either have the library in
|
||||
// %windir%/system32 or provide their own library
|
||||
_windowsDll = Kernel32.LoadLibrary(WindowsDllName);
|
||||
|
||||
// If there is no dll in the path, then attempt to load it
|
||||
// from program files
|
||||
if (_windowsDll == IntPtr.Zero)
|
||||
{
|
||||
string programFilesDirectory = Environment.ExpandEnvironmentVariables("%ProgramW6432%");
|
||||
string dllPath = Path.Combine(programFilesDirectory, @"NVIDIA Corporation\NVSMI", WindowsDllName);
|
||||
|
||||
_windowsDll = Kernel32.LoadLibrary(dllPath);
|
||||
}
|
||||
|
||||
IsAvailable = (_windowsDll != IntPtr.Zero) && InitialiseDelegates() && (_windowsNvmlInit() == NvmlReturn.Success);
|
||||
}
|
||||
|
||||
return IsAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsNvmlCompatibleWindowsVersion()
|
||||
{
|
||||
return Software.OperatingSystem.Is64Bit && ((Environment.OSVersion.Version.Major > 6) || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1));
|
||||
}
|
||||
|
||||
private static bool InitialiseDelegates()
|
||||
{
|
||||
IntPtr nvmlInit = Kernel32.GetProcAddress(_windowsDll, "nvmlInit_v2");
|
||||
|
||||
if (nvmlInit != IntPtr.Zero)
|
||||
{
|
||||
_windowsNvmlInit = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlInit, typeof(WindowsNvmlDelegate));
|
||||
}
|
||||
else
|
||||
{
|
||||
nvmlInit = Kernel32.GetProcAddress(_windowsDll, "nvmlInit");
|
||||
if (nvmlInit != IntPtr.Zero)
|
||||
_windowsNvmlInit = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlInit, typeof(WindowsNvmlDelegate));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
IntPtr nvmlShutdown = Kernel32.GetProcAddress(_windowsDll, "nvmlShutdown");
|
||||
if (nvmlShutdown != IntPtr.Zero)
|
||||
_windowsNvmlShutdown = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlShutdown, typeof(WindowsNvmlDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetHandle = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByIndex_v2");
|
||||
if (nvmlGetHandle != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByIndex = (WindowsNvmlGetHandleDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandle, typeof(WindowsNvmlGetHandleDelegate));
|
||||
else
|
||||
{
|
||||
nvmlGetHandle = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByIndex");
|
||||
if (nvmlGetHandle != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByIndex = (WindowsNvmlGetHandleDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandle, typeof(WindowsNvmlGetHandleDelegate));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
IntPtr nvmlGetPowerUsage = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPowerUsage");
|
||||
if (nvmlGetPowerUsage != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPowerUsage = (WindowsNvmlGetPowerUsageDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPowerUsage, typeof(WindowsNvmlGetPowerUsageDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetPcieThroughput = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPcieThroughput");
|
||||
if (nvmlGetPcieThroughput != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPcieThroughputDelegate = (WindowsNvmlDeviceGetPcieThroughputDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPcieThroughput, typeof(WindowsNvmlDeviceGetPcieThroughputDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetHandlePciBus = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByPciBusId_v2");
|
||||
if (nvmlGetHandlePciBus != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByPciBusId = (WindowsNvmlGetHandleByPciBusIdDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandlePciBus, typeof(WindowsNvmlGetHandleByPciBusIdDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlDeviceGetPciInfo = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPciInfo_v2");
|
||||
if (nvmlDeviceGetPciInfo != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPciInfo = (WindowsNvmlDeviceGetPciInfo)Marshal.GetDelegateForFunctionPointer(nvmlDeviceGetPciInfo, typeof(WindowsNvmlDeviceGetPciInfo));
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
nvmlShutdown();
|
||||
}
|
||||
else if (_windowsDll != IntPtr.Zero)
|
||||
{
|
||||
_windowsNvmlShutdown();
|
||||
Kernel32.FreeLibrary(_windowsDll);
|
||||
}
|
||||
|
||||
IsAvailable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static NvmlDevice? NvmlDeviceGetHandleByIndex(int index)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
NvmlDevice nvmlDevice;
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (nvmlDeviceGetHandleByIndex(index, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
if (nvmlDeviceGetHandleByIndexLegacy(index, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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) LibreHardwareMonitor and Contributors.
|
||||
// All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LibreHardwareMonitor.Interop;
|
||||
|
||||
internal static class NvidiaML
|
||||
{
|
||||
private const string LinuxDllName = "nvidia-ml";
|
||||
private const string WindowsDllName = "nvml.dll";
|
||||
|
||||
private static readonly object _syncRoot = new();
|
||||
|
||||
private static IntPtr _windowsDll;
|
||||
|
||||
private static WindowsNvmlGetHandleDelegate _windowsNvmlDeviceGetHandleByIndex;
|
||||
private static WindowsNvmlGetHandleByPciBusIdDelegate _windowsNvmlDeviceGetHandleByPciBusId;
|
||||
private static WindowsNvmlDeviceGetPcieThroughputDelegate _windowsNvmlDeviceGetPcieThroughputDelegate;
|
||||
private static WindowsNvmlDeviceGetPciInfo _windowsNvmlDeviceGetPciInfo;
|
||||
private static WindowsNvmlGetPowerUsageDelegate _windowsNvmlDeviceGetPowerUsage;
|
||||
private static WindowsNvmlDelegate _windowsNvmlInit;
|
||||
private static WindowsNvmlDelegate _windowsNvmlShutdown;
|
||||
|
||||
public enum NvmlPcieUtilCounter
|
||||
{
|
||||
TxBytes = 0,
|
||||
RxBytes = 1
|
||||
}
|
||||
|
||||
public enum NvmlReturn
|
||||
{
|
||||
/// <summary>
|
||||
/// The operation was successful
|
||||
/// </summary>
|
||||
Success = 0,
|
||||
|
||||
/// <summary>
|
||||
/// NvidiaML was not first initialized with nvmlInit()
|
||||
/// </summary>
|
||||
Uninitialized = 1,
|
||||
|
||||
/// <summary>
|
||||
/// A supplied argument is invalid
|
||||
/// </summary>
|
||||
InvalidArgument = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The requested operation is not available on target device
|
||||
/// </summary>
|
||||
NotSupported = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The current user does not have permission for operation
|
||||
/// </summary>
|
||||
NoPermission = 4,
|
||||
|
||||
/// <summary>
|
||||
/// A query to find an object was unsuccessful
|
||||
/// </summary>
|
||||
NotFound = 6,
|
||||
|
||||
/// <summary>
|
||||
/// An input argument is not large enough
|
||||
/// </summary>
|
||||
InsufficientSize = 7,
|
||||
|
||||
/// <summary>
|
||||
/// A device's external power cables are not properly attached
|
||||
/// </summary>
|
||||
InsufficientPower = 8,
|
||||
|
||||
/// <summary>
|
||||
/// NVIDIA driver is not loaded
|
||||
/// </summary>
|
||||
DriverNotLoaded = 9,
|
||||
|
||||
/// <summary>
|
||||
/// User provided timeout passed
|
||||
/// </summary>
|
||||
TimeOut = 10,
|
||||
|
||||
/// <summary>
|
||||
/// NVIDIA Kernel detected an interrupt issue with a GPU
|
||||
/// </summary>
|
||||
IRQIssue = 11,
|
||||
|
||||
/// <summary>
|
||||
/// NvidiaML Shared Library couldn't be found or loaded
|
||||
/// </summary>
|
||||
LibraryNotFound = 12,
|
||||
|
||||
/// <summary>
|
||||
/// Local version of NvidiaML doesn't implement this function
|
||||
/// </summary>
|
||||
FunctionNotFound = 13,
|
||||
|
||||
/// <summary>
|
||||
/// infoROM is corrupted
|
||||
/// </summary>
|
||||
CorruptedInfoRom = 14,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU has fallen off the bus or has otherwise become inaccessible
|
||||
/// </summary>
|
||||
GpuIsLost = 15,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU requires a reset before it can be used again
|
||||
/// </summary>
|
||||
ResetRequired = 16,
|
||||
|
||||
/// <summary>
|
||||
/// The GPU control device has been blocked by the operating system/cgroups
|
||||
/// </summary>
|
||||
OperatingSystem = 17,
|
||||
|
||||
/// <summary>
|
||||
/// RM detects a driver/library version mismatch
|
||||
/// </summary>
|
||||
LibRmVersionMismatch = 18,
|
||||
|
||||
/// <summary>
|
||||
/// An operation cannot be performed because the GPU is currently in use
|
||||
/// </summary>
|
||||
InUse = 19,
|
||||
|
||||
/// <summary>
|
||||
/// An public driver error occurred
|
||||
/// </summary>
|
||||
Unknown = 999
|
||||
}
|
||||
|
||||
public static bool IsAvailable { get; private set; }
|
||||
|
||||
public static bool Initialize()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
try
|
||||
{
|
||||
IsAvailable = nvmlInit() == NvmlReturn.Success;
|
||||
}
|
||||
catch (DllNotFoundException)
|
||||
{ }
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
try
|
||||
{
|
||||
IsAvailable = nvmlInitLegacy() == NvmlReturn.Success;
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
else if (IsNvmlCompatibleWindowsVersion())
|
||||
{
|
||||
// Attempt to load the Nvidia Management Library from the
|
||||
// windows standard search order for applications. This will
|
||||
// help installations that either have the library in
|
||||
// %windir%/system32 or provide their own library
|
||||
_windowsDll = Kernel32.LoadLibrary(WindowsDllName);
|
||||
|
||||
// If there is no dll in the path, then attempt to load it
|
||||
// from program files
|
||||
if (_windowsDll == IntPtr.Zero)
|
||||
{
|
||||
string programFilesDirectory = Environment.ExpandEnvironmentVariables("%ProgramW6432%");
|
||||
string dllPath = Path.Combine(programFilesDirectory, @"NVIDIA Corporation\NVSMI", WindowsDllName);
|
||||
|
||||
_windowsDll = Kernel32.LoadLibrary(dllPath);
|
||||
}
|
||||
|
||||
IsAvailable = (_windowsDll != IntPtr.Zero) && InitialiseDelegates() && (_windowsNvmlInit() == NvmlReturn.Success);
|
||||
}
|
||||
|
||||
return IsAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsNvmlCompatibleWindowsVersion()
|
||||
{
|
||||
return Software.OperatingSystem.Is64Bit && ((Environment.OSVersion.Version.Major > 6) || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1));
|
||||
}
|
||||
|
||||
private static bool InitialiseDelegates()
|
||||
{
|
||||
IntPtr nvmlInit = Kernel32.GetProcAddress(_windowsDll, "nvmlInit_v2");
|
||||
|
||||
if (nvmlInit != IntPtr.Zero)
|
||||
{
|
||||
_windowsNvmlInit = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlInit, typeof(WindowsNvmlDelegate));
|
||||
}
|
||||
else
|
||||
{
|
||||
nvmlInit = Kernel32.GetProcAddress(_windowsDll, "nvmlInit");
|
||||
if (nvmlInit != IntPtr.Zero)
|
||||
_windowsNvmlInit = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlInit, typeof(WindowsNvmlDelegate));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
IntPtr nvmlShutdown = Kernel32.GetProcAddress(_windowsDll, "nvmlShutdown");
|
||||
if (nvmlShutdown != IntPtr.Zero)
|
||||
_windowsNvmlShutdown = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlShutdown, typeof(WindowsNvmlDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetHandle = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByIndex_v2");
|
||||
if (nvmlGetHandle != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByIndex = (WindowsNvmlGetHandleDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandle, typeof(WindowsNvmlGetHandleDelegate));
|
||||
else
|
||||
{
|
||||
nvmlGetHandle = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByIndex");
|
||||
if (nvmlGetHandle != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByIndex = (WindowsNvmlGetHandleDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandle, typeof(WindowsNvmlGetHandleDelegate));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
IntPtr nvmlGetPowerUsage = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPowerUsage");
|
||||
if (nvmlGetPowerUsage != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPowerUsage = (WindowsNvmlGetPowerUsageDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPowerUsage, typeof(WindowsNvmlGetPowerUsageDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetPcieThroughput = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPcieThroughput");
|
||||
if (nvmlGetPcieThroughput != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPcieThroughputDelegate = (WindowsNvmlDeviceGetPcieThroughputDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPcieThroughput, typeof(WindowsNvmlDeviceGetPcieThroughputDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetHandlePciBus = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByPciBusId_v2");
|
||||
if (nvmlGetHandlePciBus != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByPciBusId = (WindowsNvmlGetHandleByPciBusIdDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandlePciBus, typeof(WindowsNvmlGetHandleByPciBusIdDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlDeviceGetPciInfo = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPciInfo_v2");
|
||||
if (nvmlDeviceGetPciInfo != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetPciInfo = (WindowsNvmlDeviceGetPciInfo)Marshal.GetDelegateForFunctionPointer(nvmlDeviceGetPciInfo, typeof(WindowsNvmlDeviceGetPciInfo));
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
nvmlShutdown();
|
||||
}
|
||||
else if (_windowsDll != IntPtr.Zero)
|
||||
{
|
||||
_windowsNvmlShutdown();
|
||||
Kernel32.FreeLibrary(_windowsDll);
|
||||
}
|
||||
|
||||
IsAvailable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static NvmlDevice? NvmlDeviceGetHandleByIndex(int index)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
NvmlDevice nvmlDevice;
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (nvmlDeviceGetHandleByIndex(index, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
if (nvmlDeviceGetHandleByIndexLegacy(index, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_windowsNvmlDeviceGetHandleByIndex(index, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NvmlDevice? NvmlDeviceGetHandleByPciBusId(string pciBusId)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
NvmlDevice nvmlDevice;
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (nvmlDeviceGetHandleByPciBusId(pciBusId, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
else
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NvmlDevice? NvmlDeviceGetHandleByPciBusId(string pciBusId)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
NvmlDevice nvmlDevice;
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (nvmlDeviceGetHandleByPciBusId(pciBusId, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -327,151 +327,152 @@ internal static class NvidiaML
|
||||
return nvmlDevice;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int? NvmlDeviceGetPowerUsage(NvmlDevice nvmlDevice)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
int powerUsage;
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (nvmlDeviceGetPowerUsage(nvmlDevice, out powerUsage) == NvmlReturn.Success)
|
||||
return powerUsage;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int? NvmlDeviceGetPowerUsage(NvmlDevice nvmlDevice)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
int powerUsage;
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (nvmlDeviceGetPowerUsage(nvmlDevice, out powerUsage) == NvmlReturn.Success)
|
||||
return powerUsage;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
if (_windowsNvmlDeviceGetPowerUsage(nvmlDevice, out powerUsage) == NvmlReturn.Success)
|
||||
return powerUsage;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static uint? NvmlDeviceGetPcieThroughput(NvmlDevice nvmlDevice, NvmlPcieUtilCounter counter)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
uint pcieThroughput;
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (nvmlDeviceGetPcieThroughput(nvmlDevice, counter, out pcieThroughput) == NvmlReturn.Success)
|
||||
return pcieThroughput;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static uint? NvmlDeviceGetPcieThroughput(NvmlDevice nvmlDevice, NvmlPcieUtilCounter counter)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
uint pcieThroughput;
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (nvmlDeviceGetPcieThroughput(nvmlDevice, counter, out pcieThroughput) == NvmlReturn.Success)
|
||||
return pcieThroughput;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
if (_windowsNvmlDeviceGetPcieThroughputDelegate(nvmlDevice, counter, out pcieThroughput) == NvmlReturn.Success)
|
||||
return pcieThroughput;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NvmlPciInfo? NvmlDeviceGetPciInfo(NvmlDevice nvmlDevice)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
var pci = new NvmlPciInfo();
|
||||
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (nvmlDeviceGetPciInfo(nvmlDevice, ref pci) == NvmlReturn.Success)
|
||||
return pci;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NvmlPciInfo? NvmlDeviceGetPciInfo(NvmlDevice nvmlDevice)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
var pci = new NvmlPciInfo();
|
||||
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (nvmlDeviceGetPciInfo(nvmlDevice, ref pci) == NvmlReturn.Success)
|
||||
return pci;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_windowsNvmlDeviceGetPciInfo(nvmlDevice, ref pci) == NvmlReturn.Success)
|
||||
return pci;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlInit_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlInit();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlInit", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlInitLegacy();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlShutdown", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlShutdown();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByIndex_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByIndex(int index, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByPciBusId_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByPciBusId([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByIndex", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByIndexLegacy(int index, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPowerUsage", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetPowerUsage(NvmlDevice device, out int power);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPcieThroughput", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetPcieThroughput(NvmlDevice device, NvmlPcieUtilCounter counter, out uint value);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPciInfo_v2")]
|
||||
private static extern NvmlReturn nvmlDeviceGetPciInfo(NvmlDevice device, ref NvmlPciInfo pci);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDelegate();
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetHandleDelegate(int index, out NvmlDevice device);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetHandleByPciBusIdDelegate([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetPowerUsageDelegate(NvmlDevice device, out int power);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDeviceGetPcieThroughputDelegate(NvmlDevice device, NvmlPcieUtilCounter counter, out uint value);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDeviceGetPciInfo(NvmlDevice device, ref NvmlPciInfo pci);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NvmlDevice
|
||||
{
|
||||
public IntPtr Handle;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NvmlPciInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
|
||||
public string busId;
|
||||
|
||||
public uint domain;
|
||||
|
||||
public uint bus;
|
||||
|
||||
public uint device;
|
||||
|
||||
public ushort pciVendorId;
|
||||
|
||||
public ushort pciDeviceId;
|
||||
|
||||
public uint pciSubSystemId;
|
||||
|
||||
public uint reserved0;
|
||||
public uint reserved1;
|
||||
public uint reserved2;
|
||||
public uint reserved3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlInit_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlInit();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlInit", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlInitLegacy();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlShutdown", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlShutdown();
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByIndex_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByIndex(int index, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByPciBusId_v2", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByPciBusId([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByIndex", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetHandleByIndexLegacy(int index, out NvmlDevice device);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPowerUsage", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetPowerUsage(NvmlDevice device, out int power);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPcieThroughput", ExactSpelling = true)]
|
||||
private static extern NvmlReturn nvmlDeviceGetPcieThroughput(NvmlDevice device, NvmlPcieUtilCounter counter, out uint value);
|
||||
|
||||
[DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPciInfo_v2")]
|
||||
private static extern NvmlReturn nvmlDeviceGetPciInfo(NvmlDevice device, ref NvmlPciInfo pci);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDelegate();
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetHandleDelegate(int index, out NvmlDevice device);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetHandleByPciBusIdDelegate([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetPowerUsageDelegate(NvmlDevice device, out int power);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDeviceGetPcieThroughputDelegate(NvmlDevice device, NvmlPcieUtilCounter counter, out uint value);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlDeviceGetPciInfo(NvmlDevice device, ref NvmlPciInfo pci);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NvmlDevice
|
||||
{
|
||||
public IntPtr Handle;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NvmlPciInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
|
||||
public string busId;
|
||||
|
||||
public uint domain;
|
||||
|
||||
public uint bus;
|
||||
|
||||
public uint device;
|
||||
|
||||
public ushort pciVendorId;
|
||||
|
||||
public ushort pciDeviceId;
|
||||
|
||||
public uint pciSubSystemId;
|
||||
|
||||
public uint reserved0;
|
||||
public uint reserved1;
|
||||
public uint reserved2;
|
||||
public uint reserved3;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user