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