Commit 66665af2 by Christopher Cameron Committed by Commit Bot

macOS/ARM: Allow populating GPU based on AGXAccelerator

The existing scheme for populating GPU vendor and device IDs fails on macOS/ARM. If we find no PCI registry entries, look for a AGXAccelerator entry, and (partially) populate that. This is sufficient for Chrome to initialize hardware acceleration. It is unknown how this will interact with multiple GPUs, and this will likely need to be revisited. Bug: chromium:1110421 Change-Id: I08069d7aecf45c83a1d2827cfccc4733c1835994 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2324939Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarLingfeng Yang <lfy@google.com> Commit-Queue: ccameron <ccameron@chromium.org>
parent f776eb9c
......@@ -77,40 +77,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<GPUDeviceInfo> *devices)
// Gathers the vendor and device IDs for GPUs listed in the IORegistry.
void GetIORegistryDevices(std::vector<GPUDeviceInfo> *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)
......@@ -217,11 +241,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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment