| Index: gpu/config/gpu_info_collector_win.cc
|
| diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc
|
| index 04f66fad6afc76fbf5f0e4e54082b4cb8ad7635f..a5686a9de6ad8b2a53087aef5ed719fc7b86c50a 100644
|
| --- a/gpu/config/gpu_info_collector_win.cc
|
| +++ b/gpu/config/gpu_info_collector_win.cc
|
| @@ -8,6 +8,7 @@
|
| #include "third_party/re2/re2/re2.h"
|
|
|
| #include <windows.h>
|
| +#include <cfgmgr32.h>
|
| #include <d3d9.h>
|
| #include <d3d11.h>
|
| #include <dxgi.h>
|
| @@ -363,6 +364,24 @@ void CollectD3D11Support() {
|
| base::Bind(CollectD3D11SupportOnWorkerThread),
|
| false);
|
| }
|
| +
|
| +void DeviceIDToVendorAndDevice(const std::wstring& id,
|
| + uint32* vendor_id,
|
| + uint32* device_id) {
|
| + *vendor_id = 0;
|
| + *device_id = 0;
|
| + if (id.length() < 21)
|
| + return;
|
| + base::string16 vendor_id_string = id.substr(8, 4);
|
| + base::string16 device_id_string = id.substr(17, 4);
|
| + int vendor = 0;
|
| + int device = 0;
|
| + base::HexStringToInt(base::UTF16ToASCII(vendor_id_string), &vendor);
|
| + base::HexStringToInt(base::UTF16ToASCII(device_id_string), &device);
|
| + *vendor_id = vendor;
|
| + *device_id = device;
|
| +}
|
| +
|
| } // namespace anonymous
|
|
|
| #if defined(GOOGLE_CHROME_BUILD) && defined(OFFICIAL_BUILD)
|
| @@ -380,17 +399,35 @@ CollectInfoResult CollectDriverInfoD3D(const std::wstring& device_id,
|
| GPUInfo* gpu_info) {
|
| TRACE_EVENT0("gpu", "CollectDriverInfoD3D");
|
|
|
| + // Display adapter class GUID from
|
| + // https://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx
|
| + GUID display_class = {0x4d36e968,
|
| + 0xe325,
|
| + 0x11ce,
|
| + {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
|
| +
|
| // create device info for the display device
|
| - HDEVINFO device_info = SetupDiGetClassDevsW(
|
| - NULL, device_id.c_str(), NULL,
|
| - DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
|
| + HDEVINFO device_info =
|
| + SetupDiGetClassDevsW(&display_class, NULL, NULL, DIGCF_PRESENT);
|
| if (device_info == INVALID_HANDLE_VALUE) {
|
| LOG(ERROR) << "Creating device info failed";
|
| return kCollectInfoNonFatalFailure;
|
| }
|
|
|
| + struct GPUDriver {
|
| + GPUInfo::GPUDevice device;
|
| + std::string driver_vendor;
|
| + std::string driver_version;
|
| + std::string driver_date;
|
| + };
|
| +
|
| + std::vector<GPUDriver> drivers;
|
| +
|
| + int primary_device = -1;
|
| + bool found_amd = false;
|
| + bool found_intel = false;
|
| +
|
| DWORD index = 0;
|
| - bool found = false;
|
| SP_DEVINFO_DATA device_info_data;
|
| device_info_data.cbSize = sizeof(device_info_data);
|
| while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) {
|
| @@ -429,35 +466,85 @@ CollectInfoResult CollectDriverInfoD3D(const std::wstring& device_id,
|
| result = RegQueryValueExW(
|
| key, L"ProviderName", NULL, NULL,
|
| reinterpret_cast<LPBYTE>(value), &dwcb_data);
|
| - if (result == ERROR_SUCCESS) {
|
| + if (result == ERROR_SUCCESS)
|
| driver_vendor = base::UTF16ToASCII(std::wstring(value));
|
| - if (driver_vendor == "Advanced Micro Devices, Inc." ||
|
| - driver_vendor == "ATI Technologies Inc.") {
|
| - // We are conservative and assume that in the absence of a clear
|
| - // signal the videocard is assumed to be switchable. Additionally,
|
| - // some switchable systems with Intel GPUs aren't correctly
|
| - // detected, so always count them.
|
| - GetAMDVideocardInfo(gpu_info);
|
| - if (!gpu_info->amd_switchable &&
|
| - gpu_info->gpu.vendor_id == 0x8086) {
|
| - gpu_info->amd_switchable = true;
|
| - gpu_info->secondary_gpus.push_back(gpu_info->gpu);
|
| - gpu_info->gpu.vendor_id = 0x1002;
|
| - gpu_info->gpu.device_id = 0; // Unknown discrete AMD GPU.
|
| - }
|
| - }
|
| +
|
| + wchar_t new_device_id[MAX_DEVICE_ID_LEN];
|
| + CONFIGRET status = CM_Get_Device_ID(
|
| + device_info_data.DevInst, new_device_id, MAX_DEVICE_ID_LEN, 0);
|
| +
|
| + if (status == CR_SUCCESS) {
|
| + GPUDriver driver;
|
| +
|
| + driver.driver_vendor = driver_vendor;
|
| + driver.driver_version = driver_version;
|
| + driver.driver_date = driver_date;
|
| + std::wstring id = new_device_id;
|
| +
|
| + if (id.compare(0, device_id.size(), device_id) == 0)
|
| + primary_device = drivers.size();
|
| +
|
| + uint32 vendor_id = 0, device_id = 0;
|
| + DeviceIDToVendorAndDevice(id, &vendor_id, &device_id);
|
| + driver.device.vendor_id = vendor_id;
|
| + driver.device.device_id = device_id;
|
| + drivers.push_back(driver);
|
| +
|
| + if (vendor_id == 0x8086)
|
| + found_intel = true;
|
| + if (vendor_id == 0x1002)
|
| + found_amd = true;
|
| }
|
|
|
| - gpu_info->driver_vendor = driver_vendor;
|
| - gpu_info->driver_version = driver_version;
|
| - gpu_info->driver_date = driver_date;
|
| - found = true;
|
| RegCloseKey(key);
|
| - break;
|
| }
|
| }
|
| }
|
| SetupDiDestroyDeviceInfoList(device_info);
|
| + bool found = false;
|
| + if (found_amd && found_intel) {
|
| + // AMD Switchable system found.
|
| + for (const auto& driver : drivers) {
|
| + if (driver.device.vendor_id == 0x8086) {
|
| + gpu_info->gpu = driver.device;
|
| + }
|
| +
|
| + if (driver.device.vendor_id == 0x1002) {
|
| + gpu_info->driver_vendor = driver.driver_vendor;
|
| + gpu_info->driver_version = driver.driver_version;
|
| + gpu_info->driver_date = driver.driver_date;
|
| + }
|
| + }
|
| + GetAMDVideocardInfo(gpu_info);
|
| +
|
| + if (!gpu_info->amd_switchable) {
|
| + // Some machines aren't properly detected as AMD switchable, but count
|
| + // them anyway.
|
| + gpu_info->amd_switchable = true;
|
| + for (const auto& driver : drivers) {
|
| + if (driver.device.vendor_id == 0x1002) {
|
| + gpu_info->gpu = driver.device;
|
| + } else {
|
| + gpu_info->secondary_gpus.push_back(driver.device);
|
| + }
|
| + }
|
| + }
|
| + found = true;
|
| + } else {
|
| + for (size_t i = 0; i < drivers.size(); ++i) {
|
| + const GPUDriver& driver = drivers[i];
|
| + if (static_cast<int>(i) == primary_device) {
|
| + found = true;
|
| + gpu_info->gpu = driver.device;
|
| + gpu_info->driver_vendor = driver.driver_vendor;
|
| + gpu_info->driver_version = driver.driver_version;
|
| + gpu_info->driver_date = driver.driver_date;
|
| + } else {
|
| + gpu_info->secondary_gpus.push_back(driver.device);
|
| + }
|
| + }
|
| + }
|
| +
|
| return found ? kCollectInfoSuccess : kCollectInfoNonFatalFailure;
|
| }
|
|
|
| @@ -551,13 +638,7 @@ CollectInfoResult CollectGpuID(uint32* vendor_id, uint32* device_id) {
|
| }
|
|
|
| if (id.length() > 20) {
|
| - int vendor = 0, device = 0;
|
| - std::wstring vendor_string = id.substr(8, 4);
|
| - std::wstring device_string = id.substr(17, 4);
|
| - base::HexStringToInt(base::UTF16ToASCII(vendor_string), &vendor);
|
| - base::HexStringToInt(base::UTF16ToASCII(device_string), &device);
|
| - *vendor_id = vendor;
|
| - *device_id = device;
|
| + DeviceIDToVendorAndDevice(id, vendor_id, device_id);
|
| if (*vendor_id != 0 && *device_id != 0)
|
| return kCollectInfoSuccess;
|
| }
|
| @@ -609,13 +690,8 @@ CollectInfoResult CollectBasicGraphicsInfo(GPUInfo* gpu_info) {
|
| return kCollectInfoNonFatalFailure;
|
| }
|
|
|
| - int vendor_id = 0, device_id = 0;
|
| - base::string16 vendor_id_string = id.substr(8, 4);
|
| - base::string16 device_id_string = id.substr(17, 4);
|
| - base::HexStringToInt(base::UTF16ToASCII(vendor_id_string), &vendor_id);
|
| - base::HexStringToInt(base::UTF16ToASCII(device_id_string), &device_id);
|
| - gpu_info->gpu.vendor_id = vendor_id;
|
| - gpu_info->gpu.device_id = device_id;
|
| + DeviceIDToVendorAndDevice(id, &gpu_info->gpu.vendor_id,
|
| + &gpu_info->gpu.device_id);
|
| // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE.
|
| if (!CollectDriverInfoD3D(id, gpu_info)) {
|
| gpu_info->basic_info_state = kCollectInfoNonFatalFailure;
|
|
|