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