• 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 OSX
IsMac()164 inline bool IsMac()
165 {
166 #if defined(ANGLE_PLATFORM_APPLE)
167     return true;
168 #else
169     return false;
170 #endif
171 }
172 
173 // Check if the OS is a specific major and minor version of OSX
IsMacVersion(const int32_t majorVersion,const int32_t minorVersion)174 inline bool IsMacVersion(const int32_t majorVersion, const int32_t minorVersion)
175 {
176     if (IsMac())
177     {
178         int32_t currentMajorVersion = 0;
179         int32_t currentMinorVersion = 0;
180         if (OperatingSystemVersionNumbers(&currentMajorVersion, &currentMinorVersion))
181         {
182             if (currentMajorVersion == majorVersion && currentMinorVersion == minorVersion)
183             {
184                 return true;
185             }
186         }
187     }
188     return false;
189 }
190 
191 // Check if the OS is OSX Leopard
IsMacLeopard()192 inline bool IsMacLeopard()
193 {
194     if (IsMacVersion(10, 5))
195     {
196         return true;
197     }
198     return false;
199 }
200 
201 // Check if the OS is OSX Snow Leopard
IsMacSnowLeopard()202 inline bool IsMacSnowLeopard()
203 {
204     if (IsMacVersion(10, 6))
205     {
206         return true;
207     }
208     return false;
209 }
210 
211 // Check if the OS is OSX Lion
IsMacLion()212 inline bool IsMacLion()
213 {
214     if (IsMacVersion(10, 7))
215     {
216         return true;
217     }
218     return false;
219 }
220 
221 // Check if the OS is OSX Mountain Lion
IsMacMountainLion()222 inline bool IsMacMountainLion()
223 {
224     if (IsMacVersion(10, 8))
225     {
226         return true;
227     }
228     return false;
229 }
230 
231 // Check if the OS is OSX Mavericks
IsMacMavericks()232 inline bool IsMacMavericks()
233 {
234     if (IsMacVersion(10, 9))
235     {
236         return true;
237     }
238     return false;
239 }
240 
241 // Check if the OS is OSX Yosemite
IsMacYosemite()242 inline bool IsMacYosemite()
243 {
244     if (IsMacVersion(10, 10))
245     {
246         return true;
247     }
248     return false;
249 }
250 
251 // Check if the OS is OSX El Capitan
IsMacElCapitan()252 inline bool IsMacElCapitan()
253 {
254     if (IsMacVersion(10, 11))
255     {
256         return true;
257     }
258     return false;
259 }
260 
261 // Check if the OS is OSX Sierra
IsMacSierra()262 inline bool IsMacSierra()
263 {
264     if (IsMacVersion(10, 12))
265     {
266         return true;
267     }
268     return false;
269 }
270 
271 // Check if the OS is OSX High Sierra
IsMacHighSierra()272 inline bool IsMacHighSierra()
273 {
274     if (IsMacVersion(10, 13))
275     {
276         return true;
277     }
278     return false;
279 }
280 
281 // Check if the OS is OSX Mojave
IsMacMojave()282 inline bool IsMacMojave()
283 {
284     if (IsMacVersion(10, 14))
285     {
286         return true;
287     }
288     return false;
289 }
290 
291 // Check if the OS is any version of Linux
IsLinux()292 inline bool IsLinux()
293 {
294 #if defined(ANGLE_PLATFORM_LINUX)
295     return true;
296 #else
297     return false;
298 #endif
299 }
300 
301 // Check if the OS is any version of Android
IsAndroid()302 inline bool IsAndroid()
303 {
304 #if defined(ANGLE_PLATFORM_ANDROID)
305     return true;
306 #else
307     return false;
308 #endif
309 }
310 
311 // Generic function call to populate the SystemInfo struct. This function will
312 // also cache the SystemInfo struct for future calls. Returns false if the
313 // struct was not fully populated. Guaranteed to set sysInfo to a valid pointer
GetGPUTestSystemInfo(SystemInfo ** sysInfo)314 inline bool GetGPUTestSystemInfo(SystemInfo **sysInfo)
315 {
316     static SystemInfo *sSystemInfo = nullptr;
317     static bool sPopulated         = false;
318     if (sSystemInfo == nullptr)
319     {
320         sSystemInfo = new SystemInfo;
321         if (!GetSystemInfo(sSystemInfo))
322         {
323             std::cout << "Error populating SystemInfo for dEQP tests." << std::endl;
324         }
325         else
326         {
327             // On dual-GPU Macs we want the active GPU to always appear to be the
328             // high-performance GPU for tests.
329             // We can call the generic GPU info collector which selects the
330             // non-Intel GPU as the active one on dual-GPU machines.
331             // See https://anglebug.com/3701.
332             if (IsMac())
333             {
334                 GetDualGPUInfo(sSystemInfo);
335             }
336             sPopulated = true;
337         }
338     }
339     *sysInfo = sSystemInfo;
340     ASSERT(*sysInfo != nullptr);
341     return sPopulated;
342 }
343 
344 // Get the active GPUDeviceInfo from the SystemInfo struct.
345 // Returns false if devInfo is not guaranteed to be set to the active device.
GetActiveGPU(GPUDeviceInfo ** devInfo)346 inline bool GetActiveGPU(GPUDeviceInfo **devInfo)
347 {
348     SystemInfo *systemInfo = nullptr;
349     GetGPUTestSystemInfo(&systemInfo);
350     if (systemInfo->gpus.size() <= 0)
351     {
352         return false;
353     }
354     uint32_t index = systemInfo->activeGPUIndex;
355     ASSERT(index < systemInfo->gpus.size());
356     *devInfo = &(systemInfo->gpus[index]);
357     return true;
358 }
359 
360 // Get the vendor ID of the active GPU from the SystemInfo struct.
361 // Returns 0 if there is an error.
GetActiveGPUVendorID()362 inline VendorID GetActiveGPUVendorID()
363 {
364     GPUDeviceInfo *activeGPU = nullptr;
365     if (GetActiveGPU(&activeGPU))
366     {
367         return activeGPU->vendorId;
368     }
369     else
370     {
371         return static_cast<VendorID>(0);
372     }
373 }
374 
375 // Get the device ID of the active GPU from the SystemInfo struct.
376 // Returns 0 if there is an error.
GetActiveGPUDeviceID()377 inline DeviceID GetActiveGPUDeviceID()
378 {
379     GPUDeviceInfo *activeGPU = nullptr;
380     if (GetActiveGPU(&activeGPU))
381     {
382         return activeGPU->deviceId;
383     }
384     else
385     {
386         return static_cast<DeviceID>(0);
387     }
388 }
389 
390 // Check whether the active GPU is NVIDIA.
IsNVIDIA()391 inline bool IsNVIDIA()
392 {
393     return angle::IsNVIDIA(GetActiveGPUVendorID());
394 }
395 
396 // Check whether the active GPU is AMD.
IsAMD()397 inline bool IsAMD()
398 {
399     return angle::IsAMD(GetActiveGPUVendorID());
400 }
401 
402 // Check whether the active GPU is Intel.
IsIntel()403 inline bool IsIntel()
404 {
405     return angle::IsIntel(GetActiveGPUVendorID());
406 }
407 
408 // Check whether the active GPU is VMWare.
IsVMWare()409 inline bool IsVMWare()
410 {
411     return angle::IsVMWare(GetActiveGPUVendorID());
412 }
413 
414 // Check whether this is a debug build.
IsDebug()415 inline bool IsDebug()
416 {
417 #if !defined(NDEBUG)
418     return true;
419 #else
420     return false;
421 #endif
422 }
423 
424 // Check whether this is a release build.
IsRelease()425 inline bool IsRelease()
426 {
427     return !IsDebug();
428 }
429 
430 // Check whether the system is a specific Android device based on the name.
IsAndroidDevice(const std::string & deviceName)431 inline bool IsAndroidDevice(const std::string &deviceName)
432 {
433     if (!IsAndroid())
434     {
435         return false;
436     }
437     SystemInfo *systemInfo = nullptr;
438     GetGPUTestSystemInfo(&systemInfo);
439     if (systemInfo->machineModelName == deviceName)
440     {
441         return true;
442     }
443     return false;
444 }
445 
446 // Check whether the system is a Nexus 5X device.
IsNexus5X()447 inline bool IsNexus5X()
448 {
449     return IsAndroidDevice("Nexus 5X");
450 }
451 
452 // Check whether the system is a Pixel 2 device.
IsPixel2()453 inline bool IsPixel2()
454 {
455     return IsAndroidDevice("Pixel 2");
456 }
457 
458 // Check whether the system is a Pixel 2XL device.
IsPixel2XL()459 inline bool IsPixel2XL()
460 {
461     return IsAndroidDevice("Pixel 2 XL");
462 }
463 
464 // Check whether the active GPU is a specific device based on the string device ID.
IsDeviceIdGPU(const std::string & gpuDeviceId)465 inline bool IsDeviceIdGPU(const std::string &gpuDeviceId)
466 {
467     uint32_t deviceId = 0;
468     if (!HexStringToUInt(gpuDeviceId, &deviceId) || deviceId == 0)
469     {
470         // PushErrorMessage(kErrorMessage[kErrorEntryWithGpuDeviceIdConflicts], line_number);
471         return false;
472     }
473     return (deviceId == GetActiveGPUDeviceID());
474 }
475 
476 // Check whether the active GPU is a NVIDIA Quadro P400
IsNVIDIAQuadroP400()477 inline bool IsNVIDIAQuadroP400()
478 {
479     if (!IsNVIDIA())
480     {
481         return false;
482     }
483     return IsDeviceIdGPU("0x1CB3");
484 }
485 
486 // Check whether the backend API has been set to D3D9 in the constructor
IsD3D9(const GPUTestConfig::API & api)487 inline bool IsD3D9(const GPUTestConfig::API &api)
488 {
489     return (api == GPUTestConfig::kAPID3D9);
490 }
491 
492 // Check whether the backend API has been set to D3D11 in the constructor
IsD3D11(const GPUTestConfig::API & api)493 inline bool IsD3D11(const GPUTestConfig::API &api)
494 {
495     return (api == GPUTestConfig::kAPID3D11);
496 }
497 
498 // Check whether the backend API has been set to OpenGL in the constructor
IsGLDesktop(const GPUTestConfig::API & api)499 inline bool IsGLDesktop(const GPUTestConfig::API &api)
500 {
501     return (api == GPUTestConfig::kAPIGLDesktop);
502 }
503 
504 // Check whether the backend API has been set to OpenGLES in the constructor
IsGLES(const GPUTestConfig::API & api)505 inline bool IsGLES(const GPUTestConfig::API &api)
506 {
507     return (api == GPUTestConfig::kAPIGLES);
508 }
509 
510 // Check whether the backend API has been set to Vulkan in the constructor
IsVulkan(const GPUTestConfig::API & api)511 inline bool IsVulkan(const GPUTestConfig::API &api)
512 {
513     return (api == GPUTestConfig::kAPIVulkan) || (api == GPUTestConfig::kAPISwiftShader);
514 }
515 
IsSwiftShader(const GPUTestConfig::API & api)516 inline bool IsSwiftShader(const GPUTestConfig::API &api)
517 {
518     return (api == GPUTestConfig::kAPISwiftShader);
519 }
520 
521 // Check whether the backend API has been set to Metal in the constructor
IsMetal(const GPUTestConfig::API & api)522 inline bool IsMetal(const GPUTestConfig::API &api)
523 {
524     return (api == GPUTestConfig::kAPIMetal);
525 }
526 
527 }  // anonymous namespace
528 
529 // Load all conditions in the constructor since this data will not change during a test set.
GPUTestConfig()530 GPUTestConfig::GPUTestConfig()
531 {
532     mConditions[kConditionNone]            = false;
533     mConditions[kConditionWinXP]           = IsWinXP();
534     mConditions[kConditionWinVista]        = IsWinVista();
535     mConditions[kConditionWin7]            = IsWin7();
536     mConditions[kConditionWin8]            = IsWin8();
537     mConditions[kConditionWin10]           = IsWin10();
538     mConditions[kConditionWin]             = IsWin();
539     mConditions[kConditionMacLeopard]      = IsMacLeopard();
540     mConditions[kConditionMacSnowLeopard]  = IsMacSnowLeopard();
541     mConditions[kConditionMacLion]         = IsMacLion();
542     mConditions[kConditionMacMountainLion] = IsMacMountainLion();
543     mConditions[kConditionMacMavericks]    = IsMacMavericks();
544     mConditions[kConditionMacYosemite]     = IsMacYosemite();
545     mConditions[kConditionMacElCapitan]    = IsMacElCapitan();
546     mConditions[kConditionMacSierra]       = IsMacSierra();
547     mConditions[kConditionMacHighSierra]   = IsMacHighSierra();
548     mConditions[kConditionMacMojave]       = IsMacMojave();
549     mConditions[kConditionMac]             = IsMac();
550     mConditions[kConditionLinux]           = IsLinux();
551     mConditions[kConditionAndroid]         = IsAndroid();
552     mConditions[kConditionNVIDIA]          = IsNVIDIA();
553     mConditions[kConditionAMD]             = IsAMD();
554     mConditions[kConditionIntel]           = IsIntel();
555     mConditions[kConditionVMWare]          = IsVMWare();
556     mConditions[kConditionRelease]         = IsRelease();
557     mConditions[kConditionDebug]           = IsDebug();
558     // If no API provided, pass these conditions by default
559     mConditions[kConditionD3D9]        = true;
560     mConditions[kConditionD3D11]       = true;
561     mConditions[kConditionGLDesktop]   = true;
562     mConditions[kConditionGLES]        = true;
563     mConditions[kConditionVulkan]      = true;
564     mConditions[kConditionSwiftShader] = true;
565     mConditions[kConditionMetal]       = true;
566 
567     mConditions[kConditionNexus5X]          = IsNexus5X();
568     mConditions[kConditionPixel2OrXL]       = IsPixel2() || IsPixel2XL();
569     mConditions[kConditionNVIDIAQuadroP400] = IsNVIDIAQuadroP400();
570 }
571 
572 // If the constructor is passed an API, load those conditions as well
GPUTestConfig(const API & api)573 GPUTestConfig::GPUTestConfig(const API &api) : GPUTestConfig()
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[kConditionSwiftShader] = IsSwiftShader(api);
581     mConditions[kConditionMetal]       = IsMetal(api);
582 }
583 
584 // Return a const reference to the list of all pre-calculated conditions.
getConditions() const585 const GPUTestConfig::ConditionArray &GPUTestConfig::getConditions() const
586 {
587     return mConditions;
588 }
589 
590 }  // namespace angle
591