Edit

kc3-lang/angle/src/gpu_info_util/SystemInfo_win.cpp

Branch :

  • Show log

    Commit

  • Author : Jonah Ryan-Davis
    Date : 2019-04-25 10:49:05
    Hash : 66e4850d
    Message : Use EnumAdapters to properly detect primary GPU on Win EnumDisplayDevicesA returns the card that's connected to the display, but EnumAdapters return the adapter which the desktop primary is displayed at index 0. We can use this to determine the device used for graphics. Also cleans up the discrepancy between platforms on finding "primary" vs "active" GPU. Asserts that the GPU expected to run ANGLE commands is the active GPU, and deprecates the primary GPU to be equal to the active GPU. Bug: angleproject:3383 Change-Id: I422fba1bbe47d85b7c09e378d559eaebf89e2625 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1584360 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Geoff Lang <geofflang@chromium.org>

  • src/gpu_info_util/SystemInfo_win.cpp
  • //
    // Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // SystemInfo_win.cpp: implementation of the Windows-specific parts of SystemInfo.h
    
    #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>
    
    #include <d3d10.h>
    #include <dxgi.h>
    
    #include <array>
    #include <sstream>
    
    namespace angle
    {
    
    namespace
    {
    
    bool GetDevicesFromDXGI(std::vector<GPUDeviceInfo> *devices)
    {
        IDXGIFactory *factory;
        if (!SUCCEEDED(CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void **>(&factory))))
        {
            return false;
        }
    
        UINT i                = 0;
        IDXGIAdapter *adapter = nullptr;
        while (factory->EnumAdapters(i++, &adapter) != DXGI_ERROR_NOT_FOUND)
        {
            DXGI_ADAPTER_DESC desc;
            adapter->GetDesc(&desc);
    
            LARGE_INTEGER umdVersion;
            if (adapter->CheckInterfaceSupport(__uuidof(ID3D10Device), &umdVersion) ==
                DXGI_ERROR_UNSUPPORTED)
            {
                adapter->Release();
                continue;
            }
    
            // The UMD driver version here is the same as in the registry except for the last number.
            uint64_t intVersion = umdVersion.QuadPart;
            std::ostringstream o;
    
            const uint64_t kMask = 0xFF;
            o << ((intVersion >> 48) & kMask) << ".";
            o << ((intVersion >> 32) & kMask) << ".";
            o << ((intVersion >> 16) & kMask) << ".";
            o << (intVersion & kMask);
    
            GPUDeviceInfo device;
            device.vendorId      = desc.VendorId;
            device.deviceId      = desc.DeviceId;
            device.driverVersion = o.str();
    
            devices->push_back(device);
    
            adapter->Release();
        }
    
        factory->Release();
    
        return (i > 0);
    }
    
    }  // anonymous namespace
    
    bool GetSystemInfo(SystemInfo *info)
    {
        if (!GetDevicesFromDXGI(&info->gpus))
        {
            return false;
        }
    
        if (info->gpus.size() == 0)
        {
            return false;
        }
    
        // Call FindActiveGPU to populate activeGPUIndex, isOptimus, and isAMDSwitchable.
        FindActiveGPU(info);
    
        // Override activeGPUIndex. The first index returned by EnumAdapters is the active GPU. We
        // can override the heuristic to find the active GPU
        info->activeGPUIndex = 0;
        // Deprecated: set primaryGPUIndex to the same index.
        info->primaryGPUIndex = 0;
    
        // Override isOptimus. nvd3d9wrap.dll is loaded into all processes when Optimus is enabled.
        HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll");
        info->isOptimus    = nvd3d9wrap != nullptr;
    
        return true;
    }
    
    }  // namespace angle