• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_linux.cpp: implementation of the Linux-specific parts of SystemInfo.h
8 
9 #include "gpu_info_util/SystemInfo_internal.h"
10 
11 #include <cstring>
12 #include <fstream>
13 
14 #include "common/angleutils.h"
15 #include "common/debug.h"
16 
17 namespace angle
18 {
19 
20 namespace
21 {
22 
ReadWholeFile(const char * filename,std::string * content)23 bool ReadWholeFile(const char *filename, std::string *content)
24 {
25     std::ifstream file(filename);
26 
27     if (!file)
28     {
29         return false;
30     }
31 
32     *content = std::string(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
33     return true;
34 }
35 
36 // Scan /sys/module/amdgpu/version.
GetAMDBrahmaDriverVersion(std::string * version)37 bool GetAMDBrahmaDriverVersion(std::string *version)
38 {
39     *version = "";
40     std::string content;
41 
42     return ReadWholeFile("/sys/module/amdgpu/version", &content) &&
43            ParseAMDBrahmaDriverVersion(content, version);
44 }
45 
46 // Scan /etc/ati/amdpcsdb.default for "ReleaseVersion".
GetAMDCatalystDriverVersion(std::string * version)47 bool GetAMDCatalystDriverVersion(std::string *version)
48 {
49     *version = "";
50     std::string content;
51 
52     return ReadWholeFile("/etc/ati/amdpcsdb.default", &content) &&
53            ParseAMDCatalystDriverVersion(content, version);
54 }
55 
56 }  // anonymous namespace
57 
58 #if !defined(GPU_INFO_USE_X11)
GetNvidiaDriverVersionWithXNVCtrl(std::string * version)59 bool GetNvidiaDriverVersionWithXNVCtrl(std::string *version)
60 {
61     return false;
62 }
63 #endif
64 
65 #if !defined(GPU_INFO_USE_LIBPCI)
GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> * devices)66 bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices)
67 {
68     return false;
69 }
70 #endif
71 
GetSystemInfo(SystemInfo * info)72 bool GetSystemInfo(SystemInfo *info)
73 {
74     if (!GetPCIDevicesWithLibPCI(&(info->gpus)))
75     {
76         return false;
77     }
78 
79     if (info->gpus.size() == 0)
80     {
81         return false;
82     }
83 
84     GetDualGPUInfo(info);
85 
86     for (size_t i = 0; i < info->gpus.size(); ++i)
87     {
88         GPUDeviceInfo *gpu = &info->gpus[i];
89 
90         // New GPUs might be added inside this loop, don't query for their driver version again
91         if (!gpu->driverVendor.empty())
92         {
93             continue;
94         }
95 
96         if (IsAMD(gpu->vendorId))
97         {
98             std::string version;
99             if (GetAMDBrahmaDriverVersion(&version))
100             {
101                 gpu->driverVendor  = "AMD (Brahma)";
102                 gpu->driverVersion = std::move(version);
103             }
104             else if (GetAMDCatalystDriverVersion(&version))
105             {
106                 gpu->driverVendor  = "AMD (Catalyst)";
107                 gpu->driverVersion = std::move(version);
108             }
109         }
110 
111         if (IsNVIDIA(gpu->vendorId))
112         {
113             std::string version;
114             if (GetNvidiaDriverVersionWithXNVCtrl(&version))
115             {
116                 gpu->driverVendor  = "Nvidia";
117                 gpu->driverVersion = std::move(version);
118             }
119         }
120 
121         // In dual-GPU cases the PCI scan sometimes only gives us the Intel GPU. If we are able to
122         // query for the Nvidia driver version, it means there was hidden Nvidia GPU, so we add it
123         // to the list.
124         if (IsIntel(gpu->vendorId) && info->gpus.size() == 1)
125         {
126             std::string version;
127             if (GetNvidiaDriverVersionWithXNVCtrl(&version))
128             {
129                 GPUDeviceInfo nvidiaInfo;
130                 nvidiaInfo.vendorId = kVendorID_NVIDIA;
131                 nvidiaInfo.deviceId = 0;
132                 gpu->driverVendor   = "Nvidia";
133                 gpu->driverVersion  = std::move(version);
134 
135                 info->gpus.emplace_back(std::move(nvidiaInfo));
136                 info->isOptimus = true;
137             }
138         }
139     }
140 
141     return true;
142 }
143 
144 }  // namespace angle
145