xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/driver_utils.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2016 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 // driver_utils.h : provides more information about current driver.
8 
9 #include <algorithm>
10 
11 #include "libANGLE/renderer/driver_utils.h"
12 
13 #include "common/android_util.h"
14 #include "common/platform.h"
15 #include "common/system_utils.h"
16 
17 #if defined(ANGLE_PLATFORM_LINUX)
18 #    include <sys/utsname.h>
19 #endif
20 
21 namespace rx
22 {
23 // Intel
24 // Referenced from
25 // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/include/pci_ids/crocus_pci_ids.h
26 // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/include/pci_ids/iris_pci_ids.h
27 namespace
28 {
29 // gen6
30 const uint16_t SandyBridge[] = {
31     0x0102, 0x0106, 0x010A,         // snb_gt1
32     0x0112, 0x0122, 0x0116, 0x0126  // snb_gt2
33 };
34 
35 // gen7
36 const uint16_t IvyBridge[] = {
37     0x0152, 0x0156, 0x015A,  // ivb_gt1
38     0x0162, 0x0166, 0x016A   // ivb_gt2
39 };
40 
41 // gen 7.5
42 const uint16_t Haswell[] = {
43     0x0402, 0x0406, 0x040A, 0x040B, 0x040E, 0x0C02, 0x0C06, 0x0C0A, 0x0C0B, 0x0C0E,
44     0x0A02, 0x0A06, 0x0A0A, 0x0A0B, 0x0A0E, 0x0D02, 0x0D06, 0x0D0A, 0x0D0B, 0x0D0E,  // hsw_gt1
45     0x0412, 0x0416, 0x041A, 0x041B, 0x041E, 0x0C12, 0x0C16, 0x0C1A, 0x0C1B, 0x0C1E,
46     0x0A12, 0x0A16, 0x0A1A, 0x0A1B, 0x0A1E, 0x0D12, 0x0D16, 0x0D1A, 0x0D1B, 0x0D1E,  // hsw_gt2
47     0x0422, 0x0426, 0x042A, 0x042B, 0x042E, 0x0C22, 0x0C26, 0x0C2A, 0x0C2B, 0x0C2E,
48     0x0A22, 0x0A26, 0x0A2A, 0x0A2B, 0x0A2E, 0x0D22, 0x0D26, 0x0D2A, 0x0D2B, 0x0D2E  // hsw_gt3
49 };
50 
51 // gen8
52 const uint16_t Broadwell[] = {
53     0x1602, 0x1606, 0x160A, 0x160B, 0x160D, 0x160E,  // bdw_gt1
54     0x1612, 0x1616, 0x161A, 0x161B, 0x161D, 0x161E,  // bdw_gt2
55     0x1622, 0x1626, 0x162A, 0x162B, 0x162D, 0x162E   // bdw_gt3
56 };
57 
58 const uint16_t CherryView[] = {0x22B0, 0x22B1, 0x22B2, 0x22B3};
59 
60 // gen9
61 const uint16_t Skylake[] = {
62     0x1902, 0x1906, 0x190A, 0x190B, 0x190E,                                          // skl_gt1
63     0x1912, 0x1913, 0x1915, 0x1916, 0x1917, 0x191A, 0x191B, 0x191D, 0x191E, 0x1921,  // skl_gt2
64     0x1923, 0x1926, 0x1927, 0x192B, 0x192D,                                          // skl_gt3
65     0x192A, 0x1932, 0x193A, 0x193B, 0x193D                                           // skl_gt4
66 };
67 
68 // gen9lp
69 const uint16_t Broxton[] = {0x0A84, 0x1A84, 0x1A85, 0x5A84, 0x5A85};
70 
71 const uint16_t GeminiLake[] = {0x3184, 0x3185};
72 
73 // gen9p5
74 const uint16_t KabyLake[] = {
75     // Kaby Lake
76     0x5902, 0x5906, 0x5908, 0x590A, 0x590B, 0x590E,                  // kbl_gt1
77     0x5913, 0x5915,                                                  // kbl_gt1_5
78     0x5912, 0x5916, 0x5917, 0x591A, 0x591B, 0x591D, 0x591E, 0x5921,  // kbl_gt2
79     0x5923, 0x5926, 0x5927,                                          // kbl_gt3
80     0x593B,                                                          // kbl_gt4
81     // Amber Lake
82     0x591C, 0x87C0  // kbl_gt2
83 };
84 
85 const uint16_t CoffeeLake[] = {
86     // Amber Lake
87     0x87CA,  // cfl_gt2
88 
89     // Coffee Lake
90     0x3E90, 0x3E93, 0x3E99, 0x3E9C,                                  // cfl_gt1
91     0x3E91, 0x3E92, 0x3E94, 0x3E96, 0x3E98, 0x3E9A, 0x3E9B, 0x3EA9,  // cfl_gt2
92     0x3EA5, 0x3EA6, 0x3EA7, 0x3EA8,                                  // cfl_gt3
93 
94     // Whisky Lake
95     0x3EA1, 0x3EA4,  // cfl_gt1
96     0x3EA0, 0x3EA3,  // cfl_gt2
97     0x3EA2,          // cfl_gt3
98 
99     // Comet Lake
100     0x9B21, 0x9BA0, 0x9BA2, 0x9BA4, 0x9BA5, 0x9BA8, 0x9BAA, 0x9BAB, 0x9BAC,          // cfl_gt1
101     0x9B41, 0x9BC0, 0x9BC2, 0x9BC4, 0x9BC5, 0x9BC6, 0x9BC8, 0x9BCA, 0x9BCB, 0x9BCC,  // cfl_gt2
102     0x9BE6, 0x9BF6                                                                   // cfl_gt2
103 };
104 
105 const uint16_t MeteorLake[] = {0x7d40, 0x7d45, 0x7d55, 0x7d60, 0x7dd5};
106 
107 const uint16_t IntelGen11[] = {
108     // Ice Lake
109     0x8A71,                                  // icl_gt0_5
110     0x8A56, 0x8A58, 0x8A5B, 0x8A5D,          // icl_gt1
111     0x8A54, 0x8A57, 0x8A59, 0x8A5A, 0x8A5C,  // icl_gt1_5
112     0x8A50, 0x8A51, 0x8A52, 0x8A53,          // icl_gt2
113 
114     // Elkhart Lake
115     0x4541, 0x4551, 0x4555, 0x4557, 0x4570, 0x4571,
116 
117     // Jasper Lake
118     0x4E51, 0x4E55, 0x4E57, 0x4E61, 0x4E71};
119 
120 const uint16_t IntelGen12[] = {
121     // Rocket Lake
122     0x4C8C,                          // rkl_gt05
123     0x4C8A, 0x4C8B, 0x4C90, 0x4C9A,  // rkl_gt1
124 
125     // Alder Lake
126     0x468B,                                                                  // adl_gt05
127     0x4680, 0x4682, 0x4688, 0x468A, 0x4690, 0x4692, 0x4693,                  // adl_gt1
128     0x4626, 0x4628, 0x462A, 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8,  // adl_gt2
129     0x46AA, 0x46B0, 0x46B1, 0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3,  // adl_gt2
130     0x46D0, 0x46D1, 0x46D2, 0x46D3, 0x46D4,                                  // adl_n
131 
132     // Tiger Lake
133     0x9A60, 0x9A68, 0x9A70,                                          // tgl_gt1
134     0x9A40, 0x9A49, 0x9A59, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8,  // tgl_gt2
135 
136     // Raptor Lake
137     0xA780, 0xA781, 0xA782, 0xA783, 0xA788, 0xA789, 0xA78A, 0xA78B,                  // rpl
138     0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9, 0xA7AA, 0xA7AB, 0xA7AC, 0xA7AD,  // rpl_p
139 
140     // DG1
141     0x4905, 0x4906, 0x4907, 0x4908, 0x4909};
142 
143 // The following is used to parse generic Vulkan driver versions.
ParseGenericVulkanDriverVersion(uint32_t driverVersion)144 angle::VersionTriple ParseGenericVulkanDriverVersion(uint32_t driverVersion)
145 {
146     // Generic Vulkan driver versions are built using the following format:
147     // (Major << 22) | (Minor << 12) | (Patch)
148     constexpr uint32_t kMinorVersionMask = angle::BitMask<uint32_t>(10);
149     constexpr uint32_t kPatchVersionMask = angle::BitMask<uint32_t>(12);
150     return angle::VersionTriple(driverVersion >> 22, (driverVersion >> 12) & kMinorVersionMask,
151                                 driverVersion & kPatchVersionMask);
152 }
153 }  // anonymous namespace
154 
IntelDriverVersion(uint32_t buildNumber)155 IntelDriverVersion::IntelDriverVersion(uint32_t buildNumber) : mBuildNumber(buildNumber) {}
156 
IntelDriverVersion(uint32_t majorVersion,uint32_t minorVersion)157 IntelDriverVersion::IntelDriverVersion(uint32_t majorVersion, uint32_t minorVersion)
158 {
159     // The following format is only used in Windows/Intel drivers.
160     // < Major (18 bits) | Minor (14 bits) >
161 #if !defined(ANGLE_PLATFORM_WINDOWS)
162     mBuildNumber = 0;
163 #else
164     constexpr uint32_t kMajorVersionMask = angle::BitMask<uint32_t>(18);
165     constexpr uint32_t kMinorVersionMask = angle::BitMask<uint32_t>(14);
166     ASSERT(majorVersion <= kMajorVersionMask && minorVersion <= kMinorVersionMask);
167 
168     mBuildNumber = (majorVersion << 14) | minorVersion;
169 #endif
170 }
171 
operator ==(const IntelDriverVersion & version) const172 bool IntelDriverVersion::operator==(const IntelDriverVersion &version) const
173 {
174     return mBuildNumber == version.mBuildNumber;
175 }
176 
operator !=(const IntelDriverVersion & version) const177 bool IntelDriverVersion::operator!=(const IntelDriverVersion &version) const
178 {
179     return !(*this == version);
180 }
181 
operator <(const IntelDriverVersion & version) const182 bool IntelDriverVersion::operator<(const IntelDriverVersion &version) const
183 {
184     return mBuildNumber < version.mBuildNumber;
185 }
186 
operator >=(const IntelDriverVersion & version) const187 bool IntelDriverVersion::operator>=(const IntelDriverVersion &version) const
188 {
189     return !(*this < version);
190 }
191 
IsSandyBridge(uint32_t DeviceId)192 bool IsSandyBridge(uint32_t DeviceId)
193 {
194     return std::find(std::begin(SandyBridge), std::end(SandyBridge), DeviceId) !=
195            std::end(SandyBridge);
196 }
197 
IsIvyBridge(uint32_t DeviceId)198 bool IsIvyBridge(uint32_t DeviceId)
199 {
200     return std::find(std::begin(IvyBridge), std::end(IvyBridge), DeviceId) != std::end(IvyBridge);
201 }
202 
IsHaswell(uint32_t DeviceId)203 bool IsHaswell(uint32_t DeviceId)
204 {
205     return std::find(std::begin(Haswell), std::end(Haswell), DeviceId) != std::end(Haswell);
206 }
207 
IsBroadwell(uint32_t DeviceId)208 bool IsBroadwell(uint32_t DeviceId)
209 {
210     return std::find(std::begin(Broadwell), std::end(Broadwell), DeviceId) != std::end(Broadwell);
211 }
212 
IsCherryView(uint32_t DeviceId)213 bool IsCherryView(uint32_t DeviceId)
214 {
215     return std::find(std::begin(CherryView), std::end(CherryView), DeviceId) !=
216            std::end(CherryView);
217 }
218 
IsSkylake(uint32_t DeviceId)219 bool IsSkylake(uint32_t DeviceId)
220 {
221     return std::find(std::begin(Skylake), std::end(Skylake), DeviceId) != std::end(Skylake);
222 }
223 
IsBroxton(uint32_t DeviceId)224 bool IsBroxton(uint32_t DeviceId)
225 {
226     return std::find(std::begin(Broxton), std::end(Broxton), DeviceId) != std::end(Broxton);
227 }
228 
IsKabyLake(uint32_t DeviceId)229 bool IsKabyLake(uint32_t DeviceId)
230 {
231     return std::find(std::begin(KabyLake), std::end(KabyLake), DeviceId) != std::end(KabyLake);
232 }
233 
IsGeminiLake(uint32_t DeviceId)234 bool IsGeminiLake(uint32_t DeviceId)
235 {
236     return std::find(std::begin(GeminiLake), std::end(GeminiLake), DeviceId) !=
237            std::end(GeminiLake);
238 }
239 
IsCoffeeLake(uint32_t DeviceId)240 bool IsCoffeeLake(uint32_t DeviceId)
241 {
242     return std::find(std::begin(CoffeeLake), std::end(CoffeeLake), DeviceId) !=
243            std::end(CoffeeLake);
244 }
245 
IsMeteorLake(uint32_t DeviceId)246 bool IsMeteorLake(uint32_t DeviceId)
247 {
248     return std::find(std::begin(MeteorLake), std::end(MeteorLake), DeviceId) !=
249            std::end(MeteorLake);
250 }
251 
Is9thGenIntel(uint32_t DeviceId)252 bool Is9thGenIntel(uint32_t DeviceId)
253 {
254     return IsSkylake(DeviceId) || IsBroxton(DeviceId) || IsKabyLake(DeviceId);
255 }
256 
Is11thGenIntel(uint32_t DeviceId)257 bool Is11thGenIntel(uint32_t DeviceId)
258 {
259     return std::find(std::begin(IntelGen11), std::end(IntelGen11), DeviceId) !=
260            std::end(IntelGen11);
261 }
262 
Is12thGenIntel(uint32_t DeviceId)263 bool Is12thGenIntel(uint32_t DeviceId)
264 {
265     return std::find(std::begin(IntelGen12), std::end(IntelGen12), DeviceId) !=
266            std::end(IntelGen12);
267 }
268 
GetVendorString(uint32_t vendorId)269 std::string GetVendorString(uint32_t vendorId)
270 {
271     switch (vendorId)
272     {
273         case VENDOR_ID_AMD:
274             return "AMD";
275         case VENDOR_ID_ARM:
276             return "ARM";
277         case VENDOR_ID_APPLE:
278             return "Apple";
279         case VENDOR_ID_BROADCOM:
280             return "Broadcom";
281         case VENDOR_ID_GOOGLE:
282             return "Google";
283         case VENDOR_ID_INTEL:
284             return "Intel";
285         case VENDOR_ID_MESA:
286             return "Mesa";
287         case VENDOR_ID_MICROSOFT:
288             return "Microsoft";
289         case VENDOR_ID_NVIDIA:
290             return "NVIDIA";
291         case VENDOR_ID_POWERVR:
292             return "Imagination Technologies";
293         case VENDOR_ID_QUALCOMM:
294             return "Qualcomm";
295         case VENDOR_ID_SAMSUNG:
296             return "Samsung Electronics Co., Ltd.";
297         case VENDOR_ID_VIVANTE:
298             return "Vivante";
299         case VENDOR_ID_VMWARE:
300             return "VMware";
301         case VENDOR_ID_VIRTIO:
302             return "VirtIO";
303         case 0xba5eba11:  // Mock vendor ID used for tests.
304             return "Test";
305         case 0:
306             return "NULL";
307     }
308 
309     std::stringstream s;
310     s << gl::FmtHex(vendorId);
311     return s.str();
312 }
313 
ParseIntelWindowsDriverVersion(uint32_t driverVersion)314 IntelDriverVersion ParseIntelWindowsDriverVersion(uint32_t driverVersion)
315 {
316 #if !defined(ANGLE_PLATFORM_WINDOWS)
317     return IntelDriverVersion(0);
318 #else
319     // Windows Intel driver versions are built in the following format:
320     // < Major (18 bits) | Minor (14 bits) >
321     constexpr uint32_t kMinorVersionMask = angle::BitMask<uint32_t>(14);
322     return IntelDriverVersion(driverVersion >> 18, driverVersion & kMinorVersionMask);
323 #endif
324 }
325 
ParseARMVulkanDriverVersion(uint32_t driverVersion)326 ARMDriverVersion ParseARMVulkanDriverVersion(uint32_t driverVersion)
327 {
328     return ParseGenericVulkanDriverVersion(driverVersion);
329 }
330 
ParseQualcommVulkanDriverVersion(uint32_t driverVersion)331 QualcommDriverVersion ParseQualcommVulkanDriverVersion(uint32_t driverVersion)
332 {
333     return ParseGenericVulkanDriverVersion(driverVersion);
334 }
335 
GetAndroidSDKVersion()336 int GetAndroidSDKVersion()
337 {
338     std::string androidSdkLevel;
339     if (!angle::android::GetSystemProperty(angle::android::kSDKSystemPropertyName,
340                                            &androidSdkLevel))
341     {
342         return 0;
343     }
344 
345     return std::atoi(androidSdkLevel.c_str());
346 }
347 #if !defined(ANGLE_PLATFORM_MACOS)
GetMacOSVersion()348 OSVersion GetMacOSVersion()
349 {
350     // Return a default version
351     return OSVersion(0, 0, 0);
352 }
353 #endif
354 
355 #if !ANGLE_PLATFORM_IOS_FAMILY
GetiOSVersion()356 OSVersion GetiOSVersion()
357 {
358     // Return a default version
359     return OSVersion(0, 0, 0);
360 }
361 #endif
362 
363 #if defined(ANGLE_PLATFORM_LINUX)
ParseLinuxOSVersion(const char * version,int * major,int * minor,int * patch)364 bool ParseLinuxOSVersion(const char *version, int *major, int *minor, int *patch)
365 {
366     errno = 0;  // reset global error flag.
367     char *next;
368     *major = static_cast<int>(strtol(version, &next, 10));
369     if (next == nullptr || *next != '.' || errno != 0)
370     {
371         return false;
372     }
373 
374     *minor = static_cast<int>(strtol(next + 1, &next, 10));
375     if (next == nullptr || *next != '.' || errno != 0)
376     {
377         return false;
378     }
379 
380     *patch = static_cast<int>(strtol(next + 1, &next, 10));
381     if (errno != 0)
382     {
383         return false;
384     }
385 
386     return true;
387 }
388 #endif
389 
GetLinuxOSVersion()390 OSVersion GetLinuxOSVersion()
391 {
392 #if defined(ANGLE_PLATFORM_LINUX)
393     struct utsname uname_info;
394     if (uname(&uname_info) != 0)
395     {
396         return OSVersion(0, 0, 0);
397     }
398 
399     int majorVersion = 0, minorVersion = 0, patchVersion = 0;
400     if (ParseLinuxOSVersion(uname_info.release, &majorVersion, &minorVersion, &patchVersion))
401     {
402         return OSVersion(majorVersion, minorVersion, patchVersion);
403     }
404 #endif
405 
406     return OSVersion(0, 0, 0);
407 }
408 
409 // There are multiple environment variables that may or may not be set during Wayland
410 // sessions, including WAYLAND_DISPLAY, XDG_SESSION_TYPE, and DESKTOP_SESSION
IsWayland()411 bool IsWayland()
412 {
413     static bool checked   = false;
414     static bool isWayland = false;
415     if (!checked)
416     {
417         if (IsLinux())
418         {
419             if (!angle::GetEnvironmentVar("WAYLAND_DISPLAY").empty())
420             {
421                 isWayland = true;
422             }
423             else if (angle::GetEnvironmentVar("XDG_SESSION_TYPE") == "wayland")
424             {
425                 isWayland = true;
426             }
427             else if (angle::GetEnvironmentVar("DESKTOP_SESSION").find("wayland") !=
428                      std::string::npos)
429             {
430                 isWayland = true;
431             }
432         }
433         checked = true;
434     }
435     return isWayland;
436 }
437 
438 }  // namespace rx
439