• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // Copyright 2019 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 #include "GPUTestConfig.h"
8 
9 #include <stdint.h>
10 #include <iostream>
11 
12 #include "common/angleutils.h"
13 #include "common/debug.h"
14 #include "common/platform.h"
15 #include "common/string_utils.h"
16 #include "gpu_info_util/SystemInfo.h"
17 
18 #if defined(ANGLE_PLATFORM_APPLE)
19 #    include "GPUTestConfig_mac.h"
20 #elif defined(ANGLE_PLATFORM_WINDOWS)
21 #    include <versionhelpers.h>
22 #endif
23 
24 namespace angle
25 {
26 
27 namespace
28 {
29 
30 #if defined(ANGLE_PLATFORM_MACOS)
31 // Generic function call to get the OS version information from any platform
32 // defined below. This function will also cache the OS version info in static
33 // variables.
OperatingSystemVersionNumbers(int32_t * majorVersion,int32_t * minorVersion)34 inline bool OperatingSystemVersionNumbers(int32_t *majorVersion, int32_t *minorVersion)
35 {
36     static int32_t sSavedMajorVersion = -1;
37     static int32_t sSavedMinorVersion = -1;
38     bool ret                          = false;
39     if (sSavedMajorVersion == -1 || sSavedMinorVersion == -1)
40     {
41         GetOperatingSystemVersionNumbers(&sSavedMajorVersion, &sSavedMinorVersion);
42         *majorVersion = sSavedMajorVersion;
43         *minorVersion = sSavedMinorVersion;
44         ret           = true;
45     }
46     else
47     {
48         ret = true;
49     }
50     *majorVersion = sSavedMajorVersion;
51     *minorVersion = sSavedMinorVersion;
52     return ret;
53 }
54 #endif
55 
56 // Check if the OS is any version of Windows
IsWin()57 inline bool IsWin()
58 {
59 #if defined(ANGLE_PLATFORM_WINDOWS)
60     return true;
61 #else
62     return false;
63 #endif
64 }
65 
66 // Check if the OS is Windows XP
IsWinXP()67 inline bool IsWinXP()
68 {
69 #if defined(ANGLE_PLATFORM_WINDOWS)
70     return IsWindowsXPOrGreater() && !IsWindowsVistaOrGreater();
71 #else
72     return false;
73 #endif
74 }
75 
76 // Check if the OS is Windows Vista
IsWinVista()77 inline bool IsWinVista()
78 {
79 #if defined(ANGLE_PLATFORM_WINDOWS)
80     return IsWindowsVistaOrGreater() && !IsWindows7OrGreater();
81 #else
82     return false;
83 #endif
84 }
85 
86 // Check if the OS is Windows 7
IsWin7()87 inline bool IsWin7()
88 {
89 #if defined(ANGLE_PLATFORM_WINDOWS)
90     return IsWindows7OrGreater() && !IsWindows8OrGreater();
91 #else
92     return false;
93 #endif
94 }
95 
96 // Check if the OS is Windows 8
IsWin8()97 inline bool IsWin8()
98 {
99 #if defined(ANGLE_PLATFORM_WINDOWS)
100     return IsWindows8OrGreater() && !IsWindows10OrGreater();
101 #else
102     return false;
103 #endif
104 }
105 
106 // Check if the OS is Windows 10
IsWin10()107 inline bool IsWin10()
108 {
109 #if defined(ANGLE_PLATFORM_WINDOWS)
110     return IsWindows10OrGreater();
111 #else
112     return false;
113 #endif
114 }
115 
116 // Check if the OS is any version of iOS
IsIOS()117 inline bool IsIOS()
118 {
119 #if defined(ANGLE_PLATFORM_IOS)
120     return true;
121 #else
122     return false;
123 #endif
124 }
125 
126 // Check if the OS is any version of OSX
IsMac()127 inline bool IsMac()
128 {
129 #if defined(ANGLE_PLATFORM_MACOS)
130     return true;
131 #else
132     return false;
133 #endif
134 }
135 
136 // Check if the OS is a specific major and minor version of OSX
IsMacVersion(const int32_t majorVersion,const int32_t minorVersion)137 inline bool IsMacVersion(const int32_t majorVersion, const int32_t minorVersion)
138 {
139 #if defined(ANGLE_PLATFORM_MACOS)
140     int32_t currentMajorVersion = 0;
141     int32_t currentMinorVersion = 0;
142     if (OperatingSystemVersionNumbers(&currentMajorVersion, &currentMinorVersion))
143     {
144         if (currentMajorVersion == majorVersion && currentMinorVersion == minorVersion)
145         {
146             return true;
147         }
148     }
149 #endif
150     return false;
151 }
152 
153 // Check if the OS is OSX Leopard
IsMacLeopard()154 inline bool IsMacLeopard()
155 {
156     if (IsMacVersion(10, 5))
157     {
158         return true;
159     }
160     return false;
161 }
162 
163 // Check if the OS is OSX Snow Leopard
IsMacSnowLeopard()164 inline bool IsMacSnowLeopard()
165 {
166     if (IsMacVersion(10, 6))
167     {
168         return true;
169     }
170     return false;
171 }
172 
173 // Check if the OS is OSX Lion
IsMacLion()174 inline bool IsMacLion()
175 {
176     if (IsMacVersion(10, 7))
177     {
178         return true;
179     }
180     return false;
181 }
182 
183 // Check if the OS is OSX Mountain Lion
IsMacMountainLion()184 inline bool IsMacMountainLion()
185 {
186     if (IsMacVersion(10, 8))
187     {
188         return true;
189     }
190     return false;
191 }
192 
193 // Check if the OS is OSX Mavericks
IsMacMavericks()194 inline bool IsMacMavericks()
195 {
196     if (IsMacVersion(10, 9))
197     {
198         return true;
199     }
200     return false;
201 }
202 
203 // Check if the OS is OSX Yosemite
IsMacYosemite()204 inline bool IsMacYosemite()
205 {
206     if (IsMacVersion(10, 10))
207     {
208         return true;
209     }
210     return false;
211 }
212 
213 // Check if the OS is OSX El Capitan
IsMacElCapitan()214 inline bool IsMacElCapitan()
215 {
216     if (IsMacVersion(10, 11))
217     {
218         return true;
219     }
220     return false;
221 }
222 
223 // Check if the OS is OSX Sierra
IsMacSierra()224 inline bool IsMacSierra()
225 {
226     if (IsMacVersion(10, 12))
227     {
228         return true;
229     }
230     return false;
231 }
232 
233 // Check if the OS is OSX High Sierra
IsMacHighSierra()234 inline bool IsMacHighSierra()
235 {
236     if (IsMacVersion(10, 13))
237     {
238         return true;
239     }
240     return false;
241 }
242 
243 // Check if the OS is OSX Mojave
IsMacMojave()244 inline bool IsMacMojave()
245 {
246     if (IsMacVersion(10, 14))
247     {
248         return true;
249     }
250     return false;
251 }
252 
253 // Check if the OS is any version of Linux
IsLinux()254 inline bool IsLinux()
255 {
256 #if defined(ANGLE_PLATFORM_LINUX)
257     return true;
258 #else
259     return false;
260 #endif
261 }
262 
263 // Check if the OS is any version of Android
IsAndroid()264 inline bool IsAndroid()
265 {
266 #if defined(ANGLE_PLATFORM_ANDROID)
267     return true;
268 #else
269     return false;
270 #endif
271 }
272 
273 // Generic function call to populate the SystemInfo struct. This function will
274 // also cache the SystemInfo struct for future calls. Returns false if the
275 // struct was not fully populated. Guaranteed to set sysInfo to a valid pointer
GetGPUTestSystemInfo(SystemInfo ** sysInfo)276 inline bool GetGPUTestSystemInfo(SystemInfo **sysInfo)
277 {
278     static SystemInfo *sSystemInfo = nullptr;
279     static bool sPopulated         = false;
280     if (sSystemInfo == nullptr)
281     {
282         sSystemInfo = new SystemInfo;
283         if (!GetSystemInfo(sSystemInfo))
284         {
285             std::cout << "Error populating SystemInfo." << std::endl;
286         }
287         else
288         {
289             // On dual-GPU Macs we want the active GPU to always appear to be the
290             // high-performance GPU for tests.
291             // We can call the generic GPU info collector which selects the
292             // non-Intel GPU as the active one on dual-GPU machines.
293             // See https://anglebug.com/3701.
294             if (IsMac())
295             {
296                 GetDualGPUInfo(sSystemInfo);
297             }
298             sPopulated = true;
299         }
300     }
301     *sysInfo = sSystemInfo;
302     ASSERT(*sysInfo != nullptr);
303     return sPopulated;
304 }
305 
306 // Get the active GPUDeviceInfo from the SystemInfo struct.
307 // Returns false if devInfo is not guaranteed to be set to the active device.
GetActiveGPU(GPUDeviceInfo ** devInfo)308 inline bool GetActiveGPU(GPUDeviceInfo **devInfo)
309 {
310     SystemInfo *systemInfo = nullptr;
311     GetGPUTestSystemInfo(&systemInfo);
312     if (systemInfo->gpus.size() <= 0)
313     {
314         return false;
315     }
316     uint32_t index = systemInfo->activeGPUIndex;
317     ASSERT(index < systemInfo->gpus.size());
318     *devInfo = &(systemInfo->gpus[index]);
319     return true;
320 }
321 
322 // Get the vendor ID of the active GPU from the SystemInfo struct.
323 // Returns 0 if there is an error.
GetActiveGPUVendorID()324 inline VendorID GetActiveGPUVendorID()
325 {
326     GPUDeviceInfo *activeGPU = nullptr;
327     if (GetActiveGPU(&activeGPU))
328     {
329         return activeGPU->vendorId;
330     }
331     else
332     {
333         return static_cast<VendorID>(0);
334     }
335 }
336 
337 // Get the device ID of the active GPU from the SystemInfo struct.
338 // Returns 0 if there is an error.
GetActiveGPUDeviceID()339 inline DeviceID GetActiveGPUDeviceID()
340 {
341     GPUDeviceInfo *activeGPU = nullptr;
342     if (GetActiveGPU(&activeGPU))
343     {
344         return activeGPU->deviceId;
345     }
346     else
347     {
348         return static_cast<DeviceID>(0);
349     }
350 }
351 
352 // Check whether the active GPU is NVIDIA.
IsNVIDIA()353 inline bool IsNVIDIA()
354 {
355     return angle::IsNVIDIA(GetActiveGPUVendorID());
356 }
357 
358 // Check whether the active GPU is AMD.
IsAMD()359 inline bool IsAMD()
360 {
361     return angle::IsAMD(GetActiveGPUVendorID());
362 }
363 
364 // Check whether the active GPU is Intel.
IsIntel()365 inline bool IsIntel()
366 {
367     return angle::IsIntel(GetActiveGPUVendorID());
368 }
369 
370 // Check whether the active GPU is VMWare.
IsVMWare()371 inline bool IsVMWare()
372 {
373     return angle::IsVMWare(GetActiveGPUVendorID());
374 }
375 
376 // Check whether the active GPU is Apple.
IsApple()377 inline bool IsApple()
378 {
379     return angle::IsApple(GetActiveGPUVendorID());
380 }
381 
382 // Check whether this is a debug build.
IsDebug()383 inline bool IsDebug()
384 {
385 #if !defined(NDEBUG)
386     return true;
387 #else
388     return false;
389 #endif
390 }
391 
392 // Check whether this is a release build.
IsRelease()393 inline bool IsRelease()
394 {
395     return !IsDebug();
396 }
397 
398 // Check whether the system is a specific Android device based on the name.
IsAndroidDevice(const std::string & deviceName)399 inline bool IsAndroidDevice(const std::string &deviceName)
400 {
401     if (!IsAndroid())
402     {
403         return false;
404     }
405     SystemInfo *systemInfo = nullptr;
406     GetGPUTestSystemInfo(&systemInfo);
407     if (systemInfo->machineModelName == deviceName)
408     {
409         return true;
410     }
411     return false;
412 }
413 
414 // Check whether the system is a Nexus 5X device.
IsNexus5X()415 inline bool IsNexus5X()
416 {
417     return IsAndroidDevice("Nexus 5X");
418 }
419 
420 // Check whether the system is a Pixel 2 device.
IsPixel2()421 inline bool IsPixel2()
422 {
423     return IsAndroidDevice("Pixel 2");
424 }
425 
426 // Check whether the system is a Pixel 2XL device.
IsPixel2XL()427 inline bool IsPixel2XL()
428 {
429     return IsAndroidDevice("Pixel 2 XL");
430 }
431 
IsPixel4()432 inline bool IsPixel4()
433 {
434     return IsAndroidDevice("Pixel 4");
435 }
436 
IsPixel4XL()437 inline bool IsPixel4XL()
438 {
439     return IsAndroidDevice("Pixel 4 XL");
440 }
441 
442 // Check whether the active GPU is a specific device based on the string device ID.
IsDeviceIdGPU(const std::string & gpuDeviceId)443 inline bool IsDeviceIdGPU(const std::string &gpuDeviceId)
444 {
445     uint32_t deviceId = 0;
446     if (!HexStringToUInt(gpuDeviceId, &deviceId) || deviceId == 0)
447     {
448         // PushErrorMessage(kErrorMessage[kErrorEntryWithGpuDeviceIdConflicts], line_number);
449         return false;
450     }
451     return (deviceId == GetActiveGPUDeviceID());
452 }
453 
454 // Check whether the active GPU is a NVIDIA Quadro P400
IsNVIDIAQuadroP400()455 inline bool IsNVIDIAQuadroP400()
456 {
457     return (IsNVIDIA() && IsDeviceIdGPU("0x1CB3"));
458 }
459 
460 // Check whether the active GPU is a NVIDIA GTX 1660
IsNVIDIAGTX1660()461 inline bool IsNVIDIAGTX1660()
462 {
463     return (IsNVIDIA() && IsDeviceIdGPU("0x2184"));
464 }
465 
466 // Check whether the backend API has been set to D3D9 in the constructor
IsD3D9(const GPUTestConfig::API & api)467 inline bool IsD3D9(const GPUTestConfig::API &api)
468 {
469     return (api == GPUTestConfig::kAPID3D9);
470 }
471 
472 // Check whether the backend API has been set to D3D11 in the constructor
IsD3D11(const GPUTestConfig::API & api)473 inline bool IsD3D11(const GPUTestConfig::API &api)
474 {
475     return (api == GPUTestConfig::kAPID3D11);
476 }
477 
478 // Check whether the backend API has been set to OpenGL in the constructor
IsGLDesktop(const GPUTestConfig::API & api)479 inline bool IsGLDesktop(const GPUTestConfig::API &api)
480 {
481     return (api == GPUTestConfig::kAPIGLDesktop);
482 }
483 
484 // Check whether the backend API has been set to OpenGLES in the constructor
IsGLES(const GPUTestConfig::API & api)485 inline bool IsGLES(const GPUTestConfig::API &api)
486 {
487     return (api == GPUTestConfig::kAPIGLES);
488 }
489 
490 // Check whether the backend API has been set to Vulkan in the constructor
IsVulkan(const GPUTestConfig::API & api)491 inline bool IsVulkan(const GPUTestConfig::API &api)
492 {
493     return (api == GPUTestConfig::kAPIVulkan) || (api == GPUTestConfig::kAPISwiftShader);
494 }
495 
IsSwiftShader(const GPUTestConfig::API & api)496 inline bool IsSwiftShader(const GPUTestConfig::API &api)
497 {
498     return (api == GPUTestConfig::kAPISwiftShader);
499 }
500 
501 // Check whether the backend API has been set to Metal in the constructor
IsMetal(const GPUTestConfig::API & api)502 inline bool IsMetal(const GPUTestConfig::API &api)
503 {
504     return (api == GPUTestConfig::kAPIMetal);
505 }
506 
507 }  // anonymous namespace
508 
509 // Load all conditions in the constructor since this data will not change during a test set.
GPUTestConfig()510 GPUTestConfig::GPUTestConfig() : GPUTestConfig(false) {}
511 
GPUTestConfig(bool isSwiftShader)512 GPUTestConfig::GPUTestConfig(bool isSwiftShader)
513 {
514     mConditions[kConditionNone]            = false;
515     mConditions[kConditionWinXP]           = IsWinXP();
516     mConditions[kConditionWinVista]        = IsWinVista();
517     mConditions[kConditionWin7]            = IsWin7();
518     mConditions[kConditionWin8]            = IsWin8();
519     mConditions[kConditionWin10]           = IsWin10();
520     mConditions[kConditionWin]             = IsWin();
521     mConditions[kConditionMacLeopard]      = IsMacLeopard();
522     mConditions[kConditionMacSnowLeopard]  = IsMacSnowLeopard();
523     mConditions[kConditionMacLion]         = IsMacLion();
524     mConditions[kConditionMacMountainLion] = IsMacMountainLion();
525     mConditions[kConditionMacMavericks]    = IsMacMavericks();
526     mConditions[kConditionMacYosemite]     = IsMacYosemite();
527     mConditions[kConditionMacElCapitan]    = IsMacElCapitan();
528     mConditions[kConditionMacSierra]       = IsMacSierra();
529     mConditions[kConditionMacHighSierra]   = IsMacHighSierra();
530     mConditions[kConditionMacMojave]       = IsMacMojave();
531     mConditions[kConditionMac]             = IsMac();
532     mConditions[kConditionIOS]             = IsIOS();
533     mConditions[kConditionLinux]           = IsLinux();
534     mConditions[kConditionAndroid]         = IsAndroid();
535     // HW vendors are irrelevant if we are running on SW
536     mConditions[kConditionNVIDIA]      = !isSwiftShader && IsNVIDIA();
537     mConditions[kConditionAMD]         = !isSwiftShader && IsAMD();
538     mConditions[kConditionIntel]       = !isSwiftShader && IsIntel();
539     mConditions[kConditionVMWare]      = !isSwiftShader && IsVMWare();
540     mConditions[kConditionApple]       = !isSwiftShader && IsApple();
541     mConditions[kConditionSwiftShader] = isSwiftShader;
542 
543     mConditions[kConditionRelease] = IsRelease();
544     mConditions[kConditionDebug]   = IsDebug();
545     // If no API provided, pass these conditions by default
546     mConditions[kConditionD3D9]      = true;
547     mConditions[kConditionD3D11]     = true;
548     mConditions[kConditionGLDesktop] = true;
549     mConditions[kConditionGLES]      = true;
550     mConditions[kConditionVulkan]    = true;
551     mConditions[kConditionMetal]     = true;
552 
553     // Devices are irrelevant if we are running on SW
554     mConditions[kConditionNexus5X]          = !isSwiftShader && IsNexus5X();
555     mConditions[kConditionPixel2OrXL]       = !isSwiftShader && (IsPixel2() || IsPixel2XL());
556     mConditions[kConditionPixel4OrXL]       = !isSwiftShader && (IsPixel4() || IsPixel4XL());
557     mConditions[kConditionNVIDIAQuadroP400] = !isSwiftShader && IsNVIDIAQuadroP400();
558     mConditions[kConditionNVIDIAGTX1660]    = !isSwiftShader && IsNVIDIAGTX1660();
559 
560     mConditions[kConditionPreRotation]    = false;
561     mConditions[kConditionPreRotation90]  = false;
562     mConditions[kConditionPreRotation180] = false;
563     mConditions[kConditionPreRotation270] = false;
564 
565     mConditions[kConditionNoSan] = !IsASan() && !IsTSan() && !IsUBSan();
566     mConditions[kConditionASan]  = IsASan();
567     mConditions[kConditionTSan]  = IsTSan();
568     mConditions[kConditionUBSan] = IsUBSan();
569 }
570 
571 // If the constructor is passed an API, load those conditions as well
GPUTestConfig(const API & api,uint32_t preRotation)572 GPUTestConfig::GPUTestConfig(const API &api, uint32_t preRotation)
573     : GPUTestConfig(IsSwiftShader(api))
574 {
575     mConditions[kConditionD3D9]      = IsD3D9(api);
576     mConditions[kConditionD3D11]     = IsD3D11(api);
577     mConditions[kConditionGLDesktop] = IsGLDesktop(api);
578     mConditions[kConditionGLES]      = IsGLES(api);
579     mConditions[kConditionVulkan]    = IsVulkan(api);
580     mConditions[kConditionMetal]     = IsMetal(api);
581 
582     switch (preRotation)
583     {
584         case 90:
585             mConditions[kConditionPreRotation]   = true;
586             mConditions[kConditionPreRotation90] = true;
587             break;
588         case 180:
589             mConditions[kConditionPreRotation]    = true;
590             mConditions[kConditionPreRotation180] = true;
591             break;
592         case 270:
593             mConditions[kConditionPreRotation]    = true;
594             mConditions[kConditionPreRotation270] = true;
595             break;
596         default:
597             break;
598     }
599 }
600 
601 // Return a const reference to the list of all pre-calculated conditions.
getConditions() const602 const GPUTestConfig::ConditionArray &GPUTestConfig::getConditions() const
603 {
604     return mConditions;
605 }
606 
607 }  // namespace angle
608