From 07234e3594ef0f170f4a82a23ba273e5fbb90b99 Mon Sep 17 00:00:00 2001 From: Emerson Pinter Date: Thu, 2 May 2024 16:42:22 -0300 Subject: [PATCH] Avoid multiple initializations of AmdGpu (#1324) ADL finds multiple logical gpus, this commit avoids multiple unneeded initializations of AmdGpu class. The main control is moved to AmdGpuGroup and the ADL_* calls are updated to ADL2_*, using the context. Adapters using PMlog should be initialized only if sensors are detected, adapters that pmlog is not enabled or doesn't work, should fallback previous logic. --- .../Hardware/Gpu/AmdGpu.cs | 29 ++----- .../Hardware/Gpu/AmdGpuGroup.cs | 77 ++++++++++++++++--- LibreHardwareMonitorLib/Interop/AtiAdlxx.cs | 65 ++++++---------- 3 files changed, 96 insertions(+), 75 deletions(-) diff --git a/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpu.cs b/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpu.cs index 40f92a3..659c950 100644 --- a/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpu.cs @@ -58,9 +58,11 @@ internal sealed class AmdGpu : GenericGpu private readonly ushort _pmLogSampleRate = 1000; private bool _overdrive8LogExists; - public AmdGpu(AtiAdlxx.ADLAdapterInfo adapterInfo, ISettings settings) + public AmdGpu(IntPtr amdContext, AtiAdlxx.ADLAdapterInfo adapterInfo, AtiAdlxx.ADLGcnInfo gcnInfo, ISettings settings) : base(adapterInfo.AdapterName.Trim(), new Identifier("gpu-amd", adapterInfo.AdapterIndex.ToString(CultureInfo.InvariantCulture)), settings) { + _context = amdContext; + _adlGcnInfo = gcnInfo; _adapterInfo = adapterInfo; BusNumber = adapterInfo.BusNumber; DeviceNumber = adapterInfo.DeviceNumber; @@ -137,13 +139,6 @@ internal sealed class AmdGpu : GenericGpu int supported = 0; int enabled = 0; int version = 0; - _adlGcnInfo = new(); - - if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Main_Control_Create)) && - AtiAdlxx.ADL2_Main_Control_Create(AtiAdlxx.Main_Memory_Alloc, _adapterInfo.AdapterIndex, ref _context) != AtiAdlxx.ADLStatus.ADL_OK) - { - _context = IntPtr.Zero; - } if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_FrameMetrics_Caps)) && AtiAdlxx.ADL2_Adapter_FrameMetrics_Caps(_context, _adapterInfo.AdapterIndex, ref supported) == AtiAdlxx.ADLStatus.ADL_OK && @@ -155,12 +150,7 @@ internal sealed class AmdGpu : GenericGpu ActivateSensor(_fullscreenFps); } - if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_GcnAsicInfo_Get))) - { - AtiAdlxx.ADL2_GcnAsicInfo_Get(_context, _adapterInfo.AdapterIndex, ref _adlGcnInfo); - } - - if (_adlGcnInfo.ASICFamilyId >= (int)AtiAdlxx.GCNFamilies.FAMILY_AI && + if (AtiAdlxx.UsePmLogForFamily(_adlGcnInfo.ASICFamilyId) && AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_PMLog_Support_Get)) && AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Device_PMLog_Device_Create)) && AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_PMLog_Start))) @@ -169,7 +159,7 @@ internal sealed class AmdGpu : GenericGpu _adlPMLogSupportInfo = new(); _adlPMLogStartOutput = new AtiAdlxx.ADLPMLogStartOutput(); _adlPMLogStartInput.usSensors = new ushort[AtiAdlxx.ADL_PMLOG_MAX_SENSORS]; - + if (_device == 0 && AtiAdlxx.ADLStatus.ADL_OK == AtiAdlxx.ADL2_Device_PMLog_Device_Create(_context, _adapterInfo.AdapterIndex, ref _device) && AtiAdlxx.ADLStatus.ADL_OK == AtiAdlxx.ADL2_Adapter_PMLog_Support_Get(_context, _adapterInfo.AdapterIndex, ref _adlPMLogSupportInfo)) @@ -406,7 +396,7 @@ internal sealed class AmdGpu : GenericGpu private bool IsSensorSupportedByPMLog(AtiAdlxx.ADLPMLogSensors sensorType) { - if (!_pmLogStarted || (int)sensorType == 0) + if (!_pmLogStarted || (int)sensorType == 0) return false; for (int i = 0; i < AtiAdlxx.ADL_PMLOG_MAX_SENSORS; i++) @@ -440,7 +430,7 @@ internal sealed class AmdGpu : GenericGpu if (!supportedByPMLog && !supportedByOD8) { - if (reset) + if (reset) sensor.Value = null; return false; @@ -642,9 +632,6 @@ internal sealed class AmdGpu : GenericGpu AtiAdlxx.ADL2_Device_PMLog_Device_Destroy(_context, _device); } - if (_context != IntPtr.Zero) - AtiAdlxx.ADL2_Main_Control_Destroy(_context); - base.Close(); } @@ -893,7 +880,7 @@ internal sealed class AmdGpu : GenericGpu foreach (AtiAdlxx.ADLPMLogSensors sensorType in Enum.GetValues(typeof(AtiAdlxx.ADLPMLogSensors))) { int i = (int)sensorType; - if (i == 0) + if (i == 0) continue; bool supported = false; diff --git a/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpuGroup.cs b/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpuGroup.cs index d54e7f3..ab2f8ca 100644 --- a/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpuGroup.cs +++ b/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpuGroup.cs @@ -15,6 +15,7 @@ namespace LibreHardwareMonitor.Hardware.Gpu; internal class AmdGpuGroup : IGroup { + private readonly IntPtr _context = IntPtr.Zero; private readonly List _hardware = new(); private readonly StringBuilder _report = new(); private readonly AtiAdlxx.ADLStatus _status; @@ -23,7 +24,7 @@ internal class AmdGpuGroup : IGroup { try { - _status = AtiAdlxx.ADL_Main_Control_Create(1); + _status = AtiAdlxx.ADL2_Main_Control_Create(AtiAdlxx.Main_Memory_Alloc, 1, ref _context); _report.AppendLine("AMD Display Library"); _report.AppendLine(); @@ -34,7 +35,7 @@ internal class AmdGpuGroup : IGroup if (_status == AtiAdlxx.ADLStatus.ADL_OK) { int numberOfAdapters = 0; - AtiAdlxx.ADL_Adapter_NumberOfAdapters_Get(ref numberOfAdapters); + AtiAdlxx.ADL2_Adapter_NumberOfAdapters_Get(_context, ref numberOfAdapters); _report.Append("Number of adapters: "); _report.AppendLine(numberOfAdapters.ToString(CultureInfo.InvariantCulture)); @@ -45,15 +46,23 @@ internal class AmdGpuGroup : IGroup List potentialHardware = new(); AtiAdlxx.ADLAdapterInfo[] adapterInfo = new AtiAdlxx.ADLAdapterInfo[numberOfAdapters]; - if (AtiAdlxx.ADL_Adapter_AdapterInfo_Get(adapterInfo) == AtiAdlxx.ADLStatus.ADL_OK) + if (AtiAdlxx.ADL2_Adapter_AdapterInfo_Get(ref _context, adapterInfo) == AtiAdlxx.ADLStatus.ADL_OK) { for (int i = 0; i < numberOfAdapters; i++) { - AtiAdlxx.ADL_Adapter_Active_Get(adapterInfo[i].AdapterIndex, out int isActive); + uint device = 0; + AtiAdlxx.ADLGcnInfo gcnInfo = new(); + AtiAdlxx.ADLPMLogSupportInfo pmLogSupportInfo = new(); + AtiAdlxx.ADL2_Adapter_Active_Get(_context, adapterInfo[i].AdapterIndex, out int isActive); + + if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_GcnAsicInfo_Get))) + { + AtiAdlxx.ADL2_GcnAsicInfo_Get(_context, adapterInfo[i].AdapterIndex, ref gcnInfo); + } int adapterId = -1; - if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL_Adapter_ID_Get))) - AtiAdlxx.ADL_Adapter_ID_Get(adapterInfo[i].AdapterIndex, out adapterId); + if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_ID_Get))) + AtiAdlxx.ADL2_Adapter_ID_Get(_context, adapterInfo[i].AdapterIndex, out adapterId); _report.Append("AdapterIndex: "); _report.AppendLine(i.ToString(CultureInfo.InvariantCulture)); @@ -77,9 +86,43 @@ internal class AmdGpuGroup : IGroup _report.AppendLine(adapterInfo[i].FunctionNumber.ToString(CultureInfo.InvariantCulture)); _report.Append("AdapterID: 0x"); _report.AppendLine(adapterId.ToString("X", CultureInfo.InvariantCulture)); + _report.AppendLine("Family: " + gcnInfo.ASICFamilyId); - if (!string.IsNullOrEmpty(adapterInfo[i].UDID) && adapterInfo[i].VendorID == AtiAdlxx.ATI_VENDOR_ID) - potentialHardware.Add(new AmdGpu(adapterInfo[i], settings)); + int sensorsSupported = 0; + if (AtiAdlxx.UsePmLogForFamily(gcnInfo.ASICFamilyId) && + AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_PMLog_Support_Get)) && + AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Device_PMLog_Device_Create))) + { + if (AtiAdlxx.ADLStatus.ADL_OK == AtiAdlxx.ADL2_Device_PMLog_Device_Create(_context, adapterInfo[i].AdapterIndex, ref device) && + AtiAdlxx.ADLStatus.ADL_OK == AtiAdlxx.ADL2_Adapter_PMLog_Support_Get(_context, adapterInfo[i].AdapterIndex, ref pmLogSupportInfo)) + { + int k = 0; + while (pmLogSupportInfo.usSensors[k] != (ushort)AtiAdlxx.ADLPMLogSensors.ADL_SENSOR_MAXTYPES) + { + k++; + } + sensorsSupported = k; + } + _report.AppendLine("Sensors Supported: " + sensorsSupported); + + if (device != 0) + { + AtiAdlxx.ADL2_Device_PMLog_Device_Destroy(_context, device); + } + } + + if (!string.IsNullOrEmpty(adapterInfo[i].UDID) && adapterInfo[i].VendorID == AtiAdlxx.ATI_VENDOR_ID && + !IsAlreadyAdded(adapterInfo[i].BusNumber, adapterInfo[i].DeviceNumber)) + { + if (sensorsSupported > 0) + { + _hardware.Add(new AmdGpu(_context, adapterInfo[i], gcnInfo, settings)); + } + else + { + potentialHardware.Add(new AmdGpu(_context, adapterInfo[i], gcnInfo, settings)); + } + } _report.AppendLine(); } @@ -88,7 +131,7 @@ internal class AmdGpuGroup : IGroup foreach (IGrouping amdGpus in potentialHardware.GroupBy(x => $"{x.BusNumber}-{x.DeviceNumber}")) { AmdGpu amdGpu = amdGpus.OrderByDescending(x => x.Sensors.Length).FirstOrDefault(); - if (amdGpu != null) + if (amdGpu != null && !IsAlreadyAdded(amdGpu.BusNumber, amdGpu.DeviceNumber)) _hardware.Add(amdGpu); } } @@ -104,6 +147,18 @@ internal class AmdGpuGroup : IGroup } } + private bool IsAlreadyAdded(int busNumber, int deviceNumber) + { + foreach (AmdGpu g in _hardware) + { + if (g.BusNumber == busNumber && g.DeviceNumber == deviceNumber) + { + return true; + } + } + return false; + } + public IReadOnlyList Hardware => _hardware; public string GetReport() @@ -118,8 +173,8 @@ internal class AmdGpuGroup : IGroup foreach (AmdGpu gpu in _hardware) gpu.Close(); - if (_status == AtiAdlxx.ADLStatus.ADL_OK) - AtiAdlxx.ADL_Main_Control_Destroy(); + if (_status == AtiAdlxx.ADLStatus.ADL_OK && _context != IntPtr.Zero) + AtiAdlxx.ADL2_Main_Control_Destroy(_context); } catch (Exception) { } diff --git a/LibreHardwareMonitorLib/Interop/AtiAdlxx.cs b/LibreHardwareMonitorLib/Interop/AtiAdlxx.cs index 0ebb43d..adead65 100644 --- a/LibreHardwareMonitorLib/Interop/AtiAdlxx.cs +++ b/LibreHardwareMonitorLib/Interop/AtiAdlxx.cs @@ -50,38 +50,6 @@ internal static class AtiAdlxx public delegate IntPtr Context(int size); - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Main_Control_Create(ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Main_Control_Destroy(); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Adapter_AdapterInfo_Get(IntPtr info, int size); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Adapter_NumberOfAdapters_Get(); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Adapter_NumberOfAdapters_Get(ref int numAdapters); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Adapter_ID_Get(int adapterIndex, out int adapterId); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Display_AdapterID_Get(int adapterIndex, out int adapterId); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Adapter_Active_Get(int adapterIndex, out int status); - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] public static extern ADLStatus ADL_Overdrive5_ODParameters_Get(int adapterIndex, out ADLODParameters parameters); @@ -142,10 +110,6 @@ internal static class AtiAdlxx [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] public static extern ADLStatus ADL2_New_QueryPMLogData_Get(IntPtr context, int adapterIndex, ref ADLPMLogDataOutput aDLPMLogDataOutput); - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - public static extern ADLStatus ADL_Graphics_Versions_Get(out ADLVersionsInfo versionInfo); - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] public static extern ADLStatus ADL2_Adapter_FrameMetrics_Caps(IntPtr context, int adapterIndex, ref int supported); @@ -190,6 +154,22 @@ internal static class AtiAdlxx [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] public static extern ADLStatus ADL2_GcnAsicInfo_Get(IntPtr context, int adapterIndex, ref ADLGcnInfo gcnInfo); + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Adapter_NumberOfAdapters_Get(IntPtr context, ref int numAdapters); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Adapter_AdapterInfo_Get(IntPtr context, IntPtr adapterInfo, int size); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Adapter_ID_Get(IntPtr context, int adapterIndex, out int adapterId); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Adapter_Active_Get(IntPtr context, int adapterIndex, out int status); + public static bool ADL_Method_Exists(string ADL_Method) { IntPtr module = Kernel32.LoadLibrary(DllName); @@ -203,11 +183,11 @@ internal static class AtiAdlxx return false; } - public static ADLStatus ADL_Main_Control_Create(int enumConnectedAdapters) + public static ADLStatus ADL2_Main_Control_Create(IntPtr context, int enumConnectedAdapters) { try { - return ADL_Method_Exists(nameof(ADL_Main_Control_Create)) ? ADL_Main_Control_Create(Main_Memory_Alloc, enumConnectedAdapters) : ADLStatus.ADL_ERR; + return ADL_Method_Exists(nameof(ADL2_Main_Control_Create)) ? ADL2_Main_Control_Create(Main_Memory_Alloc, enumConnectedAdapters, ref context) : ADLStatus.ADL_ERR; } catch { @@ -215,12 +195,12 @@ internal static class AtiAdlxx } } - public static ADLStatus ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) + public static ADLStatus ADL2_Adapter_AdapterInfo_Get(ref IntPtr context, ADLAdapterInfo[] info) { int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo)); int size = info.Length * elementSize; IntPtr ptr = Marshal.AllocHGlobal(size); - ADLStatus result = ADL_Adapter_AdapterInfo_Get(ptr, size); + ADLStatus result = ADL2_Adapter_AdapterInfo_Get(context, ptr, size); for (int i = 0; i < info.Length; i++) info[i] = (ADLAdapterInfo)Marshal.PtrToStructure((IntPtr)((long)ptr + (i * elementSize)), typeof(ADLAdapterInfo)); @@ -249,10 +229,9 @@ internal static class AtiAdlxx return result; } - public static void Main_Memory_Free(IntPtr buffer) + public static bool UsePmLogForFamily(int familyId) { - if (IntPtr.Zero != buffer) - Marshal.FreeHGlobal(buffer); + return familyId >= (int)GCNFamilies.FAMILY_AI; } internal enum ADLStatus