xref: /aosp_15_r20/external/angle/src/gpu_info_util/SystemInfo_linux.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 #if defined(ANGLE_USE_VULKAN_SYSTEM_INFO)
77         // Try vulkan backend to get GPU info
78         return GetSystemInfoVulkan(info);
79 #else
80         return false;
81 #endif  // defined(ANGLE_HAS_VULKAN_SYSTEM_INFO)
82     }
83 
84     if (info->gpus.size() == 0)
85     {
86         return false;
87     }
88 
89     GetDualGPUInfo(info);
90 
91     for (size_t i = 0; i < info->gpus.size(); ++i)
92     {
93         GPUDeviceInfo *gpu = &info->gpus[i];
94 
95         // New GPUs might be added inside this loop, don't query for their driver version again
96         if (!gpu->driverVendor.empty())
97         {
98             continue;
99         }
100 
101         if (IsAMD(gpu->vendorId))
102         {
103             std::string version;
104             if (GetAMDBrahmaDriverVersion(&version))
105             {
106                 gpu->driverVendor  = "AMD (Brahma)";
107                 gpu->driverVersion = std::move(version);
108             }
109             else if (GetAMDCatalystDriverVersion(&version))
110             {
111                 gpu->driverVendor  = "AMD (Catalyst)";
112                 gpu->driverVersion = std::move(version);
113             }
114         }
115 
116         if (IsNVIDIA(gpu->vendorId))
117         {
118             std::string version;
119             if (GetNvidiaDriverVersionWithXNVCtrl(&version))
120             {
121                 gpu->driverVendor  = "Nvidia";
122                 gpu->driverVersion = std::move(version);
123             }
124         }
125 
126         // In dual-GPU cases the PCI scan sometimes only gives us the Intel GPU. If we are able to
127         // query for the Nvidia driver version, it means there was hidden Nvidia GPU, so we add it
128         // to the list.
129         if (IsIntel(gpu->vendorId) && info->gpus.size() == 1)
130         {
131             std::string version;
132             if (GetNvidiaDriverVersionWithXNVCtrl(&version))
133             {
134                 GPUDeviceInfo nvidiaInfo;
135                 nvidiaInfo.vendorId = kVendorID_NVIDIA;
136                 nvidiaInfo.deviceId = 0;
137                 gpu->driverVendor   = "Nvidia";
138                 gpu->driverVersion  = std::move(version);
139 
140                 info->gpus.emplace_back(std::move(nvidiaInfo));
141                 info->isOptimus = true;
142             }
143         }
144     }
145 
146     return true;
147 }
148 
149 }  // namespace angle
150