Files
ReLibreHardwareMonitor/LibreHardwareMonitorLib/Interop/NvApi.cs
T
MadLongTomandPhyxionNL aa7c8be02f feat: Add Native AOT compilation support for LibreHardwareMonitorLib (#2280)
* feat: Add Native AOT compilation support for LibreHardwareMonitorLib

- Replace non-generic Marshal.GetDelegateForFunctionPointer with generic versions
  (NvApi.cs, NvidiaML.cs, OpCode.cs)
- Replace non-generic Marshal.PtrToStructure/SizeOf with generic versions
  (AtiAdlxx.cs, AmdGpu.cs, Ipmi.cs)
- Replace reflection-based Mono.Posix calls with direct Syscall for non-NETFRAMEWORK
  (OpCode.cs)
- Add DynamicallyAccessedMembers annotations for trim-safe generic marshaling
  (MsiCoreLiquidController.cs, WireViewPro2.cs)
- Add IsAotCompatible, IsTrimmable, and AOT/trim analyzers to csproj for net8.0+
- All changes maintain full backward compatibility with net472/netstandard2.0

Tested: dotnet publish with PublishAot=true on net10.0 win-x64 succeeds.
AOT binary correctly enumerates all hardware and sensors without errors.

* feat: Add conditional compilation for .NET 5.0 or greater in various classes

* feat: Add AOT test project and update workflows for AOT compilation

* Drop test project

* NET5_0_OR_GREATER > NET

---------

Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com>
2026-04-07 13:38:41 +02:00

695 lines
25 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
using Windows.Win32;
namespace LibreHardwareMonitor.Interop;
internal static class NvApi
{
public const int MAX_CLOCKS_PER_GPU = 0x120;
public const int MAX_COOLERS_PER_GPU = 20;
public const int MAX_FAN_CONTROLLER_ITEMS = 32;
public const int MAX_FAN_COOLERS_STATUS_ITEMS = 32;
public const int MAX_GPU_PUBLIC_CLOCKS = 32;
public const int MAX_GPU_UTILIZATIONS = 8;
public const int MAX_MEMORY_VALUES_PER_GPU = 5;
public const int MAX_PHYSICAL_GPUS = 64;
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 SHORT_STRING_MAX = 64;
public const int THERMAL_SENSOR_RESERVED_COUNT = 8;
public const int THERMAL_SENSOR_TEMPERATURE_COUNT = 32;
public const uint NVAPI_I2C_SPEED_DEPRECATED = 0xFFFF;
private const string DllName = "nvapi.dll";
private const string DllName64 = "nvapi64.dll";
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_GetMemoryInfoExDelegate NvAPI_GPU_GetMemoryInfoEx { 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; }
public static NvAPI_I2CReadExDelegate NvAPI_I2CReadEx { 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;
public static void Initialize()
{
NvAPI_InitializeDelegate nvApiInitialize;
try
{
if (!DllExists())
return;
nvApiInitialize = GetDelegate<NvAPI_InitializeDelegate>(0x0150E828);
}
catch (Exception e) when (e is DllNotFoundException or ArgumentNullException or EntryPointNotFoundException or BadImageFormatException)
{
return;
}
if (nvApiInitialize() == NvStatus.OK)
{
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_GPU_GetMemoryInfoEx = GetDelegate<NvAPI_GPU_GetMemoryInfoExDelegate>(0xC0599498);
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);
NvAPI_I2CReadEx = GetDelegate<NvAPI_I2CReadExDelegate>(0x4D7B0709);
NvAPI_GPU_ClientVoltRailsGetStatus = GetDelegate<NvAPI_GPU_ClientVoltRailsGetStatusDelegate>(0x465F9BCF);
IsAvailable = true;
}
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum, ref NvDisplayHandle displayHandle);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate([Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate(NvDisplayHandle displayHandle, [In, Out] ref NvDisplayDriverVersion nvDisplayDriverVersion);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GetInterfaceVersionStringDelegate(StringBuilder version);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles, out uint gpuCount);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_ClientFanCoolersGetControlDelegate(NvPhysicalGpuHandle gpuHandle, ref NvFanCoolerControl control);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_ClientFanCoolersGetStatusDelegate(NvPhysicalGpuHandle gpuHandle, ref NvFanCoolersStatus fanCoolersStatus);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_ClientFanCoolersSetControlDelegate(NvPhysicalGpuHandle gpuHandle, ref NvFanCoolerControl control);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_ClientPowerTopologyGetStatusDelegate(NvPhysicalGpuHandle gpuHandle, ref NvPowerTopology powerTopology);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetAllClockFrequenciesDelegate(NvPhysicalGpuHandle gpuHandle, ref NvGpuClockFrequencies clockFrequencies);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetAllClocksDelegate(NvPhysicalGpuHandle gpuHandle, ref NvClocks nvClocks);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetBusIdDelegate(NvPhysicalGpuHandle gpuHandle, out uint busId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate(NvPhysicalGpuHandle gpuHandle, NvCoolerTarget coolerTarget, ref NvCoolerSettings NvCoolerSettings);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetDynamicPstatesInfoExDelegate(NvPhysicalGpuHandle gpuHandle, ref NvDynamicPStatesInfo nvPStates);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate(NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetMemoryInfoExDelegate(NvPhysicalGpuHandle gpuHandle, ref NvMemoryInfoEx nvMemoryInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetPCIIdentifiersDelegate(NvPhysicalGpuHandle gpuHandle, out uint deviceId, out uint subSystemId, out uint revisionId, out uint extDeviceId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(NvPhysicalGpuHandle gpuHandle, out int value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetThermalSensorsDelegate(NvPhysicalGpuHandle gpuHandle, ref NvThermalSensors nvThermalSensors);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(NvPhysicalGpuHandle gpuHandle, int sensorIndex, ref NvThermalSettings NvThermalSettings);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_GetUsagesDelegate(NvPhysicalGpuHandle gpuHandle, ref NvUsages nvUsages);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(NvPhysicalGpuHandle gpuHandle, int coolerIndex, ref NvCoolerLevels NvCoolerLevels);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_I2CReadExDelegate(NvPhysicalGpuHandle gpuHandle, ref NvI2CInfo i2cInfo, ref uint readData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NvStatus NvAPI_GPU_ClientVoltRailsGetStatusDelegate(NvPhysicalGpuHandle gpuHandle, ref NvGpuClientVoltRailsStatus status);
public enum NvFanControlMode : uint
{
Auto = 0,
Manual = 1
}
public enum NvLevelPolicy : uint
{
None = 0,
Manual = 1,
Performance = 2,
TemperatureDiscrete = 4,
TemperatureContinuous = 8,
Silent = 16,
Auto = 32
}
public enum NvPowerTopologyDomain : uint
{
Gpu = 0,
Board
}
public enum NvUtilizationDomain
{
Gpu, // Core
FrameBuffer, // Memory Controller
VideoEngine, // Video Engine
BusInterface // Bus
}
public enum NvI2CSpeed : uint
{
Default = 0,
Speed3Khz = 1,
Speed10Khz = 2,
Speed33Khz = 3,
Speed100Khz = 4,
Speed200Khz = 5,
Speed400Khz = 6
}
public static bool IsAvailable { get; private set; }
[DllImport(DllName, EntryPoint = "nvapi_QueryInterface", CallingConvention = CallingConvention.Cdecl, PreserveSig = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern IntPtr NvAPI32_QueryInterface(uint interfaceId);
[DllImport(DllName64, EntryPoint = "nvapi_QueryInterface", CallingConvention = CallingConvention.Cdecl, PreserveSig = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern IntPtr NvAPI64_QueryInterface(uint interfaceId);
public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle, out string name)
{
StringBuilder builder = new(SHORT_STRING_MAX);
NvStatus status = _nvAPI_GPU_GetFullName?.Invoke(gpuHandle, builder) ?? NvStatus.FunctionNotFound;
name = builder.ToString();
return status;
}
public static NvStatus NvAPI_GetInterfaceVersionString(out string version)
{
StringBuilder builder = new(SHORT_STRING_MAX);
NvStatus status = _nvAPI_GetInterfaceVersionString?.Invoke(builder) ?? NvStatus.FunctionNotFound;
version = builder.ToString();
return status;
}
private static T GetDelegate<T>(uint id) where T : class
{
IntPtr ptr = Environment.Is64BitProcess ? NvAPI64_QueryInterface(id) : NvAPI32_QueryInterface(id);
if (ptr != IntPtr.Zero)
{
return Marshal.GetDelegateForFunctionPointer<T>(ptr);
}
else
{
return null;
}
}
public static bool DllExists()
{
FreeLibrarySafeHandle module = PInvoke.LoadLibrary(Environment.Is64BitProcess ? DllName64 : DllName);
if (module.IsInvalid)
return false;
module.Dispose();
return true;
}
internal static int MAKE_NVAPI_VERSION<T>(int ver)
{
return Marshal.SizeOf<T>() | (ver << 16);
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvFanCoolerControl
{
public uint Version;
private readonly uint _reserved;
public uint Count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)]
private readonly uint[] _reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_FAN_CONTROLLER_ITEMS)]
public NvFanCoolerControlItem[] Items;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvFanCoolerControlItem
{
public uint CoolerId;
public uint Level;
public NvFanControlMode ControlMode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)]
private readonly uint[] _reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvPowerTopology
{
public int Version;
public uint Count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_POWER_TOPOLOGIES, ArraySubType = UnmanagedType.Struct)]
public NvPowerTopologyEntry[] Entries;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvPowerTopologyEntry
{
public NvPowerTopologyDomain Domain;
private readonly uint _reserved;
public uint PowerUsage;
private readonly uint _reserved1;
}
internal enum NvStatus
{
OK = 0,
Error = -1,
LibraryNotFound = -2,
NoImplementation = -3,
ApiNotInitialized = -4,
InvalidArgument = -5,
NvidiaDeviceNotFound = -6,
EndEnumeration = -7,
InvalidHandle = -8,
IncompatibleStructVersion = -9,
HandleInvalidated = -10,
OpenGlContextNotCurrent = -11,
NoGlExpert = -12,
InstrumentationDisabled = -13,
ExpectedLogicalGpuHandle = -100,
ExpectedPhysicalGpuHandle = -101,
ExpectedDisplayHandle = -102,
InvalidCombination = -103,
NotSupported = -104,
PortIdNotFound = -105,
ExpectedUnattachedDisplayHandle = -106,
InvalidPerfLevel = -107,
DeviceBusy = -108,
NvPersistFileNotFound = -109,
PersistDataNotFound = -110,
ExpectedTvDisplay = -111,
ExpectedTvDisplayOnConnector = -112,
NoActiveSliTopology = -113,
SliRenderingModeNotAllowed = -114,
ExpectedDigitalFlatPanel = -115,
ArgumentExceedMaxSize = -116,
DeviceSwitchingNotAllowed = -117,
TestingClocksNotSupported = -118,
UnknownUnderscanConfig = -119,
TimeoutReconfiguringGpuTopo = -120,
DataNotFound = -121,
ExpectedAnalogDisplay = -122,
NoVidLink = -123,
RequiresReboot = -124,
InvalidHybridMode = -125,
MixedTargetTypes = -126,
Syswow64NotSupported = -127,
ImplicitSetGpuTopologyChangeNotAllowed = -128,
RequestUserToCloseNonMigratableApps = -129,
OutOfMemory = -130,
WasStillDrawing = -131,
FileNotFound = -132,
TooManyUniqueStateObjects = -133,
InvalidCall = -134,
D3D101LibraryNotFound = -135,
FunctionNotFound = -136
}
internal enum NvThermalController
{
None = 0,
GpuInternal,
Adm1032,
Max6649,
Max1617,
Lm99,
Lm89,
Lm64,
Adt7473,
SbMax6649,
VBiosEvt,
OS,
Unknown = -1
}
internal enum NvThermalTarget
{
None = 0,
Gpu = 1,
Memory = 2,
PowerSupply = 4,
Board = 8,
VisualComputingBoard = 9,
VisualComputingInlet = 10,
VisualComputingOutlet = 11,
All = 15,
Unknown = -1
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvSensor
{
public NvThermalController Controller;
public uint DefaultMinTemp;
public uint DefaultMaxTemp;
public uint CurrentTemp;
public NvThermalTarget Target;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvThermalSettings
{
public uint Version;
public uint Count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_THERMAL_SENSORS_PER_GPU)]
public NvSensor[] Sensor;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NvDisplayHandle
{
private readonly IntPtr ptr;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NvPhysicalGpuHandle
{
private readonly IntPtr ptr;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvClocks
{
public uint Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_CLOCKS_PER_GPU)]
public uint[] Clock;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvDynamicPStatesInfo
{
public uint Version;
public uint Flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_GPU_UTILIZATIONS)]
public NvDynamicPState[] Utilizations;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvDynamicPState
{
public bool IsPresent;
public int Percentage;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvUsages
{
public uint Version;
private readonly uint _reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public NvUsagesEntry[] Entries;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvUsagesEntry
{
public uint IsPresent;
public uint Percentage;
private readonly uint _reserved1;
private readonly uint _reserved2;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvCooler
{
public int Type;
public int Controller;
public int DefaultMin;
public int DefaultMax;
public int CurrentMin;
public int CurrentMax;
public int CurrentLevel;
public int DefaultPolicy;
public int CurrentPolicy;
public int Target;
public int ControlType;
public int Active;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvFanCoolersStatus
{
public uint Version;
public uint Count;
public ulong Reserved1;
public ulong Reserved2;
public ulong Reserved3;
public ulong Reserved4;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_FAN_COOLERS_STATUS_ITEMS)]
internal NvFanCoolersStatusItem[] Items;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvFanCoolersStatusItem
{
public uint CoolerId;
public uint CurrentRpm;
public uint CurrentMinLevel;
public uint CurrentMaxLevel;
public uint CurrentLevel;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)]
private readonly uint[] _reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvCoolerSettings
{
public uint Version;
public uint Count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_COOLERS_PER_GPU)]
public NvCooler[] Cooler;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvLevel
{
public int Level;
public NvLevelPolicy Policy;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvCoolerLevels
{
public uint Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_COOLERS_PER_GPU)]
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
{
public uint Version;
public uint DedicatedVideoMemory;
public uint AvailableDedicatedVideoMemory;
public uint SystemVideoMemory;
public uint SharedSystemMemory;
public uint CurrentAvailableDedicatedVideoMemory;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NvMemoryInfoEx
{
public uint Version;
public ulong DedicatedVideoMemory;
public ulong AvailableDedicatedVideoMemory;
public ulong SystemVideoMemory;
public ulong SharedSystemMemory;
public ulong CurrentAvailableDedicatedVideoMemory;
public ulong DedicatedVideoMemoryEvictionsSize;
public ulong DedicatedVideoMemoryEvictionCount;
public ulong DedicatedVideoMemoryPromotionsSize;
public ulong DedicatedVideoMemoryPromotionCount;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvDisplayDriverVersion
{
public uint Version;
public uint DriverVersion;
public uint BldChangeListNum;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = SHORT_STRING_MAX)]
public string BuildBranch;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = SHORT_STRING_MAX)]
public string Adapter;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvGpuClockFrequencies
{
public uint Version;
private readonly uint _reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_GPU_PUBLIC_CLOCKS)]
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,
Memory = 4,
Processor = 7,
Video = 8,
Undefined = MAX_CLOCKS_PER_GPU
}
internal enum NvGpuClockFrequenciesClockType
{
CurrentFrequency,
BaseClock,
BoostClock,
ClockTypeNumber
}
internal enum NvCoolerTarget
{
None = 0,
Gpu,
Memory,
PowerSupply = 4,
All = 7 // This cooler cools all of the components related to its target gpu.
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvGpuClockFrequenciesDomain
{
private readonly uint _isPresent;
public uint Frequency;
public bool IsPresent => (_isPresent & 1) != 0;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NvI2CInfo
{
public uint Version;
public uint DisplayMask;
public byte IsDDCPort;
public byte I2CDevAddress;
public IntPtr I2CRegAddress;
public uint RegAddrSize;
public IntPtr Data;
public uint Size;
public uint I2CSpeed;
public NvI2CSpeed I2CSpeedKhz;
public byte PortId;
public uint IsPortIdSet;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate NvStatus NvAPI_InitializeDelegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(NvPhysicalGpuHandle gpuHandle, StringBuilder name);
}