1 // 2 // Copyright 2013 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // SystemInfo_win.cpp: implementation of the Windows-specific parts of SystemInfo.h 8 9 #include "gpu_info_util/SystemInfo_internal.h" 10 11 #include "common/debug.h" 12 #include "common/string_utils.h" 13 14 // Windows.h needs to be included first 15 #include <windows.h> 16 17 #include <dxgi.h> 18 19 #include <array> 20 #include <sstream> 21 22 namespace angle 23 { 24 25 namespace 26 { 27 GetDevicesFromDXGI(std::vector<GPUDeviceInfo> * devices)28bool GetDevicesFromDXGI(std::vector<GPUDeviceInfo> *devices) 29 { 30 #if defined(ANGLE_ENABLE_WINDOWS_UWP) 31 IDXGIFactory1 *factory; 32 if (!SUCCEEDED( 33 CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void **>(&factory)))) 34 { 35 return false; 36 } 37 #else 38 IDXGIFactory *factory; 39 if (!SUCCEEDED(CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void **>(&factory)))) 40 { 41 return false; 42 } 43 #endif 44 45 UINT i = 0; 46 IDXGIAdapter *adapter = nullptr; 47 while (factory->EnumAdapters(i++, &adapter) != DXGI_ERROR_NOT_FOUND) 48 { 49 DXGI_ADAPTER_DESC desc; 50 adapter->GetDesc(&desc); 51 52 LARGE_INTEGER umdVersion; 53 if (adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &umdVersion) == 54 DXGI_ERROR_UNSUPPORTED) 55 { 56 adapter->Release(); 57 continue; 58 } 59 60 // The UMD driver version here is the same as in the registry except for the last number. 61 uint64_t intVersion = umdVersion.QuadPart; 62 std::ostringstream o; 63 64 constexpr uint64_t kMask16 = std::numeric_limits<uint16_t>::max(); 65 o << ((intVersion >> 48) & kMask16) << "."; 66 o << ((intVersion >> 32) & kMask16) << "."; 67 o << ((intVersion >> 16) & kMask16) << "."; 68 o << (intVersion & kMask16); 69 70 GPUDeviceInfo device; 71 device.vendorId = desc.VendorId; 72 device.deviceId = desc.DeviceId; 73 device.driverVersion = o.str(); 74 75 devices->push_back(device); 76 77 adapter->Release(); 78 } 79 80 factory->Release(); 81 82 return (i > 0); 83 } 84 85 } // anonymous namespace 86 GetSystemInfo(SystemInfo * info)87bool GetSystemInfo(SystemInfo *info) 88 { 89 if (!GetDevicesFromDXGI(&info->gpus)) 90 { 91 return false; 92 } 93 94 if (info->gpus.size() == 0) 95 { 96 return false; 97 } 98 99 // Call GetDualGPUInfo to populate activeGPUIndex, isOptimus, and isAMDSwitchable. 100 GetDualGPUInfo(info); 101 102 // Override activeGPUIndex. The first index returned by EnumAdapters is the active GPU. We 103 // can override the heuristic to find the active GPU 104 info->activeGPUIndex = 0; 105 106 #if !defined(ANGLE_ENABLE_WINDOWS_UWP) 107 // Override isOptimus. nvd3d9wrap.dll is loaded into all processes when Optimus is enabled. 108 HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll"); 109 info->isOptimus = nvd3d9wrap != nullptr; 110 #endif 111 112 return true; 113 } 114 115 } // namespace angle 116