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