• 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/3701.
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 this is a debug build.
IsDebug()281 inline bool IsDebug()
282 {
283 #if !defined(NDEBUG)
284     return true;
285 #else
286     return false;
287 #endif
288 }
289 
290 // Check whether this is a release build.
IsRelease()291 inline bool IsRelease()
292 {
293     return !IsDebug();
294 }
295 
296 // Check whether the system is a specific Android device based on the name.
IsAndroidDevice(const std::string & deviceName)297 inline bool IsAndroidDevice(const std::string &deviceName)
298 {
299     if (!IsAndroid())
300     {
301         return false;
302     }
303     SystemInfo *systemInfo = nullptr;
304     GetGPUTestSystemInfo(&systemInfo);
305     if (systemInfo->machineModelName == deviceName)
306     {
307         return true;
308     }
309     return false;
310 }
311 
312 // Check whether the system is a Nexus 5X device.
IsNexus5X()313 inline bool IsNexus5X()
314 {
315     return IsAndroidDevice("Nexus 5X");
316 }
317 
318 // Check whether the system is a Pixel 2 device.
IsPixel2()319 inline bool IsPixel2()
320 {
321     return IsAndroidDevice("Pixel 2");
322 }
323 
324 // Check whether the system is a Pixel 2XL device.
IsPixel2XL()325 inline bool IsPixel2XL()
326 {
327     return IsAndroidDevice("Pixel 2 XL");
328 }
329 
IsPixel4()330 inline bool IsPixel4()
331 {
332     return IsAndroidDevice("Pixel 4");
333 }
334 
IsPixel4XL()335 inline bool IsPixel4XL()
336 {
337     return IsAndroidDevice("Pixel 4 XL");
338 }
339 
IsPixel6()340 inline bool IsPixel6()
341 {
342     return IsAndroidDevice("Pixel 6");
343 }
344 
IsPixel7()345 inline bool IsPixel7()
346 {
347     return IsAndroidDevice("Pixel 7");
348 }
349 
IsOppoFlipN2()350 inline bool IsOppoFlipN2()
351 {
352     return IsAndroidDevice("CPH2437");
353 }
354 
IsMaliG710()355 inline bool IsMaliG710()
356 {
357     return IsPixel7() || IsOppoFlipN2();
358 }
359 
IsGalaxyA23()360 inline bool IsGalaxyA23()
361 {
362     return IsAndroidDevice("SM-A236U1");
363 }
364 
IsGalaxyA34()365 inline bool IsGalaxyA34()
366 {
367     return IsAndroidDevice("SM-A346M");
368 }
369 
IsGalaxyA54()370 inline bool IsGalaxyA54()
371 {
372     return IsAndroidDevice("SM-A546E");
373 }
374 
IsGalaxyS23()375 inline bool IsGalaxyS23()
376 {
377     return IsAndroidDevice("SM-S911U1");
378 }
379 
IsGalaxyQualcomm()380 inline bool IsGalaxyQualcomm()
381 {
382     return IsGalaxyA23() || IsGalaxyS23();
383 }
384 
IsFindX6()385 inline bool IsFindX6()
386 {
387     return IsAndroidDevice("PGFM10");
388 }
389 
390 // Check whether the active GPU is a specific device based on the string device ID.
IsDeviceIdGPU(const std::string & gpuDeviceId)391 inline bool IsDeviceIdGPU(const std::string &gpuDeviceId)
392 {
393     uint32_t deviceId = 0;
394     if (!HexStringToUInt(gpuDeviceId, &deviceId) || deviceId == 0)
395     {
396         // PushErrorMessage(kErrorMessage[kErrorEntryWithGpuDeviceIdConflicts], line_number);
397         return false;
398     }
399     return (deviceId == GetActiveGPUDeviceID());
400 }
401 
402 // Check whether the active GPU is a NVIDIA Quadro P400
IsNVIDIAQuadroP400()403 inline bool IsNVIDIAQuadroP400()
404 {
405     return (IsNVIDIA() && IsDeviceIdGPU("0x1CB3"));
406 }
407 
408 // Check whether the active GPU is a NVIDIA GTX 1660
IsNVIDIAGTX1660()409 inline bool IsNVIDIAGTX1660()
410 {
411     return (IsNVIDIA() && IsDeviceIdGPU("0x2184"));
412 }
413 
414 // Check whether the backend API has been set to D3D9 in the constructor
IsD3D9(const GPUTestConfig::API & api)415 inline bool IsD3D9(const GPUTestConfig::API &api)
416 {
417     return (api == GPUTestConfig::kAPID3D9);
418 }
419 
420 // Check whether the backend API has been set to D3D11 in the constructor
IsD3D11(const GPUTestConfig::API & api)421 inline bool IsD3D11(const GPUTestConfig::API &api)
422 {
423     return (api == GPUTestConfig::kAPID3D11);
424 }
425 
426 // Check whether the backend API has been set to OpenGL in the constructor
IsGLDesktop(const GPUTestConfig::API & api)427 inline bool IsGLDesktop(const GPUTestConfig::API &api)
428 {
429     return (api == GPUTestConfig::kAPIGLDesktop);
430 }
431 
432 // Check whether the backend API has been set to OpenGLES in the constructor
IsGLES(const GPUTestConfig::API & api)433 inline bool IsGLES(const GPUTestConfig::API &api)
434 {
435     return (api == GPUTestConfig::kAPIGLES);
436 }
437 
438 // Check whether the backend API has been set to Vulkan in the constructor
IsVulkan(const GPUTestConfig::API & api)439 inline bool IsVulkan(const GPUTestConfig::API &api)
440 {
441     return (api == GPUTestConfig::kAPIVulkan) || (api == GPUTestConfig::kAPISwiftShader);
442 }
443 
IsSwiftShader(const GPUTestConfig::API & api)444 inline bool IsSwiftShader(const GPUTestConfig::API &api)
445 {
446     return (api == GPUTestConfig::kAPISwiftShader);
447 }
448 
449 // Check whether the backend API has been set to Metal in the constructor
IsMetal(const GPUTestConfig::API & api)450 inline bool IsMetal(const GPUTestConfig::API &api)
451 {
452     return (api == GPUTestConfig::kAPIMetal);
453 }
454 
455 }  // anonymous namespace
456 
457 // Load all conditions in the constructor since this data will not change during a test set.
GPUTestConfig()458 GPUTestConfig::GPUTestConfig() : GPUTestConfig(false) {}
459 
GPUTestConfig(bool isSwiftShader)460 GPUTestConfig::GPUTestConfig(bool isSwiftShader)
461 {
462     mConditions[kConditionNone]            = false;
463     mConditions[kConditionWinXP]           = IsWindowsXP();
464     mConditions[kConditionWinVista]        = IsWindowsVista();
465     mConditions[kConditionWin7]            = IsWindows7();
466     mConditions[kConditionWin8]            = IsWindows8();
467     mConditions[kConditionWin10]           = IsWindows10OrLater();
468     mConditions[kConditionWin]             = IsWindows();
469     mConditions[kConditionMacLeopard]      = IsMacLeopard();
470     mConditions[kConditionMacSnowLeopard]  = IsMacSnowLeopard();
471     mConditions[kConditionMacLion]         = IsMacLion();
472     mConditions[kConditionMacMountainLion] = IsMacMountainLion();
473     mConditions[kConditionMacMavericks]    = IsMacMavericks();
474     mConditions[kConditionMacYosemite]     = IsMacYosemite();
475     mConditions[kConditionMacElCapitan]    = IsMacElCapitan();
476     mConditions[kConditionMacSierra]       = IsMacSierra();
477     mConditions[kConditionMacHighSierra]   = IsMacHighSierra();
478     mConditions[kConditionMacMojave]       = IsMacMojave();
479     mConditions[kConditionMac]             = IsMac();
480     mConditions[kConditionIOS]             = IsIOS();
481     mConditions[kConditionLinux]           = IsLinux();
482     mConditions[kConditionAndroid]         = IsAndroid();
483     // HW vendors are irrelevant if we are running on SW
484     mConditions[kConditionNVIDIA]      = !isSwiftShader && IsNVIDIA();
485     mConditions[kConditionAMD]         = !isSwiftShader && IsAMD();
486     mConditions[kConditionIntel]       = !isSwiftShader && IsIntel();
487     mConditions[kConditionVMWare]      = !isSwiftShader && IsVMWare();
488     mConditions[kConditionApple]       = !isSwiftShader && IsAppleGPU();
489     mConditions[kConditionSwiftShader] = isSwiftShader;
490 
491     mConditions[kConditionRelease] = IsRelease();
492     mConditions[kConditionDebug]   = IsDebug();
493     // If no API provided, pass these conditions by default
494     mConditions[kConditionD3D9]      = true;
495     mConditions[kConditionD3D11]     = true;
496     mConditions[kConditionGLDesktop] = true;
497     mConditions[kConditionGLES]      = true;
498     mConditions[kConditionVulkan]    = true;
499     mConditions[kConditionMetal]     = true;
500 
501     // Devices are irrelevant if we are running on SW
502     mConditions[kConditionNexus5X]          = !isSwiftShader && IsNexus5X();
503     mConditions[kConditionPixel2OrXL]       = !isSwiftShader && (IsPixel2() || IsPixel2XL());
504     mConditions[kConditionPixel4OrXL]       = !isSwiftShader && (IsPixel4() || IsPixel4XL());
505     mConditions[kConditionPixel6]           = !isSwiftShader && (IsPixel6());
506     mConditions[kConditionPixel7]           = !isSwiftShader && (IsPixel7());
507     mConditions[kConditionFlipN2]           = !isSwiftShader && (IsOppoFlipN2());
508     mConditions[kConditionMaliG710]         = !isSwiftShader && (IsMaliG710());
509     mConditions[kConditionGalaxyA23]        = !isSwiftShader && (IsGalaxyA23());
510     mConditions[kConditionGalaxyA34]        = !isSwiftShader && (IsGalaxyA34());
511     mConditions[kConditionGalaxyA54]        = !isSwiftShader && (IsGalaxyA54());
512     mConditions[kConditionGalaxyS23]        = !isSwiftShader && (IsGalaxyS23());
513     mConditions[kConditionGalaxyQualcomm]   = !isSwiftShader && (IsGalaxyQualcomm());
514     mConditions[kConditionFindX6]           = !isSwiftShader && (IsFindX6());
515     mConditions[kConditionNVIDIAQuadroP400] = !isSwiftShader && IsNVIDIAQuadroP400();
516     mConditions[kConditionNVIDIAGTX1660]    = !isSwiftShader && IsNVIDIAGTX1660();
517 
518     mConditions[kConditionPreRotation]    = false;
519     mConditions[kConditionPreRotation90]  = false;
520     mConditions[kConditionPreRotation180] = false;
521     mConditions[kConditionPreRotation270] = false;
522 
523     mConditions[kConditionNoSan] = !IsASan() && !IsTSan() && !IsUBSan();
524     mConditions[kConditionASan]  = IsASan();
525     mConditions[kConditionTSan]  = IsTSan();
526     mConditions[kConditionUBSan] = IsUBSan();
527 }
528 
529 // If the constructor is passed an API, load those conditions as well
GPUTestConfig(const API & api,uint32_t preRotation)530 GPUTestConfig::GPUTestConfig(const API &api, uint32_t preRotation)
531     : GPUTestConfig(IsSwiftShader(api))
532 {
533     mConditions[kConditionD3D9]      = IsD3D9(api);
534     mConditions[kConditionD3D11]     = IsD3D11(api);
535     mConditions[kConditionGLDesktop] = IsGLDesktop(api);
536     mConditions[kConditionGLES]      = IsGLES(api);
537     mConditions[kConditionVulkan]    = IsVulkan(api);
538     mConditions[kConditionMetal]     = IsMetal(api);
539 
540     switch (preRotation)
541     {
542         case 90:
543             mConditions[kConditionPreRotation]   = true;
544             mConditions[kConditionPreRotation90] = true;
545             break;
546         case 180:
547             mConditions[kConditionPreRotation]    = true;
548             mConditions[kConditionPreRotation180] = true;
549             break;
550         case 270:
551             mConditions[kConditionPreRotation]    = true;
552             mConditions[kConditionPreRotation270] = true;
553             break;
554         default:
555             break;
556     }
557 }
558 
559 // Return a const reference to the list of all pre-calculated conditions.
getConditions() const560 const GPUTestConfig::ConditionArray &GPUTestConfig::getConditions() const
561 {
562     return mConditions;
563 }
564 
565 }  // namespace angle
566