1 //
2 // Copyright 2014 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 // angle_test_instantiate.cpp: Adds support for filtering parameterized
8 // tests by platform, so we skip unsupported configs.
9
10 #include "test_utils/angle_test_instantiate.h"
11
12 #include <algorithm>
13 #include <array>
14 #include <iostream>
15 #include <map>
16
17 #include "angle_gl.h"
18 #include "common/base/anglebase/no_destructor.h"
19 #include "common/debug.h"
20 #include "common/platform.h"
21 #include "common/system_utils.h"
22 #include "gpu_info_util/SystemInfo.h"
23 #include "test_utils/angle_test_configs.h"
24 #include "util/EGLWindow.h"
25 #include "util/OSWindow.h"
26 #include "util/test_utils.h"
27
28 #if defined(ANGLE_PLATFORM_WINDOWS)
29 # include <VersionHelpers.h>
30 # include "util/windows/WGLWindow.h"
31 #endif // defined(ANGLE_PLATFORM_WINDOWS)
32
33 #if defined(ANGLE_PLATFORM_APPLE)
34 # include "test_utils/angle_test_instantiate_apple.h"
35 #endif
36
37 namespace angle
38 {
39 namespace
40 {
IsEGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow,const char * eglLibraryName)41 bool IsEGLConfigSupported(const PlatformParameters ¶m,
42 OSWindow *osWindow,
43 const char *eglLibraryName)
44 {
45 std::unique_ptr<angle::Library> eglLibrary;
46
47 #if defined(ANGLE_USE_UTIL_LOADER)
48 eglLibrary.reset(
49 angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ModuleDir));
50 #endif
51
52 EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);
53 ConfigParameters configParams;
54 bool result =
55 eglWindow->initializeGL(osWindow, eglLibrary.get(), angle::GLESDriverType::AngleEGL,
56 param.eglParameters, configParams);
57 eglWindow->destroyGL();
58 EGLWindow::Delete(&eglWindow);
59 return result;
60 }
61
IsAngleEGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow)62 bool IsAngleEGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow)
63 {
64 return IsEGLConfigSupported(param, osWindow, ANGLE_EGL_LIBRARY_NAME);
65 }
66
IsAngleVulkanSecondariesEGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow)67 bool IsAngleVulkanSecondariesEGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow)
68 {
69 return IsEGLConfigSupported(param, osWindow, ANGLE_VULKAN_SECONDARIES_EGL_LIBRARY_NAME);
70 }
71
IsSystemWGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow)72 bool IsSystemWGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow)
73 {
74 #if defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
75 std::unique_ptr<angle::Library> openglLibrary(
76 angle::OpenSharedLibrary("opengl32", angle::SearchType::SystemDir));
77
78 WGLWindow *wglWindow = WGLWindow::New(param.majorVersion, param.minorVersion);
79 ConfigParameters configParams;
80 bool result =
81 wglWindow->initializeGL(osWindow, openglLibrary.get(), angle::GLESDriverType::SystemWGL,
82 param.eglParameters, configParams);
83 wglWindow->destroyGL();
84 WGLWindow::Delete(&wglWindow);
85 return result;
86 #else
87 return false;
88 #endif // defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
89 }
90
IsSystemEGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow)91 bool IsSystemEGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow)
92 {
93 #if defined(ANGLE_USE_UTIL_LOADER)
94 std::unique_ptr<angle::Library> eglLibrary;
95
96 eglLibrary.reset(OpenSharedLibraryWithExtension(GetNativeEGLLibraryNameWithExtension(),
97 SearchType::SystemDir));
98
99 EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);
100 ConfigParameters configParams;
101 bool result =
102 eglWindow->initializeGL(osWindow, eglLibrary.get(), angle::GLESDriverType::SystemEGL,
103 param.eglParameters, configParams);
104 eglWindow->destroyGL();
105 EGLWindow::Delete(&eglWindow);
106 return result;
107 #else
108 return false;
109 #endif
110 }
111
IsZinkEGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow)112 bool IsZinkEGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow)
113 {
114 return IsEGLConfigSupported(param, osWindow, ANGLE_MESA_EGL_LIBRARY_NAME);
115 }
116
IsAndroidDevice(const std::string & deviceName)117 bool IsAndroidDevice(const std::string &deviceName)
118 {
119 if (!IsAndroid())
120 {
121 return false;
122 }
123 SystemInfo *systemInfo = GetTestSystemInfo();
124 if (systemInfo->machineModelName == deviceName)
125 {
126 return true;
127 }
128 return false;
129 }
130
IsAndroidSdkLevelOrNewer(int level)131 bool IsAndroidSdkLevelOrNewer(int level)
132 {
133 if (!IsAndroid())
134 {
135 return false;
136 }
137 SystemInfo *systemInfo = GetTestSystemInfo();
138 if (systemInfo->androidSdkLevel >= level)
139 {
140 return true;
141 }
142 return false;
143 }
144
IsAndroid9OrNewer()145 bool IsAndroid9OrNewer()
146 {
147 return IsAndroidSdkLevelOrNewer(28);
148 }
149
GetActiveGPUDeviceInfo()150 GPUDeviceInfo *GetActiveGPUDeviceInfo()
151 {
152 SystemInfo *systemInfo = GetTestSystemInfo();
153 // Unfortunately sometimes GPU info collection can fail.
154 if (systemInfo->gpus.empty())
155 {
156 return nullptr;
157 }
158 return &systemInfo->gpus[systemInfo->activeGPUIndex];
159 }
160
HasSystemVendorID(VendorID vendorID)161 bool HasSystemVendorID(VendorID vendorID)
162 {
163 GPUDeviceInfo *gpuInfo = GetActiveGPUDeviceInfo();
164
165 return gpuInfo && gpuInfo->vendorId == vendorID;
166 }
167
HasSystemDeviceID(VendorID vendorID,DeviceID deviceID)168 bool HasSystemDeviceID(VendorID vendorID, DeviceID deviceID)
169 {
170 GPUDeviceInfo *gpuInfo = GetActiveGPUDeviceInfo();
171
172 return gpuInfo && gpuInfo->vendorId == vendorID && gpuInfo->deviceId == deviceID;
173 }
174
175 using ParamAvailabilityCache = std::map<PlatformParameters, bool>;
176
GetAvailabilityCache()177 ParamAvailabilityCache &GetAvailabilityCache()
178 {
179 static angle::base::NoDestructor<std::unique_ptr<ParamAvailabilityCache>>
180 sParamAvailabilityCache(new ParamAvailabilityCache());
181 return **sParamAvailabilityCache;
182 }
183
184 constexpr size_t kMaxConfigNameLen = 100;
185 std::array<char, kMaxConfigNameLen> gSelectedConfig;
186 } // namespace
187
188 bool gEnableANGLEPerTestCaptureLabel = false;
189
IsConfigSelected()190 bool IsConfigSelected()
191 {
192 return gSelectedConfig[0] != 0;
193 }
194
195 #if !defined(ANGLE_PLATFORM_APPLE)
196 // For Apple platform, see angle_test_instantiate_apple.mm
IsMetalTextureSwizzleAvailable()197 bool IsMetalTextureSwizzleAvailable()
198 {
199 return false;
200 }
201 #endif
202
GetTestSystemInfo()203 SystemInfo *GetTestSystemInfo()
204 {
205 static SystemInfo *sSystemInfo = nullptr;
206 if (sSystemInfo == nullptr)
207 {
208 sSystemInfo = new SystemInfo;
209 if (!GetSystemInfo(sSystemInfo))
210 {
211 std::cerr << "Warning: incomplete system info collection.\n";
212 }
213
214 // On dual-GPU Macs we want the active GPU to always appear to be the
215 // high-performance GPU for tests.
216 // We can call the generic GPU info collector which selects the
217 // non-Intel GPU as the active one on dual-GPU machines.
218 if (IsMac())
219 {
220 GetDualGPUInfo(sSystemInfo);
221 }
222
223 // Print complete system info when available.
224 // Seems to trip up Android test expectation parsing.
225 // Also don't print info when a config is selected to prevent test spam.
226 if (!IsAndroid() && !IsConfigSelected())
227 {
228 PrintSystemInfo(*sSystemInfo);
229 }
230 }
231 return sSystemInfo;
232 }
233
IsARM64()234 bool IsARM64()
235 {
236 // _M_ARM64 is Windows-specific, while __aarch64__ is for other platforms.
237 #if defined(_M_ARM64) || defined(__aarch64__)
238 return true;
239 #else
240 return false;
241 #endif
242 }
243
IsOzone()244 bool IsOzone()
245 {
246 #if defined(USE_OZONE) && (defined(USE_X11) || defined(ANGLE_USE_VULKAN_DISPLAY))
247 // We do not have a proper support for Ozone/Linux yet. Still, we need to figure out how to
248 // properly initialize tests and differentiate between X11 and Wayland. Probably, passing a
249 // command line argument could be sufficient. At the moment, run tests only for X11 backend
250 // as we don't have Wayland support in Angle. Yes, this is a bit weird to return false, but
251 // it makes it possible to continue angle tests with X11 regardless of the Chromium config
252 // for linux, which is use_x11 && use_ozone. Also, IsOzone is a bit vague now. It was only
253 // expected that angle could run with ozone/drm backend for ChromeOS. And returning true
254 // for desktop Linux when USE_OZONE && USE_X11 are both defined results in incorrect tests'
255 // expectations. We should also rework them and make IsOzone less vague.
256 //
257 // TODO(crbug.com/angleproject/4977): make it possible to switch between X11 and Wayland on
258 // Ozone/Linux builds. Probably, it's possible to identify the WAYLAND backend by checking
259 // the WAYLAND_DISPLAY or XDG_SESSION_TYPE env vars. And also make the IsOzone method less
260 // vague (read the comment above).
261 return false;
262 #elif defined(USE_OZONE)
263 return true;
264 #else
265 return false;
266 #endif
267 }
268
IsNexus5X()269 bool IsNexus5X()
270 {
271 return IsAndroidDevice("Nexus 5X");
272 }
273
IsNexus9()274 bool IsNexus9()
275 {
276 return IsAndroidDevice("Nexus 9");
277 }
278
IsPixelXL()279 bool IsPixelXL()
280 {
281 return IsAndroidDevice("Pixel XL");
282 }
283
IsPixel2()284 bool IsPixel2()
285 {
286 return IsAndroidDevice("Pixel 2");
287 }
288
IsPixel2XL()289 bool IsPixel2XL()
290 {
291 return IsAndroidDevice("Pixel 2 XL");
292 }
293
IsPixel4()294 bool IsPixel4()
295 {
296 return IsAndroidDevice("Pixel 4");
297 }
298
IsPixel4XL()299 bool IsPixel4XL()
300 {
301 return IsAndroidDevice("Pixel 4 XL");
302 }
303
IsPixel6()304 bool IsPixel6()
305 {
306 return IsAndroidDevice("Pixel 6");
307 }
308
IsGalaxyS22()309 bool IsGalaxyS22()
310 {
311 return IsAndroidDevice("SM-S901B");
312 }
313
IsNVIDIAShield()314 bool IsNVIDIAShield()
315 {
316 return IsAndroidDevice("SHIELD Android TV");
317 }
318
IsAndroid14OrNewer()319 bool IsAndroid14OrNewer()
320 {
321 return IsAndroidSdkLevelOrNewer(34);
322 }
323
IsIntel()324 bool IsIntel()
325 {
326 return HasSystemVendorID(kVendorID_Intel);
327 }
328
IsIntelUHD630Mobile()329 bool IsIntelUHD630Mobile()
330 {
331 return HasSystemDeviceID(kVendorID_Intel, kDeviceID_UHD630Mobile);
332 }
333
IsAMD()334 bool IsAMD()
335 {
336 return HasSystemVendorID(kVendorID_AMD);
337 }
338
IsAppleGPU()339 bool IsAppleGPU()
340 {
341 return HasSystemVendorID(kVendorID_Apple);
342 }
343
IsARM()344 bool IsARM()
345 {
346 return HasSystemVendorID(kVendorID_ARM);
347 }
348
IsSwiftshaderDevice()349 bool IsSwiftshaderDevice()
350 {
351 return HasSystemDeviceID(kVendorID_GOOGLE, kDeviceID_Swiftshader);
352 }
353
IsSwiftShaderSupported()354 bool IsSwiftShaderSupported()
355 {
356 #if defined(ANGLE_ENABLE_SWIFTSHADER)
357 return true;
358 #else
359 return false;
360 #endif
361 }
362
IsNVIDIA()363 bool IsNVIDIA()
364 {
365 #if defined(ANGLE_PLATFORM_ANDROID)
366 // NVIDIA Shield cannot detect vendor ID (http://anglebug.com/42262205)
367 if (IsNVIDIAShield())
368 {
369 return true;
370 }
371 #endif
372 return HasSystemVendorID(kVendorID_NVIDIA);
373 }
374
IsQualcomm()375 bool IsQualcomm()
376 {
377 return HasSystemVendorID(kVendorID_Qualcomm) || IsNexus5X() || IsNexus9() || IsPixelXL() ||
378 IsPixel2() || IsPixel2XL() || IsPixel4() || IsPixel4XL();
379 }
380
HasMesa()381 bool HasMesa()
382 {
383 #if defined(ANGLE_HAS_MESA)
384 return true;
385 #else
386 return false;
387 #endif // defined(ANGLE_HAS_MESA)
388 }
389
IsConfigAllowlisted(const SystemInfo & systemInfo,const PlatformParameters & param)390 bool IsConfigAllowlisted(const SystemInfo &systemInfo, const PlatformParameters ¶m)
391 {
392 VendorID vendorID =
393 systemInfo.gpus.empty() ? 0 : systemInfo.gpus[systemInfo.activeGPUIndex].vendorId;
394
395 // We support the default and null back-ends on every platform.
396 if (param.driver == GLESDriverType::AngleEGL)
397 {
398 if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
399 return true;
400 if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE)
401 return true;
402 }
403
404 if (param.isSwiftshader() || IsSwiftshaderDevice())
405 {
406 if (!IsSwiftShaderSupported())
407 {
408 return false;
409 }
410
411 // TODO: http://crbug.com/swiftshader/145
412 // Swiftshader does not currently have all the robustness features
413 // we need for ANGLE. In particular, it is unable to detect and recover
414 // from infinitely looping shaders. That bug is the tracker for fixing
415 // that and when resolved we can remove the following code.
416 // This test will disable tests marked with the config WithRobustness
417 // when run with the swiftshader Vulkan driver and on Android.
418 if (param.eglParameters.robustness == EGL_TRUE)
419 {
420 return false;
421 }
422 }
423
424 if (param.driver == GLESDriverType::AngleVulkanSecondariesEGL)
425 {
426 if (param.getRenderer() != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
427 {
428 return false;
429 }
430 if (IsAndroid() &&
431 param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE)
432 {
433 return false;
434 }
435 return true;
436 }
437
438 if (IsWindows())
439 {
440 switch (param.driver)
441 {
442 case GLESDriverType::AngleEGL:
443 switch (param.getRenderer())
444 {
445 case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
446 case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
447 return true;
448 case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
449 // Note we disable AMD OpenGL testing on Windows due to using a very old and
450 // outdated card with many driver bugs. See http://anglebug.com/42263687
451 return !IsAMD();
452 case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
453 if (IsARM64())
454 {
455 return param.getDeviceType() ==
456 EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
457 }
458 return true;
459 case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
460 // ES 3.1+ back-end is not supported properly.
461 if (param.eglParameters.majorVersion == 3 &&
462 param.eglParameters.minorVersion > 0)
463 {
464 return false;
465 }
466
467 // Win ES emulation is currently only supported on NVIDIA.
468 return IsNVIDIA(vendorID);
469 case EGL_PLATFORM_ANGLE_TYPE_WEBGPU_ANGLE:
470 return true;
471 default:
472 return false;
473 }
474 case GLESDriverType::SystemWGL:
475 // AMD does not support the ES compatibility extensions.
476 return !IsAMD(vendorID);
477 default:
478 return false;
479 }
480 }
481
482 #if defined(ANGLE_PLATFORM_APPLE)
483 if (IsMac() || IsIOS())
484 {
485 // We do not support non-ANGLE bindings on OSX.
486 if (param.driver != GLESDriverType::AngleEGL)
487 {
488 return false;
489 }
490
491 switch (param.getRenderer())
492 {
493 case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
494 if (IsIOS())
495 {
496 // OpenGL backend has been deprecated on iOS.
497 return false;
498 }
499 // ES 3.1+ back-end is not supported properly.
500 if (param.majorVersion == 3 && param.minorVersion > 0)
501 {
502 return false;
503 }
504 return true;
505 case EGL_PLATFORM_ANGLE_TYPE_WEBGPU_ANGLE:
506 return true;
507 case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
508 if (!IsMetalRendererAvailable())
509 {
510 return false;
511 }
512 return true;
513 case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
514 // OSX does not support native vulkan
515 return param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
516 default:
517 return false;
518 }
519 }
520 #endif // #if defined(ANGLE_PLATFORM_APPLE)
521
522 if (IsFuchsia())
523 {
524 // We do not support non-ANGLE bindings on Fuchsia.
525 if (param.driver != GLESDriverType::AngleEGL)
526 {
527 return false;
528 }
529
530 // ES 3 configs do not work properly on Fuchsia ARM.
531 // TODO(anglebug.com/42262979): Investigate missing features.
532 if (param.majorVersion > 2 && IsARM())
533 return false;
534
535 // Loading swiftshader is not brought up on Fuchsia.
536 // TODO(anglebug.com/42262980): Support loading swiftshader vulkan ICD.
537 if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE)
538 return false;
539
540 // Currently we only support the Vulkan back-end on Fuchsia.
541 return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
542 }
543
544 if (IsOzone())
545 {
546 // We do not support non-ANGLE bindings on Ozone.
547 if (param.driver != GLESDriverType::AngleEGL)
548 return false;
549
550 // ES 3 configs do not work properly on Ozone.
551 if (param.majorVersion > 2)
552 return false;
553
554 // Currently we only support the GLES back-end on Ozone.
555 return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE);
556 }
557
558 if (IsLinux() || IsAndroid())
559 {
560 // We do not support WGL bindings on Linux/Android. We do support system EGL.
561 switch (param.driver)
562 {
563 case GLESDriverType::SystemEGL:
564 return param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
565 case GLESDriverType::SystemWGL:
566 return false;
567 case GLESDriverType::ZinkEGL:
568 return HasMesa();
569 default:
570 break;
571 }
572 }
573
574 if (IsLinux())
575 {
576 ASSERT(param.driver == GLESDriverType::AngleEGL);
577
578 // Currently we support the OpenGL and Vulkan back-ends on Linux.
579 switch (param.getRenderer())
580 {
581 case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
582 return true;
583 case EGL_PLATFORM_ANGLE_TYPE_WEBGPU_ANGLE:
584 return true;
585 case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
586 // http://issuetracker.google.com/173004081
587 return !IsIntel() || !param.isEnableRequested(Feature::AsyncCommandQueue) ||
588 param.isDisableRequested(Feature::AsyncCommandQueue);
589 default:
590 return false;
591 }
592 }
593
594 if (IsAndroid())
595 {
596 ASSERT(param.driver == GLESDriverType::AngleEGL);
597
598 // Nexus Android devices don't support backing 3.2 contexts
599 if (param.eglParameters.majorVersion == 3 && param.eglParameters.minorVersion == 2)
600 {
601 if (IsNexus5X())
602 {
603 return false;
604 }
605 }
606
607 // Currently we support the GLES and Vulkan back-ends on Android.
608 switch (param.getRenderer())
609 {
610 case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
611 return true;
612 case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
613 // Swiftshader's vulkan frontend doesn't build on Android.
614 if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE)
615 {
616 return false;
617 }
618 if (!IsAndroid9OrNewer())
619 {
620 return false;
621 }
622 return true;
623 default:
624 return false;
625 }
626 }
627
628 // Unknown platform.
629 return false;
630 }
631
IsConfigSupported(const PlatformParameters & param)632 bool IsConfigSupported(const PlatformParameters ¶m)
633 {
634 OSWindow *osWindow = OSWindow::New();
635 bool result = false;
636 if (osWindow->initialize("CONFIG_TESTER", 1, 1))
637 {
638 switch (param.driver)
639 {
640 case GLESDriverType::AngleEGL:
641 result = IsAngleEGLConfigSupported(param, osWindow);
642 break;
643 case GLESDriverType::AngleVulkanSecondariesEGL:
644 result = IsAngleVulkanSecondariesEGLConfigSupported(param, osWindow);
645 break;
646 case GLESDriverType::SystemEGL:
647 result = IsSystemEGLConfigSupported(param, osWindow);
648 break;
649 case GLESDriverType::SystemWGL:
650 result = IsSystemWGLConfigSupported(param, osWindow);
651 break;
652 case GLESDriverType::ZinkEGL:
653 result = IsZinkEGLConfigSupported(param, osWindow);
654 break;
655 }
656
657 osWindow->destroy();
658 }
659
660 OSWindow::Delete(&osWindow);
661 return result;
662 }
663
IsPlatformAvailable(const PlatformParameters & param)664 bool IsPlatformAvailable(const PlatformParameters ¶m)
665 {
666 // Disable "null" device when not on ANGLE or in D3D9.
667 if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
668 {
669 if (!IsANGLE(param.driver))
670 return false;
671 if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
672 return false;
673 }
674
675 switch (param.getRenderer())
676 {
677 case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
678 break;
679
680 case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
681 #if !defined(ANGLE_ENABLE_D3D9)
682 return false;
683 #else
684 break;
685 #endif
686
687 case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
688 #if !defined(ANGLE_ENABLE_D3D11)
689 return false;
690 #else
691 break;
692 #endif
693
694 case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
695 case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
696 #if !defined(ANGLE_ENABLE_OPENGL)
697 return false;
698 #else
699 break;
700 #endif
701
702 case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
703 #if !defined(ANGLE_ENABLE_VULKAN)
704 return false;
705 #else
706 break;
707 #endif
708
709 case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
710 #if !defined(ANGLE_ENABLE_METAL)
711 return false;
712 #else
713 break;
714 #endif
715
716 case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
717 #if !defined(ANGLE_ENABLE_NULL)
718 return false;
719 #else
720 break;
721 #endif
722 case EGL_PLATFORM_ANGLE_TYPE_WEBGPU_ANGLE:
723 #if !defined(ANGLE_ENABLE_WGPU)
724 return false;
725 #else
726 break;
727 #endif
728
729 default:
730 std::cout << "Unknown test platform: " << param << std::endl;
731 return false;
732 }
733
734 bool result = false;
735
736 auto iter = GetAvailabilityCache().find(param);
737 if (iter != GetAvailabilityCache().end())
738 {
739 result = iter->second;
740 }
741 else
742 {
743 if (IsConfigSelected())
744 {
745 std::stringstream strstr;
746 strstr << param;
747 if (strstr.str() == std::string(gSelectedConfig.data()))
748 {
749 result = true;
750 }
751 }
752 else
753 {
754 const SystemInfo *systemInfo = GetTestSystemInfo();
755
756 if (systemInfo)
757 {
758 result = IsConfigAllowlisted(*systemInfo, param);
759 }
760 else
761 {
762 result = IsConfigSupported(param);
763 }
764 }
765
766 GetAvailabilityCache()[param] = result;
767
768 // Enable this unconditionally to print available platforms.
769 if (IsConfigSelected())
770 {
771 if (result)
772 {
773 std::cout << "Test Config: " << param << "\n";
774 }
775 }
776 else if (!result)
777 {
778 std::cout << "Skipping tests using configuration " << param
779 << " because it is not available.\n";
780 }
781 }
782 return result;
783 }
784
GetAvailableTestPlatformNames()785 std::vector<std::string> GetAvailableTestPlatformNames()
786 {
787 std::vector<std::string> platformNames;
788
789 for (const auto &iter : GetAvailabilityCache())
790 {
791 if (iter.second)
792 {
793 std::stringstream strstr;
794 strstr << iter.first;
795 platformNames.push_back(strstr.str());
796 }
797 }
798
799 // Keep the list sorted.
800 std::sort(platformNames.begin(), platformNames.end());
801
802 return platformNames;
803 }
804
SetSelectedConfig(const char * selectedConfig)805 void SetSelectedConfig(const char *selectedConfig)
806 {
807 gSelectedConfig.fill(0);
808 strncpy(gSelectedConfig.data(), selectedConfig, kMaxConfigNameLen - 1);
809 }
810
GetDriverTypeFromString(const char * driverName,GLESDriverType defaultDriverType)811 GLESDriverType GetDriverTypeFromString(const char *driverName, GLESDriverType defaultDriverType)
812 {
813 if (!driverName)
814 {
815 return defaultDriverType;
816 }
817
818 if (strcmp(driverName, "angle") == 0)
819 {
820 return GLESDriverType::AngleEGL;
821 }
822
823 if (strcmp(driverName, "angle-vulkan-secondaries") == 0)
824 {
825 return GLESDriverType::AngleVulkanSecondariesEGL;
826 }
827
828 if (strcmp(driverName, "zink") == 0)
829 {
830 return GLESDriverType::ZinkEGL;
831 }
832
833 if (strcmp(driverName, "native") == 0 || strcmp(driverName, "system") == 0)
834 {
835 if (IsWindows())
836 {
837 return GLESDriverType::SystemWGL;
838 }
839 else
840 {
841 return GLESDriverType::SystemEGL;
842 }
843 }
844
845 printf("Unknown driver type: %s\n", driverName);
846 exit(EXIT_FAILURE);
847 }
848 } // namespace angle
849