Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Unified Diff: gpu/config/gpu_info_collector_win.cc

Issue 893993006: Enumerate all display adapters to detect AMD switchable graphics. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..bd543945144e098ead78f8f719727dadd2d490af 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,33 @@ CollectInfoResult CollectDriverInfoD3D(const std::wstring& device_id,
GPUInfo* gpu_info) {
TRACE_EVENT0("gpu", "CollectDriverInfoD3D");
+ GUID display_class = {0x4d36e968,
+ 0xe325,
+ 0x11ce,
+ {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
Zhenyao Mo 2015/02/05 23:04:28 nit: can you add a comment where the above data co
+
// 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 +464,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 +636,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 +688,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;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698