diff options
Diffstat (limited to 'src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp')
-rw-r--r-- | src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp new file mode 100644 index 0000000000..98f000b069 --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp @@ -0,0 +1,144 @@ +// +// 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_linux.cpp: implementation of the Linux-specific parts of SystemInfo.h + +#include "gpu_info_util/SystemInfo_internal.h" + +#include <cstring> +#include <fstream> + +#include "common/angleutils.h" +#include "common/debug.h" + +namespace angle +{ + +namespace +{ + +bool ReadWholeFile(const char *filename, std::string *content) +{ + std::ifstream file(filename); + + if (!file) + { + return false; + } + + *content = std::string(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()); + return true; +} + +// Scan /sys/module/amdgpu/version. +bool GetAMDBrahmaDriverVersion(std::string *version) +{ + *version = ""; + std::string content; + + return ReadWholeFile("/sys/module/amdgpu/version", &content) && + ParseAMDBrahmaDriverVersion(content, version); +} + +// Scan /etc/ati/amdpcsdb.default for "ReleaseVersion". +bool GetAMDCatalystDriverVersion(std::string *version) +{ + *version = ""; + std::string content; + + return ReadWholeFile("/etc/ati/amdpcsdb.default", &content) && + ParseAMDCatalystDriverVersion(content, version); +} + +} // anonymous namespace + +#if !defined(GPU_INFO_USE_X11) +bool GetNvidiaDriverVersionWithXNVCtrl(std::string *version) +{ + return false; +} +#endif + +#if !defined(GPU_INFO_USE_LIBPCI) +bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices) +{ + return false; +} +#endif + +bool GetSystemInfo(SystemInfo *info) +{ + if (!GetPCIDevicesWithLibPCI(&(info->gpus))) + { + return false; + } + + if (info->gpus.size() == 0) + { + return false; + } + + FindPrimaryGPU(info); + + for (size_t i = 0; i < info->gpus.size(); ++i) + { + GPUDeviceInfo *gpu = &info->gpus[i]; + + // New GPUs might be added inside this loop, don't query for their driver version again + if (!gpu->driverVendor.empty()) + { + continue; + } + + if (IsAMD(gpu->vendorId)) + { + std::string version; + if (GetAMDBrahmaDriverVersion(&version)) + { + gpu->driverVendor = "AMD (Brahma)"; + gpu->driverVersion = std::move(version); + } + else if (GetAMDCatalystDriverVersion(&version)) + { + gpu->driverVendor = "AMD (Catalyst)"; + gpu->driverVersion = std::move(version); + } + } + + if (IsNvidia(gpu->vendorId)) + { + std::string version; + if (GetNvidiaDriverVersionWithXNVCtrl(&version)) + { + gpu->driverVendor = "Nvidia"; + gpu->driverVersion = std::move(version); + } + } + + // In dual-GPU cases the PCI scan sometimes only gives us the Intel GPU. + // If we are able to query for the Nvidia driver version, it means there + // was hidden Nvidia GPU, so we add it to the list and make it primary. + if (IsIntel(gpu->vendorId) && info->gpus.size() == 1) + { + std::string version; + if (GetNvidiaDriverVersionWithXNVCtrl(&version)) + { + GPUDeviceInfo nvidiaInfo; + nvidiaInfo.vendorId = kVendorID_Nvidia; + nvidiaInfo.deviceId = 0; + gpu->driverVendor = "Nvidia"; + gpu->driverVersion = std::move(version); + + info->gpus.emplace_back(std::move(nvidiaInfo)); + info->isOptimus = true; + } + } + } + + return true; +} + +} // namespace angle |