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