private bool QueryAdl() { // ADL does not get devices in order map devices by bus number // bus id, <name, uuid> var isAdlInit = true; var adlRet = -1; var numberOfAdapters = 0; var adl2Control = IntPtr.Zero; if (null != ADL.ADL_Main_Control_Create) { // Second parameter is 1: Get only the present adapters adlRet = ADL.ADL_Main_Control_Create(ADL.ADL_Main_Memory_Alloc, 1); } if (ADL.ADL_SUCCESS == adlRet) { ADL.ADL_Adapter_NumberOfAdapters_Get?.Invoke(ref numberOfAdapters); Helpers.ConsolePrint(Tag, "Number Of Adapters: " + numberOfAdapters); if (0 < numberOfAdapters) { // Get OS adpater info from ADL var osAdapterInfoData = new ADLAdapterInfoArray(); if (null != ADL.ADL_Adapter_AdapterInfo_Get) { var size = Marshal.SizeOf(osAdapterInfoData); var adapterBuffer = Marshal.AllocCoTaskMem(size); Marshal.StructureToPtr(osAdapterInfoData, adapterBuffer, false); adlRet = ADL.ADL_Adapter_AdapterInfo_Get(adapterBuffer, size); var adl2Ret = -1; if (ADL.ADL2_Main_Control_Create != null) { adl2Ret = ADL.ADL2_Main_Control_Create(ADL.ADL_Main_Memory_Alloc, 0, ref adl2Control); } var adl2Info = new ADLAdapterInfoArray(); var size2 = Marshal.SizeOf(adl2Info); var buffer = Marshal.AllocCoTaskMem(size2); if (adl2Ret == ADL.ADL_SUCCESS && ADL.ADL2_Adapter_AdapterInfo_Get != null) { Marshal.StructureToPtr(adl2Info, buffer, false); adl2Ret = ADL.ADL2_Adapter_AdapterInfo_Get(adl2Control, buffer, Marshal.SizeOf(adl2Info)); } else { adl2Ret = -1; } if (adl2Ret == ADL.ADL_SUCCESS) { adl2Info = (ADLAdapterInfoArray)Marshal.PtrToStructure(buffer, adl2Info.GetType()); } if (ADL.ADL_SUCCESS == adlRet) { osAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(adapterBuffer, osAdapterInfoData.GetType()); var isActive = 0; for (var i = 0; i < numberOfAdapters; i++) { // Check if the adapter is active if (null != ADL.ADL_Adapter_Active_Get) { adlRet = ADL.ADL_Adapter_Active_Get( osAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref isActive); } if (ADL.ADL_SUCCESS != adlRet) { continue; } // we are looking for amd // TODO check discrete and integrated GPU separation var vendorID = osAdapterInfoData.ADLAdapterInfo[i].VendorID; var devName = osAdapterInfoData.ADLAdapterInfo[i].AdapterName; if (vendorID != AmdVendorID && !devName.ToLower().Contains("amd") && !devName.ToLower().Contains("radeon") && !devName.ToLower().Contains("firepro")) { continue; } var pnpStr = osAdapterInfoData.ADLAdapterInfo[i].PNPString; // find vi controller pnp var infSection = ""; foreach (var vCtrl in _availableControllers) { if (vCtrl.PnpDeviceID == pnpStr) { infSection = vCtrl.InfSection; } } var backSlashLast = pnpStr.LastIndexOf('\\'); var serial = pnpStr.Substring(backSlashLast, pnpStr.Length - backSlashLast); var end0 = serial.IndexOf('&'); var end1 = serial.IndexOf('&', end0 + 1); // get serial serial = serial.Substring(end0 + 1, end1 - end0 - 1); var udid = osAdapterInfoData.ADLAdapterInfo[i].UDID; const int pciVenIDStrSize = 21; // PCI_VEN_XXXX&DEV_XXXX var uuid = udid.Substring(0, pciVenIDStrSize) + "_" + serial; var budId = osAdapterInfoData.ADLAdapterInfo[i].BusNumber; var index = osAdapterInfoData.ADLAdapterInfo[i].AdapterIndex; if (_amdDeviceUuid.Contains(uuid)) { continue; } try { Helpers.ConsolePrint(Tag, $"ADL device added BusNumber:{budId} NAME:{devName} UUID:{uuid}"); } catch (Exception e) { Helpers.ConsolePrint(Tag, e.Message); } _amdDeviceUuid.Add(uuid); //_busIds.Add(OSAdapterInfoData.ADLAdapterInfo[i].BusNumber); //_amdDeviceName.Add(devName); if (_busIdInfos.ContainsKey(budId)) { continue; } var adl2Index = -1; if (adl2Ret == ADL.ADL_SUCCESS) { adl2Index = adl2Info.ADLAdapterInfo .FirstOrDefault(a => a.UDID == osAdapterInfoData.ADLAdapterInfo[i].UDID) .AdapterIndex; } var info = new BusIdInfo { Name = devName, Uuid = uuid, InfSection = infSection, Adl1Index = index, Adl2Index = adl2Index }; _busIdInfos.Add(budId, info); } } else { Helpers.ConsolePrint(Tag, "ADL_Adapter_AdapterInfo_Get() returned error code " + adlRet); isAdlInit = false; } // Release the memory for the AdapterInfo structure if (IntPtr.Zero != adapterBuffer) { Marshal.FreeCoTaskMem(adapterBuffer); } if (buffer != IntPtr.Zero) { Marshal.FreeCoTaskMem(buffer); } } } if (null != ADL.ADL_Main_Control_Destroy && numberOfAdapters <= 0) { // Close ADL if it found no AMD devices ADL.ADL_Main_Control_Destroy(); } if (ADL.ADL2_Main_Control_Destroy != null && adl2Control != IntPtr.Zero) { ADL.ADL2_Main_Control_Destroy(adl2Control); } } else { // TODO Helpers.ConsolePrint(Tag, "ADL_Main_Control_Create() returned error code " + adlRet); Helpers.ConsolePrint(Tag, "Check if ADL is properly installed!"); isAdlInit = false; } return(isAdlInit); }