@@ -35,6 +35,8 @@ namespace LibreHardwareMonitor.Hardware.Gpu
|
||||
_handle = handle;
|
||||
_displayHandle = displayHandle;
|
||||
|
||||
bool hasPciBusId = NvApi.NvAPI_GPU_GetBusId(handle, out uint busId) == NvApi.NvStatus.OK;
|
||||
|
||||
NvApi.NvGPUThermalSettings thermalSettings = GetThermalSettings();
|
||||
_temperatures = new Sensor[thermalSettings.Count];
|
||||
for (int i = 0; i < _temperatures.Length; i++)
|
||||
@@ -105,7 +107,11 @@ namespace LibreHardwareMonitor.Hardware.Gpu
|
||||
|
||||
if (NvidiaML.IsAvailable)
|
||||
{
|
||||
_nvmlDevice = NvidiaML.NvmlDeviceGetHandleByIndex(adapterIndex);
|
||||
if (hasPciBusId)
|
||||
_nvmlDevice = NvidiaML.NvmlDeviceGetHandleByPciBusId($" 0000:{busId:X2}:00.0") ?? NvidiaML.NvmlDeviceGetHandleByIndex(_adapterIndex);
|
||||
else
|
||||
_nvmlDevice = NvidiaML.NvmlDeviceGetHandleByIndex(_adapterIndex);
|
||||
|
||||
if (_nvmlDevice.HasValue)
|
||||
{
|
||||
_powerUsage = new Sensor("GPU Package", 0, SensorType.Power, this, settings);
|
||||
|
||||
@@ -31,7 +31,6 @@ namespace LibreHardwareMonitor.Hardware.Gpu
|
||||
}
|
||||
|
||||
NvApi.NvPhysicalGpuHandle[] handles = new NvApi.NvPhysicalGpuHandle[NvApi.MAX_PHYSICAL_GPUS];
|
||||
int count;
|
||||
if (NvApi.NvAPI_EnumPhysicalGPUs == null)
|
||||
{
|
||||
_report.AppendLine("Error: NvAPI_EnumPhysicalGPUs not available");
|
||||
@@ -39,27 +38,26 @@ namespace LibreHardwareMonitor.Hardware.Gpu
|
||||
return;
|
||||
}
|
||||
|
||||
NvApi.NvStatus status = NvApi.NvAPI_EnumPhysicalGPUs(handles, out int count);
|
||||
if (status != NvApi.NvStatus.OK)
|
||||
{
|
||||
NvApi.NvStatus status = NvApi.NvAPI_EnumPhysicalGPUs(handles, out count);
|
||||
if (status != NvApi.NvStatus.OK)
|
||||
{
|
||||
_report.AppendLine("Status: " + status);
|
||||
_report.AppendLine();
|
||||
return;
|
||||
}
|
||||
_report.AppendLine("Status: " + status);
|
||||
_report.AppendLine();
|
||||
return;
|
||||
}
|
||||
|
||||
IDictionary<NvApi.NvPhysicalGpuHandle, NvApi.NvDisplayHandle> displayHandles = new Dictionary<NvApi.NvPhysicalGpuHandle, NvApi.NvDisplayHandle>();
|
||||
if (NvApi.NvAPI_EnumNvidiaDisplayHandle != null && NvApi.NvAPI_GetPhysicalGPUsFromDisplay != null)
|
||||
{
|
||||
NvApi.NvStatus status = NvApi.NvStatus.OK;
|
||||
status = NvApi.NvStatus.OK;
|
||||
int i = 0;
|
||||
while (status == NvApi.NvStatus.OK)
|
||||
{
|
||||
NvApi.NvDisplayHandle displayHandle = new NvApi.NvDisplayHandle();
|
||||
status = NvApi.NvAPI_EnumNvidiaDisplayHandle(i, ref displayHandle);
|
||||
i++;
|
||||
|
||||
NvApi.NvDisplayHandle a;
|
||||
|
||||
if (status == NvApi.NvStatus.OK)
|
||||
{
|
||||
NvApi.NvPhysicalGpuHandle[] handlesFromDisplay = new NvApi.NvPhysicalGpuHandle[NvApi.MAX_PHYSICAL_GPUS];
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace LibreHardwareMonitor.Interop
|
||||
public static readonly NvAPI_GPU_GetPCIIdentifiersDelegate NvAPI_GPU_GetPCIIdentifiers;
|
||||
public static readonly NvAPI_GPU_GetPStatesDelegate NvAPI_GPU_GetPStates;
|
||||
public static readonly NvAPI_GPU_GetTachReadingDelegate NvAPI_GPU_GetTachReading;
|
||||
public static readonly NvAPI_GPU_GetBusIdDelegate NvAPI_GPU_GetBusId;
|
||||
|
||||
public static readonly NvAPI_GPU_GetThermalSettingsDelegate NvAPI_GPU_GetThermalSettings;
|
||||
public static readonly NvAPI_GPU_GetUsagesDelegate NvAPI_GPU_GetUsages;
|
||||
@@ -91,6 +92,9 @@ namespace LibreHardwareMonitor.Interop
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate NvStatus NvAPI_GPU_SetCoolerLevelsDelegate(NvPhysicalGpuHandle gpuHandle, int coolerIndex, ref NvGPUCoolerLevels NvGPUCoolerLevels);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate NvStatus NvAPI_GPU_GetBusIdDelegate(NvPhysicalGpuHandle gpuHandle, out uint busId);
|
||||
|
||||
static NvApi()
|
||||
{
|
||||
NvAPI_InitializeDelegate nvApiInitialize;
|
||||
@@ -129,6 +133,7 @@ namespace LibreHardwareMonitor.Interop
|
||||
GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
|
||||
GetDelegate(0x01053FA5, out _nvAPI_GetInterfaceVersionString);
|
||||
GetDelegate(0x2DDFB66E, out NvAPI_GPU_GetPCIIdentifiers);
|
||||
GetDelegate(0x1BE0B8E5, out NvAPI_GPU_GetBusId);
|
||||
|
||||
IsAvailable = true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace LibreHardwareMonitor.Interop
|
||||
|
||||
private static WindowsNvmlGetHandleDelegate _windowsNvmlDeviceGetHandleByIndex;
|
||||
private static WindowsNvmlGetPowerUsageDelegate _windowsNvmlDeviceGetPowerUsage;
|
||||
private static WindowsNvmlGetHandleByPciBusIdDelegate _windowsNvmlDeviceGetHandleByPciBusId;
|
||||
private static WindowsNvmlDelegate _windowsNvmlInit;
|
||||
private static WindowsNvmlDelegate _windowsNvmlShutdown;
|
||||
|
||||
@@ -118,6 +119,11 @@ namespace LibreHardwareMonitor.Interop
|
||||
else
|
||||
return false;
|
||||
|
||||
IntPtr nvmlGetHandlePciBus = Kernel32.GetProcAddress(WindowsDll, "nvmlDeviceGetHandleByPciBusId_v2");
|
||||
if (nvmlGetHandlePciBus != IntPtr.Zero)
|
||||
_windowsNvmlDeviceGetHandleByPciBusId = (WindowsNvmlGetHandleByPciBusIdDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandlePciBus, typeof(WindowsNvmlGetHandleByPciBusIdDelegate));
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -165,6 +171,26 @@ namespace LibreHardwareMonitor.Interop
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
internal static NvmlDevice? NvmlDeviceGetHandleByPciBusId(string pciBusId)
|
||||
{
|
||||
if (IsAvailable)
|
||||
{
|
||||
NvmlDevice nvmlDevice;
|
||||
if (Software.OperatingSystem.IsLinux)
|
||||
{
|
||||
if (nvmlDeviceGetHandleByPciBusId(pciBusId, out nvmlDevice) == NvmlReturn.Success)
|
||||
return nvmlDevice;
|
||||
}
|
||||
else if (_windowsNvmlDeviceGetHandleByPciBusId(pciBusId, out nvmlDevice) == NvmlReturn.Success)
|
||||
{
|
||||
return nvmlDevice;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static int? NvmlDeviceGetPowerUsage(NvmlDevice nvmlDevice)
|
||||
{
|
||||
if (IsAvailable)
|
||||
@@ -197,6 +223,9 @@ namespace LibreHardwareMonitor.Interop
|
||||
[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);
|
||||
|
||||
@@ -207,8 +236,10 @@ namespace LibreHardwareMonitor.Interop
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetHandleDelegate(int index, out NvmlDevice device);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetPowerUsageDelegate(NvmlDevice device, out int power);
|
||||
private delegate NvmlReturn WindowsNvmlGetHandleByPciBusIdDelegate([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device);
|
||||
|
||||
private delegate NvmlReturn WindowsNvmlGetPowerUsageDelegate(NvmlDevice device, out int power);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NvmlDevice
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user