Commit 1a1ae0f8 by Corentin Wallez

SystemInfo: Find primary with EnumDisplayDevices

Without DXGI, EnumDisplayDevices is the only way to get the primary device. Previously the code would work on most configs with a combination of AMD, Intel and NVIDIA GPUs but would fail on more esoteric system. Like our try bots that have Matrox GPUs. BUG=angleproject:1874 BUG=angleproject:2137 Change-Id: Ie2dfbb559001ccad2fd5b8a8fd6436e0fba9d003 Reviewed-on: https://chromium-review.googlesource.com/651629Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent ad6e2b6a
......@@ -43,8 +43,12 @@ struct SystemInfo
bool isOptimus = false;
bool isAMDSwitchable = false;
// Only available on macOS
std::string machineModelName;
std::string machineModelVersion;
// Only available on Windows, set even on failure.
std::string primaryDisplayDeviceId;
};
bool GetSystemInfo(SystemInfo *info);
......
......@@ -8,10 +8,16 @@
#include "gpu_info_util/SystemInfo_internal.h"
#include "common/debug.h"
#include "common/string_utils.h"
// Windows.h needs to be included first
#include <windows.h>
#if defined(GPU_INFO_USE_SETUPAPI)
// Remove parts of commctrl.h that have compile errors
#define NOTOOLBAR
#define NOTOOLTIPS
#include <cfgmgr32.h>
#include <setupapi.h>
#elif defined(GPU_INFO_USE_DXGI)
......@@ -30,6 +36,23 @@ namespace angle
namespace
{
// Returns the CM device ID of the primary GPU.
std::string GetPrimaryDisplayDeviceId()
{
DISPLAY_DEVICEA displayDevice;
displayDevice.cb = sizeof(DISPLAY_DEVICEA);
for (int i = 0; EnumDisplayDevicesA(nullptr, i, &displayDevice, 0); ++i)
{
if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
{
return displayDevice.DeviceID;
}
}
return "";
}
#if defined(GPU_INFO_USE_SETUPAPI)
std::string GetRegistryStringValue(HKEY key, const char *valueName)
......@@ -173,6 +196,9 @@ bool GetDevicesFromDXGI(std::vector<GPUDeviceInfo> *devices)
bool GetSystemInfo(SystemInfo *info)
{
// Get the CM device ID first so that it is returned even in error cases.
info->primaryDisplayDeviceId = GetPrimaryDisplayDeviceId();
#if defined(GPU_INFO_USE_SETUPAPI)
if (!GetDevicesFromRegistry(&info->gpus))
{
......@@ -194,6 +220,27 @@ bool GetSystemInfo(SystemInfo *info)
FindPrimaryGPU(info);
// Override the primary GPU index with what we gathered from EnumDisplayDevices
uint32_t primaryVendorId = 0;
uint32_t primaryDeviceId = 0;
if (!CMDeviceIDToDeviceAndVendorID(info->primaryDisplayDeviceId, &primaryVendorId,
&primaryDeviceId))
{
return false;
}
bool foundPrimary = false;
for (size_t i = 0; i < info->gpus.size(); ++i)
{
if (info->gpus[i].vendorId == primaryVendorId && info->gpus[i].deviceId == primaryDeviceId)
{
info->primaryGPUIndex = static_cast<int>(i);
foundPrimary = true;
}
}
ASSERT(foundPrimary);
// nvd3d9wrap.dll is loaded into all processes when Optimus is enabled.
HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll");
info->isOptimus = nvd3d9wrap != nullptr;
......
......@@ -88,6 +88,11 @@ TEST(PrintSystemInfoTest, Print)
std::cout << "Machine Model: " << info.machineModelName << " version "
<< info.machineModelVersion << "\n";
}
if (!info.primaryDisplayDeviceId.empty())
{
std::cout << "Primary Display Device: " << info.primaryDisplayDeviceId << "\n";
}
std::cout << std::endl;
#else
std::cerr << "GetSystemInfo not implemented, skipping" << std::endl;
......
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