Commit f34c193d authored by Patrick To's avatar Patrick To Committed by Commit Bot

Add LUID to GPUInfo and about:gpu in Windows

When initializing the GPUInfo of each GPU on the computer, also include
the LUID. A LUID is needed to uniquely identify a GPU adapter. The
vendor ID and device ID is not sufficient because device IDs are unique
only relative to the vendor ID, not to each other. If a computer has
two of the same exact GPU, they will have the same vendor ID and
device ID, but different LUIDs.

This change is one part of a series of changes to add multi-GPU support
for VR. This code was originally reviewed as part of a larger CL here:
https://chromium-review.googlesource.com/c/chromium/src/+/2096778

However, that change is being split into smaller pieces to facilitate
code review and landing. The other parts of the split will be put up
within a few days.

Bug: 792657
Change-Id: I4821e2d1317caf335add61b16a9adc7e0d08a41b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2216166Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarRafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Commit-Queue: Patrick To <patrto@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#773118}
parent ef9c48b6
...@@ -136,6 +136,9 @@ std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) { ...@@ -136,6 +136,9 @@ std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) {
rt += base::StringPrintf(", SUBSYS=0x%08x, REV=%u", gpu.sub_sys_id, rt += base::StringPrintf(", SUBSYS=0x%08x, REV=%u", gpu.sub_sys_id,
gpu.revision); gpu.revision);
} }
rt += base::StringPrintf(", LUID={%ld,%lu}", gpu.luid.HighPart,
gpu.luid.LowPart);
#endif #endif
if (gpu.active) if (gpu.active)
rt += " *ACTIVE*"; rt += " *ACTIVE*";
......
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
#include "gpu/vulkan/buildflags.h" #include "gpu/vulkan/buildflags.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#if defined(OS_WIN)
#include <dxgi.h>
#endif
#if BUILDFLAG(ENABLE_VULKAN) #if BUILDFLAG(ENABLE_VULKAN)
#include "gpu/config/vulkan_info.h" #include "gpu/config/vulkan_info.h"
#endif #endif
...@@ -251,10 +255,19 @@ struct GPU_EXPORT GPUInfo { ...@@ -251,10 +255,19 @@ struct GPU_EXPORT GPUInfo {
// The graphics card revision number. // The graphics card revision number.
uint32_t revision = 0u; uint32_t revision = 0u;
// The graphics card LUID. This is a unique identifier for the graphics card
// that is guaranteed to be unique until the computer is restarted. The LUID
// is used over the vendor id and device id because the device id is only
// unique relative its vendor, not to each other. If there are more than one
// of the same exact graphics card, they all have the same vendor id and
// device id but different LUIDs.
LUID luid;
#endif // OS_WIN #endif // OS_WIN
// Whether this GPU is the currently used one. // Whether this GPU is the currently used one.
// Currently this field is only supported and meaningful on OS X. // Currently this field is only supported and meaningful on OS X and on
// Windows using Angle with D3D11.
bool active = false; bool active = false;
// The strings that describe the GPU. // The strings that describe the GPU.
......
...@@ -344,7 +344,14 @@ bool CollectGraphicsInfoGL(GPUInfo* gpu_info) { ...@@ -344,7 +344,14 @@ bool CollectGraphicsInfoGL(GPUInfo* gpu_info) {
gpu_info->pixel_shader_version = glsl_version; gpu_info->pixel_shader_version = glsl_version;
gpu_info->vertex_shader_version = glsl_version; gpu_info->vertex_shader_version = glsl_version;
IdentifyActiveGPU(gpu_info); bool active_gpu_identified = false;
#if defined(OS_WIN)
active_gpu_identified = IdentifyActiveGPUWithLuid(gpu_info);
#endif // OS_WIN
if (!active_gpu_identified)
IdentifyActiveGPU(gpu_info);
return true; return true;
} }
......
...@@ -59,6 +59,9 @@ GPU_EXPORT bool CollectD3D11FeatureInfo(D3D_FEATURE_LEVEL* d3d11_feature_level, ...@@ -59,6 +59,9 @@ GPU_EXPORT bool CollectD3D11FeatureInfo(D3D_FEATURE_LEVEL* d3d11_feature_level,
// Collect the hardware overlay support flags. // Collect the hardware overlay support flags.
GPU_EXPORT void CollectHardwareOverlayInfo(OverlayInfo* overlay_info); GPU_EXPORT void CollectHardwareOverlayInfo(OverlayInfo* overlay_info);
// Identify the active GPU based on LUIDs.
bool IdentifyActiveGPUWithLuid(GPUInfo* gpu_info);
#endif // OS_WIN #endif // OS_WIN
// Create a GL context and collect GL strings and versions. // Create a GL context and collect GL strings and versions.
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "gpu/config/gpu_util.h" #include "gpu/config/gpu_util.h"
#include "third_party/vulkan_headers/include/vulkan/vulkan.h" #include "third_party/vulkan_headers/include/vulkan/vulkan.h"
#include "ui/gl/direct_composition_surface_win.h" #include "ui/gl/direct_composition_surface_win.h"
#include "ui/gl/gl_angle_util_win.h"
#include "ui/gl/gl_surface_egl.h"
namespace gpu { namespace gpu {
...@@ -83,6 +85,32 @@ OverlaySupport FlagsToOverlaySupport(bool overlays_supported, UINT flags) { ...@@ -83,6 +85,32 @@ OverlaySupport FlagsToOverlaySupport(bool overlays_supported, UINT flags) {
return OverlaySupport::kNone; return OverlaySupport::kNone;
} }
bool GetActiveAdapterLuid(LUID* luid) {
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
gl::QueryD3D11DeviceObjectFromANGLE();
if (!d3d11_device)
return false;
Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device;
if (FAILED(d3d11_device.As(&dxgi_device)))
return false;
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
if (FAILED(dxgi_device->GetAdapter(&adapter)))
return false;
DXGI_ADAPTER_DESC desc;
if (FAILED(adapter->GetDesc(&desc)))
return false;
// Zero isn't a valid LUID.
if (desc.AdapterLuid.HighPart == 0 && desc.AdapterLuid.LowPart == 0)
return false;
*luid = desc.AdapterLuid;
return true;
}
} // namespace } // namespace
#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OFFICIAL_BUILD) #if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OFFICIAL_BUILD)
...@@ -144,6 +172,7 @@ bool CollectDriverInfoD3D(GPUInfo* gpu_info) { ...@@ -144,6 +172,7 @@ bool CollectDriverInfoD3D(GPUInfo* gpu_info) {
device.device_id = desc.DeviceId; device.device_id = desc.DeviceId;
device.sub_sys_id = desc.SubSysId; device.sub_sys_id = desc.SubSysId;
device.revision = desc.Revision; device.revision = desc.Revision;
device.luid = desc.AdapterLuid;
LARGE_INTEGER umd_version; LARGE_INTEGER umd_version;
hr = dxgi_adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), hr = dxgi_adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice),
...@@ -614,4 +643,30 @@ bool CollectBasicGraphicsInfo(GPUInfo* gpu_info) { ...@@ -614,4 +643,30 @@ bool CollectBasicGraphicsInfo(GPUInfo* gpu_info) {
return CollectDriverInfoD3D(gpu_info); return CollectDriverInfoD3D(gpu_info);
} }
bool IdentifyActiveGPUWithLuid(GPUInfo* gpu_info) {
LUID luid;
if (!GetActiveAdapterLuid(&luid))
return false;
gpu_info->gpu.active = false;
for (size_t i = 0; i < gpu_info->secondary_gpus.size(); i++)
gpu_info->secondary_gpus[i].active = false;
if (gpu_info->gpu.luid.HighPart == luid.HighPart &&
gpu_info->gpu.luid.LowPart == luid.LowPart) {
gpu_info->gpu.active = true;
return true;
}
for (size_t i = 0; i < gpu_info->secondary_gpus.size(); i++) {
if (gpu_info->secondary_gpus[i].luid.HighPart == luid.HighPart &&
gpu_info->secondary_gpus[i].luid.LowPart == luid.LowPart) {
gpu_info->secondary_gpus[i].active = true;
return true;
}
}
return false;
}
} // namespace gpu } // namespace gpu
...@@ -399,6 +399,10 @@ mojom("interfaces") { ...@@ -399,6 +399,10 @@ mojom("interfaces") {
mojom = "gpu.mojom.ImageDecodeAcceleratorSupportedProfile" mojom = "gpu.mojom.ImageDecodeAcceleratorSupportedProfile"
cpp = "::gpu::ImageDecodeAcceleratorSupportedProfile" cpp = "::gpu::ImageDecodeAcceleratorSupportedProfile"
}, },
{
mojom = "gpu.mojom.Luid"
cpp = "::LUID"
},
] ]
traits_sources = [ "gpu_info_mojom_traits.cc" ] traits_sources = [ "gpu_info_mojom_traits.cc" ]
traits_headers = [ "gpu_info_mojom_traits.h" ] traits_headers = [ "gpu_info_mojom_traits.h" ]
......
...@@ -12,6 +12,13 @@ import "ui/gfx/geometry/mojom/geometry.mojom"; ...@@ -12,6 +12,13 @@ import "ui/gfx/geometry/mojom/geometry.mojom";
[EnableIf=supports_vulkan] [EnableIf=supports_vulkan]
import "gpu/ipc/common/vulkan_info.mojom"; import "gpu/ipc/common/vulkan_info.mojom";
// Corresponds to LUID in dxgi.h
[EnableIf=is_win]
struct Luid {
int32 high;
uint32 low;
};
// gpu::GPUInfo::GPUDevice // gpu::GPUInfo::GPUDevice
struct GpuDevice { struct GpuDevice {
uint32 vendor_id; uint32 vendor_id;
...@@ -26,6 +33,8 @@ struct GpuDevice { ...@@ -26,6 +33,8 @@ struct GpuDevice {
string driver_vendor; string driver_vendor;
string driver_version; string driver_version;
int32 cuda_compute_capability_major; int32 cuda_compute_capability_major;
[EnableIf=is_win]
Luid luid;
}; };
// gpu::VideoCodecProfile // gpu::VideoCodecProfile
......
...@@ -28,6 +28,9 @@ bool StructTraits<gpu::mojom::GpuDeviceDataView, gpu::GPUInfo::GPUDevice>::Read( ...@@ -28,6 +28,9 @@ bool StructTraits<gpu::mojom::GpuDeviceDataView, gpu::GPUInfo::GPUDevice>::Read(
out->cuda_compute_capability_major = data.cuda_compute_capability_major(); out->cuda_compute_capability_major = data.cuda_compute_capability_major();
return data.ReadVendorString(&out->vendor_string) && return data.ReadVendorString(&out->vendor_string) &&
data.ReadDeviceString(&out->device_string) && data.ReadDeviceString(&out->device_string) &&
#if defined(OS_WIN)
data.ReadLuid(&out->luid) &&
#endif // OS_WIN
data.ReadDriverVendor(&out->driver_vendor) && data.ReadDriverVendor(&out->driver_vendor) &&
data.ReadDriverVersion(&out->driver_version); data.ReadDriverVersion(&out->driver_version);
} }
...@@ -375,6 +378,15 @@ bool StructTraits<gpu::mojom::OverlayInfoDataView, gpu::OverlayInfo>::Read( ...@@ -375,6 +378,15 @@ bool StructTraits<gpu::mojom::OverlayInfoDataView, gpu::OverlayInfo>::Read(
return data.ReadYuy2OverlaySupport(&out->yuy2_overlay_support) && return data.ReadYuy2OverlaySupport(&out->yuy2_overlay_support) &&
data.ReadNv12OverlaySupport(&out->nv12_overlay_support); data.ReadNv12OverlaySupport(&out->nv12_overlay_support);
} }
// static
bool StructTraits<gpu::mojom::LuidDataView, LUID>::Read(
gpu::mojom::LuidDataView data,
LUID* out) {
out->HighPart = data.high();
out->LowPart = data.low();
return true;
}
#endif #endif
bool StructTraits<gpu::mojom::GpuInfoDataView, gpu::GPUInfo>::Read( bool StructTraits<gpu::mojom::GpuInfoDataView, gpu::GPUInfo>::Read(
......
...@@ -36,6 +36,10 @@ struct StructTraits<gpu::mojom::GpuDeviceDataView, gpu::GPUInfo::GPUDevice> { ...@@ -36,6 +36,10 @@ struct StructTraits<gpu::mojom::GpuDeviceDataView, gpu::GPUInfo::GPUDevice> {
static uint32_t revision(const gpu::GPUInfo::GPUDevice& input) { static uint32_t revision(const gpu::GPUInfo::GPUDevice& input) {
return input.revision; return input.revision;
} }
static const LUID luid(const gpu::GPUInfo::GPUDevice& input) {
return input.luid;
}
#endif // OS_WIN #endif // OS_WIN
static bool active(const gpu::GPUInfo::GPUDevice& input) { static bool active(const gpu::GPUInfo::GPUDevice& input) {
...@@ -253,6 +257,15 @@ struct StructTraits<gpu::mojom::OverlayInfoDataView, gpu::OverlayInfo> { ...@@ -253,6 +257,15 @@ struct StructTraits<gpu::mojom::OverlayInfoDataView, gpu::OverlayInfo> {
} }
}; };
template <>
struct StructTraits<gpu::mojom::LuidDataView, LUID> {
static bool Read(gpu::mojom::LuidDataView data, LUID* out);
static int32_t high(const LUID& input) { return input.HighPart; }
static uint32_t low(const LUID& input) { return input.LowPart; }
};
#endif #endif
template <> template <>
......
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