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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace LibreHardwareMonitor.Hardware.Gpu;
|
||||
|
||||
internal class AmdGpuGroup : IGroup
|
||||
{
|
||||
private readonly IntPtr _context = IntPtr.Zero;
|
||||
private readonly List<AmdGpu> _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<AmdGpu> 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<string, AmdGpu> 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<IHardware> 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)
|
||||
{ }
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user