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