--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -445,21 +445,24 @@ GfxInfo::Init()
uint32_t adapterVendorID[2] = {0, 0};
uint32_t adapterDeviceID[2] = {0, 0};
uint32_t adapterSubsysID[2] = {0, 0};
adapterVendorID[0] = ParseIDFromDeviceID(mDeviceID[0], "VEN_", 4);
adapterDeviceID[0] = ParseIDFromDeviceID(mDeviceID[0], "&DEV_", 4);
adapterSubsysID[0] = ParseIDFromDeviceID(mDeviceID[0], "&SUBSYS_", 8);
- mAdapterVendorID[0].AppendPrintf("0x%04x", adapterVendorID[0]);
- mAdapterDeviceID[0].AppendPrintf("0x%04x", adapterDeviceID[0]);
- mAdapterSubsysID[0].AppendPrintf("%08x", adapterSubsysID[0]);
+ // Sometimes we don't get the valid device using this method. For now,
+ // allow zero vendor or device as valid, as long as the other value is
+ // non-zero.
+ bool foundValidDevice = (adapterVendorID[0] != 0 ||
+ adapterDeviceID[0] != 0);
- // We now check for second display adapter.
+ // We now check for second display adapter. If we didn't find the valid
+ // device using the original approach, we will try the alternative.
// Device interface class for display adapters.
CLSID GUID_DISPLAY_DEVICE_ARRIVAL;
HRESULT hresult = CLSIDFromString(L"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
&GUID_DISPLAY_DEVICE_ARRIVAL);
if (hresult == NOERROR) {
devinfo = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL,
nullptr, nullptr,
@@ -498,18 +501,21 @@ GfxInfo::Init()
result = RegQueryValueExW(key, L"MatchingDeviceId", nullptr,
nullptr, (LPBYTE)value, &dwcbData);
if (result != ERROR_SUCCESS) {
continue;
}
deviceID2 = value;
adapterVendorID[1] = ParseIDFromDeviceID(deviceID2, "VEN_", 4);
adapterDeviceID[1] = ParseIDFromDeviceID(deviceID2, "&DEV_", 4);
- if (adapterVendorID[0] == adapterVendorID[1] &&
- adapterDeviceID[0] == adapterDeviceID[1]) {
+ // Skip the devices we already considered, as well as any
+ // "zero" ones.
+ if ((adapterVendorID[0] == adapterVendorID[1] &&
+ adapterDeviceID[0] == adapterDeviceID[1]) ||
+ (adapterVendorID[1] == 0 && adapterDeviceID[1] == 0)) {
RegCloseKey(key);
continue;
}
// If this device is missing driver information, it is unlikely to
// be a real display adapter.
if (NS_FAILED(GetKeyValue(driverKey2.get(), L"InstalledDisplayDrivers",
adapterDriver2, REG_MULTI_SZ))) {
@@ -537,16 +543,31 @@ GfxInfo::Init()
nullptr, (LPBYTE)value, &dwcbData);
if (result != ERROR_SUCCESS) {
dwcbData = sizeof(value);
result = RegQueryValueExW(key, L"DriverDesc", nullptr, nullptr,
(LPBYTE)value, &dwcbData);
}
RegCloseKey(key);
if (result == ERROR_SUCCESS) {
+ // If we didn't find a valid device with the original method
+ // take this one, and continue looking for the second GPU.
+ if (!foundValidDevice) {
+ foundValidDevice = true;
+ adapterVendorID[0] = adapterVendorID[1];
+ adapterDeviceID[0] = adapterDeviceID[1];
+ mDeviceString[0] = value;
+ mDeviceID[0] = deviceID2;
+ mDeviceKey[0] = driverKey2;
+ mDriverVersion[0] = driverVersion2;
+ mDriverDate[0] = driverDate2;
+ adapterSubsysID[0] = ParseIDFromDeviceID(mDeviceID[0], "&SUBSYS_", 8);
+ continue;
+ }
+
mHasDualGPU = true;
mDeviceString[1] = value;
mDeviceID[1] = deviceID2;
mDeviceKey[1] = driverKey2;
mDriverVersion[1] = driverVersion2;
mDriverDate[1] = driverDate2;
adapterSubsysID[1] = ParseIDFromDeviceID(mDeviceID[1], "&SUBSYS_", 8);
mAdapterVendorID[1].AppendPrintf("0x%04x", adapterVendorID[1]);
@@ -557,16 +578,20 @@ GfxInfo::Init()
}
}
}
SetupDiDestroyDeviceInfoList(devinfo);
}
}
+ mAdapterVendorID[0].AppendPrintf("0x%04x", adapterVendorID[0]);
+ mAdapterDeviceID[0].AppendPrintf("0x%04x", adapterDeviceID[0]);
+ mAdapterSubsysID[0].AppendPrintf("%08x", adapterSubsysID[0]);
+
// Sometimes, the enumeration is not quite right and the two adapters
// end up being swapped. Actually enumerate the adapters that come
// back from the DXGI factory to check, and tag the second as active
// if found.
if (mHasDualGPU) {
nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll"));
decltype(CreateDXGIFactory)* createDXGIFactory = (decltype(CreateDXGIFactory)*)
GetProcAddress(dxgiModule, "CreateDXGIFactory");