xref: /aosp_15_r20/external/angle/src/tests/test_utils/angle_test_instantiate.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 &param,
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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param)
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 &param)
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 &param)
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