Path: blob/main_old/src/gpu_info_util/SystemInfo.cpp
1693 views
//1// Copyright 2013 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// SystemInfo.cpp: implementation of the system-agnostic parts of SystemInfo.h78#include "gpu_info_util/SystemInfo.h"910#include <cstring>11#include <iostream>12#include <sstream>1314#include "common/debug.h"15#include "common/string_utils.h"1617namespace angle18{19namespace20{21std::string VendorName(VendorID vendor)22{23switch (vendor)24{25case kVendorID_AMD:26return "AMD";27case kVendorID_ARM:28return "ARM";29case kVendorID_Broadcom:30return "Broadcom";31case kVendorID_GOOGLE:32return "Google";33case kVendorID_ImgTec:34return "ImgTec";35case kVendorID_Intel:36return "Intel";37case kVendorID_Kazan:38return "Kazan";39case kVendorID_NVIDIA:40return "NVIDIA";41case kVendorID_Qualcomm:42return "Qualcomm";43case kVendorID_VeriSilicon:44return "VeriSilicon";45case kVendorID_Vivante:46return "Vivante";47case kVendorID_VMWare:48return "VMWare";49case kVendorID_Apple:50return "Apple";51default:52return "Unknown (" + std::to_string(vendor) + ")";53}54}55} // anonymous namespace56GPUDeviceInfo::GPUDeviceInfo() = default;5758GPUDeviceInfo::~GPUDeviceInfo() = default;5960GPUDeviceInfo::GPUDeviceInfo(const GPUDeviceInfo &other) = default;6162SystemInfo::SystemInfo() = default;6364SystemInfo::~SystemInfo() = default;6566SystemInfo::SystemInfo(const SystemInfo &other) = default;6768bool SystemInfo::hasNVIDIAGPU() const69{70for (const GPUDeviceInfo &gpu : gpus)71{72if (IsNVIDIA(gpu.vendorId))73{74return true;75}76}77return false;78}7980bool SystemInfo::hasIntelGPU() const81{82for (const GPUDeviceInfo &gpu : gpus)83{84if (IsIntel(gpu.vendorId))85{86return true;87}88}89return false;90}9192bool SystemInfo::hasAMDGPU() const93{94for (const GPUDeviceInfo &gpu : gpus)95{96if (IsAMD(gpu.vendorId))97{98return true;99}100}101return false;102}103104bool IsAMD(VendorID vendorId)105{106return vendorId == kVendorID_AMD;107}108109bool IsARM(VendorID vendorId)110{111return vendorId == kVendorID_ARM;112}113114bool IsBroadcom(VendorID vendorId)115{116return vendorId == kVendorID_Broadcom;117}118119bool IsImgTec(VendorID vendorId)120{121return vendorId == kVendorID_ImgTec;122}123124bool IsKazan(VendorID vendorId)125{126return vendorId == kVendorID_Kazan;127}128129bool IsIntel(VendorID vendorId)130{131return vendorId == kVendorID_Intel;132}133134bool IsNVIDIA(VendorID vendorId)135{136return vendorId == kVendorID_NVIDIA;137}138139bool IsQualcomm(VendorID vendorId)140{141return vendorId == kVendorID_Qualcomm;142}143144bool IsGoogle(VendorID vendorId)145{146return vendorId == kVendorID_GOOGLE;147}148149bool IsVeriSilicon(VendorID vendorId)150{151return vendorId == kVendorID_VeriSilicon;152}153154bool IsVMWare(VendorID vendorId)155{156return vendorId == kVendorID_VMWare;157}158159bool IsVivante(VendorID vendorId)160{161return vendorId == kVendorID_Vivante;162}163164bool IsApple(VendorID vendorId)165{166return vendorId == kVendorID_Apple;167}168169bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version)170{171const size_t begin = content.find_first_of("0123456789");172if (begin == std::string::npos)173{174return false;175}176177const size_t end = content.find_first_not_of("0123456789.", begin);178if (end == std::string::npos)179{180*version = content.substr(begin);181}182else183{184*version = content.substr(begin, end - begin);185}186return true;187}188189bool ParseAMDCatalystDriverVersion(const std::string &content, std::string *version)190{191std::istringstream stream(content);192193std::string line;194while (std::getline(stream, line))195{196static const char kReleaseVersion[] = "ReleaseVersion=";197if (line.compare(0, std::strlen(kReleaseVersion), kReleaseVersion) != 0)198{199continue;200}201202if (ParseAMDBrahmaDriverVersion(line, version))203{204return true;205}206}207return false;208}209210bool ParseMacMachineModel(const std::string &identifier,211std::string *type,212int32_t *major,213int32_t *minor)214{215size_t numberLoc = identifier.find_first_of("0123456789");216if (numberLoc == std::string::npos)217{218return false;219}220221size_t commaLoc = identifier.find(',', numberLoc);222if (commaLoc == std::string::npos || commaLoc >= identifier.size())223{224return false;225}226227const char *numberPtr = &identifier[numberLoc];228const char *commaPtr = &identifier[commaLoc + 1];229char *endPtr = nullptr;230231int32_t majorTmp = static_cast<int32_t>(std::strtol(numberPtr, &endPtr, 10));232if (endPtr == numberPtr)233{234return false;235}236237int32_t minorTmp = static_cast<int32_t>(std::strtol(commaPtr, &endPtr, 10));238if (endPtr == commaPtr)239{240return false;241}242243*major = majorTmp;244*minor = minorTmp;245*type = identifier.substr(0, numberLoc);246247return true;248}249250bool CMDeviceIDToDeviceAndVendorID(const std::string &id, uint32_t *vendorId, uint32_t *deviceId)251{252unsigned int vendor = 0;253unsigned int device = 0;254255bool success = id.length() >= 21 && HexStringToUInt(id.substr(8, 4), &vendor) &&256HexStringToUInt(id.substr(17, 4), &device);257258*vendorId = vendor;259*deviceId = device;260return success;261}262263void GetDualGPUInfo(SystemInfo *info)264{265ASSERT(!info->gpus.empty());266267// On dual-GPU systems we assume the non-Intel GPU is the graphics one.268// TODO: this is incorrect and problematic. activeGPUIndex must be removed if it cannot be269// determined correctly. A potential solution is to create an OpenGL context and parse270// GL_VENDOR. Currently, our test infrastructure is relying on this information and incorrectly271// applies test expectations on dual-GPU systems when the Intel GPU is active.272// http://anglebug.com/6174.273int active = 0;274bool hasIntel = false;275for (size_t i = 0; i < info->gpus.size(); ++i)276{277if (IsIntel(info->gpus[i].vendorId))278{279hasIntel = true;280}281if (IsIntel(info->gpus[active].vendorId))282{283active = static_cast<int>(i);284}285}286287// Assume that a combination of NVIDIA or AMD with Intel means Optimus or AMD Switchable288info->activeGPUIndex = active;289info->isOptimus = hasIntel && IsNVIDIA(info->gpus[active].vendorId);290info->isAMDSwitchable = hasIntel && IsAMD(info->gpus[active].vendorId);291}292293void PrintSystemInfo(const SystemInfo &info)294{295std::cout << info.gpus.size() << " GPUs:\n";296297for (size_t i = 0; i < info.gpus.size(); i++)298{299const auto &gpu = info.gpus[i];300301std::cout << " " << i << " - " << VendorName(gpu.vendorId) << " device id: 0x" << std::hex302<< std::uppercase << gpu.deviceId << std::dec << "\n";303if (!gpu.driverVendor.empty())304{305std::cout << " Driver Vendor: " << gpu.driverVendor << "\n";306}307if (!gpu.driverVersion.empty())308{309std::cout << " Driver Version: " << gpu.driverVersion << "\n";310}311if (!gpu.driverDate.empty())312{313std::cout << " Driver Date: " << gpu.driverDate << "\n";314}315}316317std::cout << "\n";318std::cout << "Active GPU: " << info.activeGPUIndex << "\n";319320std::cout << "\n";321std::cout << "Optimus: " << (info.isOptimus ? "true" : "false") << "\n";322std::cout << "AMD Switchable: " << (info.isAMDSwitchable ? "true" : "false") << "\n";323324std::cout << "\n";325if (!info.machineManufacturer.empty())326{327std::cout << "Machine Manufacturer: " << info.machineManufacturer << "\n";328}329if (!info.machineModelName.empty())330{331std::cout << "Machine Model: " << info.machineModelName << "\n";332}333if (!info.machineModelVersion.empty())334{335std::cout << "Machine Model Version: " << info.machineModelVersion << "\n";336}337std::cout << std::endl;338}339340VersionInfo ParseNvidiaDriverVersion(uint32_t version)341{342return {343version >> 22, // major344version >> 14 & 0xff, // minor345version >> 6 & 0xff, // subMinor346version & 0x3f // patch347};348}349} // namespace angle350351352