Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/gpu_info_util/SystemInfo.cpp
1693 views
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.cpp: implementation of the system-agnostic parts of SystemInfo.h
8
9
#include "gpu_info_util/SystemInfo.h"
10
11
#include <cstring>
12
#include <iostream>
13
#include <sstream>
14
15
#include "common/debug.h"
16
#include "common/string_utils.h"
17
18
namespace angle
19
{
20
namespace
21
{
22
std::string VendorName(VendorID vendor)
23
{
24
switch (vendor)
25
{
26
case kVendorID_AMD:
27
return "AMD";
28
case kVendorID_ARM:
29
return "ARM";
30
case kVendorID_Broadcom:
31
return "Broadcom";
32
case kVendorID_GOOGLE:
33
return "Google";
34
case kVendorID_ImgTec:
35
return "ImgTec";
36
case kVendorID_Intel:
37
return "Intel";
38
case kVendorID_Kazan:
39
return "Kazan";
40
case kVendorID_NVIDIA:
41
return "NVIDIA";
42
case kVendorID_Qualcomm:
43
return "Qualcomm";
44
case kVendorID_VeriSilicon:
45
return "VeriSilicon";
46
case kVendorID_Vivante:
47
return "Vivante";
48
case kVendorID_VMWare:
49
return "VMWare";
50
case kVendorID_Apple:
51
return "Apple";
52
default:
53
return "Unknown (" + std::to_string(vendor) + ")";
54
}
55
}
56
} // anonymous namespace
57
GPUDeviceInfo::GPUDeviceInfo() = default;
58
59
GPUDeviceInfo::~GPUDeviceInfo() = default;
60
61
GPUDeviceInfo::GPUDeviceInfo(const GPUDeviceInfo &other) = default;
62
63
SystemInfo::SystemInfo() = default;
64
65
SystemInfo::~SystemInfo() = default;
66
67
SystemInfo::SystemInfo(const SystemInfo &other) = default;
68
69
bool SystemInfo::hasNVIDIAGPU() const
70
{
71
for (const GPUDeviceInfo &gpu : gpus)
72
{
73
if (IsNVIDIA(gpu.vendorId))
74
{
75
return true;
76
}
77
}
78
return false;
79
}
80
81
bool SystemInfo::hasIntelGPU() const
82
{
83
for (const GPUDeviceInfo &gpu : gpus)
84
{
85
if (IsIntel(gpu.vendorId))
86
{
87
return true;
88
}
89
}
90
return false;
91
}
92
93
bool SystemInfo::hasAMDGPU() const
94
{
95
for (const GPUDeviceInfo &gpu : gpus)
96
{
97
if (IsAMD(gpu.vendorId))
98
{
99
return true;
100
}
101
}
102
return false;
103
}
104
105
bool IsAMD(VendorID vendorId)
106
{
107
return vendorId == kVendorID_AMD;
108
}
109
110
bool IsARM(VendorID vendorId)
111
{
112
return vendorId == kVendorID_ARM;
113
}
114
115
bool IsBroadcom(VendorID vendorId)
116
{
117
return vendorId == kVendorID_Broadcom;
118
}
119
120
bool IsImgTec(VendorID vendorId)
121
{
122
return vendorId == kVendorID_ImgTec;
123
}
124
125
bool IsKazan(VendorID vendorId)
126
{
127
return vendorId == kVendorID_Kazan;
128
}
129
130
bool IsIntel(VendorID vendorId)
131
{
132
return vendorId == kVendorID_Intel;
133
}
134
135
bool IsNVIDIA(VendorID vendorId)
136
{
137
return vendorId == kVendorID_NVIDIA;
138
}
139
140
bool IsQualcomm(VendorID vendorId)
141
{
142
return vendorId == kVendorID_Qualcomm;
143
}
144
145
bool IsGoogle(VendorID vendorId)
146
{
147
return vendorId == kVendorID_GOOGLE;
148
}
149
150
bool IsVeriSilicon(VendorID vendorId)
151
{
152
return vendorId == kVendorID_VeriSilicon;
153
}
154
155
bool IsVMWare(VendorID vendorId)
156
{
157
return vendorId == kVendorID_VMWare;
158
}
159
160
bool IsVivante(VendorID vendorId)
161
{
162
return vendorId == kVendorID_Vivante;
163
}
164
165
bool IsApple(VendorID vendorId)
166
{
167
return vendorId == kVendorID_Apple;
168
}
169
170
bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version)
171
{
172
const size_t begin = content.find_first_of("0123456789");
173
if (begin == std::string::npos)
174
{
175
return false;
176
}
177
178
const size_t end = content.find_first_not_of("0123456789.", begin);
179
if (end == std::string::npos)
180
{
181
*version = content.substr(begin);
182
}
183
else
184
{
185
*version = content.substr(begin, end - begin);
186
}
187
return true;
188
}
189
190
bool ParseAMDCatalystDriverVersion(const std::string &content, std::string *version)
191
{
192
std::istringstream stream(content);
193
194
std::string line;
195
while (std::getline(stream, line))
196
{
197
static const char kReleaseVersion[] = "ReleaseVersion=";
198
if (line.compare(0, std::strlen(kReleaseVersion), kReleaseVersion) != 0)
199
{
200
continue;
201
}
202
203
if (ParseAMDBrahmaDriverVersion(line, version))
204
{
205
return true;
206
}
207
}
208
return false;
209
}
210
211
bool ParseMacMachineModel(const std::string &identifier,
212
std::string *type,
213
int32_t *major,
214
int32_t *minor)
215
{
216
size_t numberLoc = identifier.find_first_of("0123456789");
217
if (numberLoc == std::string::npos)
218
{
219
return false;
220
}
221
222
size_t commaLoc = identifier.find(',', numberLoc);
223
if (commaLoc == std::string::npos || commaLoc >= identifier.size())
224
{
225
return false;
226
}
227
228
const char *numberPtr = &identifier[numberLoc];
229
const char *commaPtr = &identifier[commaLoc + 1];
230
char *endPtr = nullptr;
231
232
int32_t majorTmp = static_cast<int32_t>(std::strtol(numberPtr, &endPtr, 10));
233
if (endPtr == numberPtr)
234
{
235
return false;
236
}
237
238
int32_t minorTmp = static_cast<int32_t>(std::strtol(commaPtr, &endPtr, 10));
239
if (endPtr == commaPtr)
240
{
241
return false;
242
}
243
244
*major = majorTmp;
245
*minor = minorTmp;
246
*type = identifier.substr(0, numberLoc);
247
248
return true;
249
}
250
251
bool CMDeviceIDToDeviceAndVendorID(const std::string &id, uint32_t *vendorId, uint32_t *deviceId)
252
{
253
unsigned int vendor = 0;
254
unsigned int device = 0;
255
256
bool success = id.length() >= 21 && HexStringToUInt(id.substr(8, 4), &vendor) &&
257
HexStringToUInt(id.substr(17, 4), &device);
258
259
*vendorId = vendor;
260
*deviceId = device;
261
return success;
262
}
263
264
void GetDualGPUInfo(SystemInfo *info)
265
{
266
ASSERT(!info->gpus.empty());
267
268
// On dual-GPU systems we assume the non-Intel GPU is the graphics one.
269
// TODO: this is incorrect and problematic. activeGPUIndex must be removed if it cannot be
270
// determined correctly. A potential solution is to create an OpenGL context and parse
271
// GL_VENDOR. Currently, our test infrastructure is relying on this information and incorrectly
272
// applies test expectations on dual-GPU systems when the Intel GPU is active.
273
// http://anglebug.com/6174.
274
int active = 0;
275
bool hasIntel = false;
276
for (size_t i = 0; i < info->gpus.size(); ++i)
277
{
278
if (IsIntel(info->gpus[i].vendorId))
279
{
280
hasIntel = true;
281
}
282
if (IsIntel(info->gpus[active].vendorId))
283
{
284
active = static_cast<int>(i);
285
}
286
}
287
288
// Assume that a combination of NVIDIA or AMD with Intel means Optimus or AMD Switchable
289
info->activeGPUIndex = active;
290
info->isOptimus = hasIntel && IsNVIDIA(info->gpus[active].vendorId);
291
info->isAMDSwitchable = hasIntel && IsAMD(info->gpus[active].vendorId);
292
}
293
294
void PrintSystemInfo(const SystemInfo &info)
295
{
296
std::cout << info.gpus.size() << " GPUs:\n";
297
298
for (size_t i = 0; i < info.gpus.size(); i++)
299
{
300
const auto &gpu = info.gpus[i];
301
302
std::cout << " " << i << " - " << VendorName(gpu.vendorId) << " device id: 0x" << std::hex
303
<< std::uppercase << gpu.deviceId << std::dec << "\n";
304
if (!gpu.driverVendor.empty())
305
{
306
std::cout << " Driver Vendor: " << gpu.driverVendor << "\n";
307
}
308
if (!gpu.driverVersion.empty())
309
{
310
std::cout << " Driver Version: " << gpu.driverVersion << "\n";
311
}
312
if (!gpu.driverDate.empty())
313
{
314
std::cout << " Driver Date: " << gpu.driverDate << "\n";
315
}
316
}
317
318
std::cout << "\n";
319
std::cout << "Active GPU: " << info.activeGPUIndex << "\n";
320
321
std::cout << "\n";
322
std::cout << "Optimus: " << (info.isOptimus ? "true" : "false") << "\n";
323
std::cout << "AMD Switchable: " << (info.isAMDSwitchable ? "true" : "false") << "\n";
324
325
std::cout << "\n";
326
if (!info.machineManufacturer.empty())
327
{
328
std::cout << "Machine Manufacturer: " << info.machineManufacturer << "\n";
329
}
330
if (!info.machineModelName.empty())
331
{
332
std::cout << "Machine Model: " << info.machineModelName << "\n";
333
}
334
if (!info.machineModelVersion.empty())
335
{
336
std::cout << "Machine Model Version: " << info.machineModelVersion << "\n";
337
}
338
std::cout << std::endl;
339
}
340
341
VersionInfo ParseNvidiaDriverVersion(uint32_t version)
342
{
343
return {
344
version >> 22, // major
345
version >> 14 & 0xff, // minor
346
version >> 6 & 0xff, // subMinor
347
version & 0x3f // patch
348
};
349
}
350
} // namespace angle
351
352