Commit 1d8d106a authored by Zhenyao Mo's avatar Zhenyao Mo Committed by Commit Bot

Collect SubSysId and Revision of a GPU on Windows.

In many situations the same GPU on different OEM devices manifest
different behaviors, so it's important to switch from 2-part
identification of a GPU (vendor_id, device_id) to 4-part:
  (vendor_id, device_id, sub_sys_id, revision)

This is the first CL. This adds the fields to GPUInfo and add
the info collection and wire the info to about:gpu page.

BUG=1006960
TEST=gpu_unittests, about:gpu
R=sunnyps@chromium.org,dcheng@chromium.org

Change-Id: Ia8623cdf842ec8eb899a018c26c9267fb9a2c880
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1824457
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarAlexei Filippov <alph@chromium.org>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700382}
parent 00b647bd
......@@ -123,13 +123,18 @@ class AuxGPUInfoEnumerator : public gpu::GPUInfo::Enumerator {
std::unique_ptr<GPUDevice> GPUDeviceToProtocol(
const gpu::GPUInfo::GPUDevice& device) {
return GPUDevice::Create().SetVendorId(device.vendor_id)
.SetDeviceId(device.device_id)
.SetVendorString(device.vendor_string)
.SetDeviceString(device.device_string)
.SetDriverVendor(device.driver_vendor)
.SetDriverVersion(device.driver_version)
.Build();
return GPUDevice::Create()
.SetVendorId(device.vendor_id)
.SetDeviceId(device.device_id)
#if defined(OS_WIN)
.SetSubSysId(device.sub_sys_id)
.SetRevision(device.revision)
#endif
.SetVendorString(device.vendor_string)
.SetDeviceString(device.device_string)
.SetDriverVendor(device.driver_vendor)
.SetDriverVersion(device.driver_version)
.Build();
}
std::unique_ptr<SystemInfo::VideoDecodeAcceleratorCapability>
......
......@@ -115,7 +115,7 @@ std::unique_ptr<base::ListValue> DxDiagNodeToList(const gpu::DxDiagNode& node) {
}
return list;
}
#endif
#endif // OS_WIN
std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) {
std::string vendor = base::StringPrintf("0x%04x", gpu.vendor_id);
......@@ -124,8 +124,17 @@ std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) {
std::string device = base::StringPrintf("0x%04x", gpu.device_id);
if (!gpu.device_string.empty())
device += " [" + gpu.device_string + "]";
return base::StringPrintf("VENDOR = %s, DEVICE= %s%s",
vendor.c_str(), device.c_str(), gpu.active ? " *ACTIVE*" : "");
std::string rt = base::StringPrintf("VENDOR= %s, DEVICE=%s", vendor.c_str(),
device.c_str());
#if defined(OS_WIN)
if (gpu.sub_sys_id || gpu.revision) {
rt += base::StringPrintf(", SUBSYS=0x%08x, REV=%u", gpu.sub_sys_id,
gpu.revision);
}
#endif
if (gpu.active)
rt += " *ACTIVE*";
return rt;
}
std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
......
......@@ -14,6 +14,10 @@ void EnumerateGPUDevice(const gpu::GPUInfo::GPUDevice& device,
enumerator->BeginGPUDevice();
enumerator->AddInt("vendorId", device.vendor_id);
enumerator->AddInt("deviceId", device.device_id);
#if defined(OS_WIN)
enumerator->AddInt("subSysId", device.sub_sys_id);
enumerator->AddInt("revision", device.revision);
#endif // OS_WIN
enumerator->AddBool("active", device.active);
enumerator->AddString("vendorString", device.vendor_string);
enumerator->AddString("deviceString", device.device_string);
......@@ -155,11 +159,7 @@ operator=(const ImageDecodeAcceleratorSupportedProfile& other) = default;
ImageDecodeAcceleratorSupportedProfile& ImageDecodeAcceleratorSupportedProfile::
operator=(ImageDecodeAcceleratorSupportedProfile&& other) = default;
GPUInfo::GPUDevice::GPUDevice()
: vendor_id(0),
device_id(0),
active(false),
cuda_compute_capability_major(0) {}
GPUInfo::GPUDevice::GPUDevice() = default;
GPUInfo::GPUDevice::GPUDevice(const GPUInfo::GPUDevice& other) = default;
......
......@@ -194,15 +194,24 @@ struct GPU_EXPORT GPUInfo {
GPUDevice& operator=(GPUDevice&& other) noexcept;
// The DWORD (uint32_t) representing the graphics card vendor id.
uint32_t vendor_id;
uint32_t vendor_id = 0u;
// The DWORD (uint32_t) representing the graphics card device id.
// Device ids are unique to vendor, not to one another.
uint32_t device_id;
uint32_t device_id = 0u;
#if defined(OS_WIN)
// The graphics card subsystem id.
// The lower 16 bits represents the subsystem vendor id.
uint32_t sub_sys_id = 0u;
// The graphics card revision number.
uint32_t revision = 0u;
#endif // OS_WIN
// Whether this GPU is the currently used one.
// Currently this field is only supported and meaningful on OS X.
bool active;
bool active = false;
// The strings that describe the GPU.
// In Linux these strings are obtained through libpci.
......@@ -216,7 +225,7 @@ struct GPU_EXPORT GPUInfo {
// NVIDIA CUDA compute capability, major version. 0 if undetermined. Can be
// used to determine the hardware generation that the GPU belongs to.
int cuda_compute_capability_major;
int cuda_compute_capability_major = 0;
};
GPUInfo();
......
......@@ -123,6 +123,8 @@ bool CollectDriverInfoD3D(GPUInfo* gpu_info) {
GPUInfo::GPUDevice device;
device.vendor_id = desc.VendorId;
device.device_id = desc.DeviceId;
device.sub_sys_id = desc.SubSysId;
device.revision = desc.Revision;
LARGE_INTEGER umd_version;
hr = dxgi_adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice),
......
......@@ -13,6 +13,10 @@ import "ui/gfx/geometry/mojom/geometry.mojom";
struct GpuDevice {
uint32 vendor_id;
uint32 device_id;
[EnableIf=is_win]
uint32 sub_sys_id;
[EnableIf=is_win]
uint32 revision;
bool active;
string vendor_string;
string device_string;
......
......@@ -16,6 +16,10 @@ bool StructTraits<gpu::mojom::GpuDeviceDataView, gpu::GPUInfo::GPUDevice>::Read(
gpu::GPUInfo::GPUDevice* out) {
out->vendor_id = data.vendor_id();
out->device_id = data.device_id();
#if defined(OS_WIN)
out->sub_sys_id = data.sub_sys_id();
out->revision = data.revision();
#endif // OS_WIN
out->active = data.active();
out->cuda_compute_capability_major = data.cuda_compute_capability_major();
return data.ReadVendorString(&out->vendor_string) &&
......
......@@ -27,6 +27,16 @@ struct StructTraits<gpu::mojom::GpuDeviceDataView, gpu::GPUInfo::GPUDevice> {
return input.device_id;
}
#if defined(OS_WIN)
static uint32_t sub_sys_id(const gpu::GPUInfo::GPUDevice& input) {
return input.sub_sys_id;
}
static uint32_t revision(const gpu::GPUInfo::GPUDevice& input) {
return input.revision;
}
#endif // OS_WIN
static bool active(const gpu::GPUInfo::GPUDevice& input) {
return input.active;
}
......
......@@ -107,11 +107,19 @@ TEST_F(StructTraitsTest, GPUDevice) {
// Using the values from gpu/config/gpu_info_collector_unittest.cc::nvidia_gpu
const uint32_t vendor_id = 0x10de;
const uint32_t device_id = 0x0df8;
#if defined(OS_WIN)
const uint32_t sub_sys_id = 0xc0d8144d;
const uint32_t revision = 4u;
#endif // OS_WIN
const std::string vendor_string = "vendor_string";
const std::string device_string = "device_string";
input.vendor_id = vendor_id;
input.device_id = device_id;
#if defined(OS_WIN)
input.sub_sys_id = sub_sys_id;
input.revision = revision;
#endif // OS_WIN
input.vendor_string = vendor_string;
input.device_string = device_string;
input.active = false;
......@@ -121,6 +129,10 @@ TEST_F(StructTraitsTest, GPUDevice) {
EXPECT_EQ(vendor_id, output.vendor_id);
EXPECT_EQ(device_id, output.device_id);
#if defined(OS_WIN)
EXPECT_EQ(sub_sys_id, output.sub_sys_id);
EXPECT_EQ(revision, output.revision);
#endif // OS_WIN
EXPECT_FALSE(output.active);
EXPECT_TRUE(vendor_string.compare(output.vendor_string) == 0);
EXPECT_TRUE(device_string.compare(output.device_string) == 0);
......@@ -221,6 +233,10 @@ TEST_F(StructTraitsTest, GpuInfo) {
EXPECT_EQ(amd_switchable, output.amd_switchable);
EXPECT_EQ(gpu.vendor_id, output.gpu.vendor_id);
EXPECT_EQ(gpu.device_id, output.gpu.device_id);
#if defined(OS_WIN)
EXPECT_EQ(gpu.sub_sys_id, output.gpu.sub_sys_id);
EXPECT_EQ(gpu.revision, output.gpu.revision);
#endif // OS_WIN
EXPECT_EQ(gpu.active, output.gpu.active);
EXPECT_EQ(gpu.vendor_string, output.gpu.vendor_string);
EXPECT_EQ(gpu.device_string, output.gpu.device_string);
......@@ -230,6 +246,10 @@ TEST_F(StructTraitsTest, GpuInfo) {
const gpu::GPUInfo::GPUDevice& actual_gpu = output.secondary_gpus[i];
EXPECT_EQ(expected_gpu.vendor_id, actual_gpu.vendor_id);
EXPECT_EQ(expected_gpu.device_id, actual_gpu.device_id);
#if defined(OS_WIN)
EXPECT_EQ(expected_gpu.sub_sys_id, actual_gpu.sub_sys_id);
EXPECT_EQ(expected_gpu.revision, actual_gpu.revision);
#endif // OS_WIN
EXPECT_EQ(expected_gpu.active, actual_gpu.active);
EXPECT_EQ(expected_gpu.vendor_string, actual_gpu.vendor_string);
EXPECT_EQ(expected_gpu.device_string, actual_gpu.device_string);
......
......@@ -6370,6 +6370,10 @@ experimental domain SystemInfo
number vendorId
# PCI ID of the GPU device, if available; 0 otherwise.
number deviceId
# Sub sys ID of the GPU, only available on Windows.
optional number subSysId
# Revision of the GPU, only available on Windows.
optional number revision
# String description of the GPU vendor, if the PCI ID is not available.
string vendorString
# String description of the GPU device, if the PCI ID is not available.
......
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