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