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