diff --git a/src/gpu_info_util/SystemInfo_mac.mm b/src/gpu_info_util/SystemInfo_mac.mm index 8728d3e770..e37c842df8 100644 --- a/src/gpu_info_util/SystemInfo_mac.mm +++ b/src/gpu_info_util/SystemInfo_mac.mm @@ -118,40 +118,64 @@ bool GetEntryProperty(io_registry_entry_t entry, CFStringRef name, uint32_t *val return true; } -// Gathers the vendor and device IDs for the PCI GPUs -bool GetPCIDevices(std::vector *devices) +// Gathers the vendor and device IDs for GPUs listed in the IORegistry. +void GetIORegistryDevices(std::vector *devices) { - // matchDictionary will be consumed by IOServiceGetMatchingServices, no need to release it. - CFMutableDictionaryRef matchDictionary = IOServiceMatching("IOPCIDevice"); - - io_iterator_t entryIterator; - if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchDictionary, &entryIterator) != - kIOReturnSuccess) + constexpr uint32_t kNumServices = 2; + const char *kServiceNames[kNumServices] = {"IOPCIDevice", "AGXAccelerator"}; + const bool kServiceIsVGA[kNumServices] = {true, false}; + for (uint32_t i = 0; i < kNumServices; ++i) { - return false; - } + // matchDictionary will be consumed by IOServiceGetMatchingServices, no need to release it. + CFMutableDictionaryRef matchDictionary = IOServiceMatching(kServiceNames[i]); - io_registry_entry_t entry = IO_OBJECT_NULL; + io_iterator_t entryIterator; + if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchDictionary, &entryIterator) != + kIOReturnSuccess) + { + continue; + } - while ((entry = IOIteratorNext(entryIterator)) != IO_OBJECT_NULL) - { - constexpr uint32_t kClassCodeDisplayVGA = 0x30000; - uint32_t classCode; - GPUDeviceInfo info; - - if (GetEntryProperty(entry, CFSTR("class-code"), &classCode) && - classCode == kClassCodeDisplayVGA && - GetEntryProperty(entry, CFSTR("vendor-id"), &info.vendorId) && - GetEntryProperty(entry, CFSTR("device-id"), &info.deviceId)) + io_registry_entry_t entry = IO_OBJECT_NULL; + while ((entry = IOIteratorNext(entryIterator)) != IO_OBJECT_NULL) { + constexpr uint32_t kClassCodeDisplayVGA = 0x30000; + uint32_t classCode; + GPUDeviceInfo info; + + // AGXAccelerator entries only provide a vendor ID. + if (!GetEntryProperty(entry, CFSTR("vendor-id"), &info.vendorId)) + { + continue; + } + + if (kServiceIsVGA[i]) + { + if (!GetEntryProperty(entry, CFSTR("class-code"), &classCode)) + { + continue; + } + if (classCode != kClassCodeDisplayVGA) + { + continue; + } + if (!GetEntryProperty(entry, CFSTR("device-id"), &info.deviceId)) + { + continue; + } + } + devices->push_back(info); + IOObjectRelease(entry); } + IOObjectRelease(entryIterator); - IOObjectRelease(entry); + // If any devices have been populated by IOPCIDevice, do not continue to AGXAccelerator. + if (!devices->empty()) + { + break; + } } - IOObjectRelease(entryIterator); - - return true; } void SetActiveGPUIndex(SystemInfo *info) @@ -203,11 +227,7 @@ bool GetSystemInfo(SystemInfo *info) info->machineModelVersion = std::to_string(major) + "." + std::to_string(minor); } - if (!GetPCIDevices(&(info->gpus))) - { - return false; - } - + GetIORegistryDevices(&info->gpus); if (info->gpus.empty()) { return false;