| // | |
| // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // angle_test_instantiate.cpp: Adds support for filtering parameterized | |
| // tests by platform, so we skip unsupported configs. | |
| #include "test_utils/angle_test_instantiate.h" | |
| #include <iostream> | |
| #include <map> | |
| #include "angle_gl.h" | |
| #include "common/platform.h" | |
| #include "gpu_info_util/SystemInfo.h" | |
| #include "test_utils/angle_test_configs.h" | |
| #include "util/EGLWindow.h" | |
| #include "util/OSWindow.h" | |
| #include "util/system_utils.h" | |
| #if defined(ANGLE_PLATFORM_WINDOWS) | |
| # include "util/windows/WGLWindow.h" | |
| #endif // defined(ANGLE_PLATFORM_WINDOWS) | |
| namespace angle | |
| { | |
| namespace | |
| { | |
| SystemInfo *GetTestSystemInfo() | |
| { | |
| static SystemInfo *sSystemInfo = nullptr; | |
| if (sSystemInfo == nullptr) | |
| { | |
| sSystemInfo = new SystemInfo; | |
| GetSystemInfo(sSystemInfo); | |
| } | |
| return sSystemInfo; | |
| } | |
| bool IsANGLEConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow) | |
| { | |
| std::unique_ptr<angle::Library> eglLibrary; | |
| #if defined(ANGLE_USE_UTIL_LOADER) | |
| eglLibrary.reset(angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME)); | |
| #endif | |
| EGLWindow *eglWindow = | |
| EGLWindow::New(param.majorVersion, param.minorVersion, param.eglParameters); | |
| bool result = eglWindow->initializeGL(osWindow, eglLibrary.get()); | |
| eglWindow->destroyGL(); | |
| EGLWindow::Delete(&eglWindow); | |
| return result; | |
| } | |
| bool IsWGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow) | |
| { | |
| #if defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER) | |
| std::unique_ptr<angle::Library> openglLibrary(angle::OpenSharedLibrary("opengl32")); | |
| WGLWindow *wglWindow = WGLWindow::New(param.majorVersion, param.minorVersion); | |
| bool result = wglWindow->initializeGL(osWindow, openglLibrary.get()); | |
| wglWindow->destroyGL(); | |
| WGLWindow::Delete(&wglWindow); | |
| return result; | |
| #else | |
| return false; | |
| #endif // defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER) | |
| } | |
| bool IsNativeConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow) | |
| { | |
| // Not yet implemented. | |
| return false; | |
| } | |
| } // namespace | |
| bool IsAndroid() | |
| { | |
| #if defined(ANGLE_PLATFORM_ANDROID) | |
| return true; | |
| #else | |
| return false; | |
| #endif | |
| } | |
| bool IsLinux() | |
| { | |
| #if defined(ANGLE_PLATFORM_LINUX) | |
| return true; | |
| #else | |
| return false; | |
| #endif | |
| } | |
| bool IsOSX() | |
| { | |
| #if defined(ANGLE_PLATFORM_APPLE) | |
| return true; | |
| #else | |
| return false; | |
| #endif | |
| } | |
| bool IsOzone() | |
| { | |
| #if defined(USE_OZONE) | |
| return true; | |
| #else | |
| return false; | |
| #endif | |
| } | |
| bool IsWindows() | |
| { | |
| #if defined(ANGLE_PLATFORM_WINDOWS) | |
| return true; | |
| #else | |
| return false; | |
| #endif | |
| } | |
| bool IsConfigWhitelisted(const SystemInfo &systemInfo, const PlatformParameters ¶m) | |
| { | |
| VendorID vendorID = systemInfo.gpus[systemInfo.primaryGPUIndex].vendorId; | |
| // We support the default and null back-ends on every platform. | |
| if (param.driver == GLESDriverType::AngleEGL) | |
| { | |
| if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) | |
| return true; | |
| if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE) | |
| return true; | |
| } | |
| // Vulkan ES 3.0 is not yet supported. | |
| if (param.majorVersion > 2 && param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) | |
| { | |
| return false; | |
| } | |
| if (IsWindows()) | |
| { | |
| switch (param.driver) | |
| { | |
| case GLESDriverType::AngleEGL: | |
| switch (param.getRenderer()) | |
| { | |
| case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: | |
| case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: | |
| case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: | |
| case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: | |
| return true; | |
| case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: | |
| // ES 3.1+ back-end is not supported properly. | |
| if (param.eglParameters.majorVersion == 3 && | |
| param.eglParameters.minorVersion > 0) | |
| { | |
| return false; | |
| } | |
| // Win ES emulation is currently only supported on NVIDIA. | |
| return vendorID == kVendorID_Nvidia; | |
| default: | |
| return false; | |
| } | |
| case GLESDriverType::SystemWGL: | |
| // AMD does not support the ES compatibility extensions. | |
| return vendorID != kVendorID_AMD; | |
| default: | |
| return false; | |
| } | |
| } | |
| if (IsOSX()) | |
| { | |
| // Currently we only support the OpenGL back-end on OSX. | |
| if (param.driver != GLESDriverType::AngleEGL) | |
| { | |
| return false; | |
| } | |
| // OSX does not support ES 3.1 features. | |
| if (param.majorVersion == 3 && param.minorVersion > 0) | |
| { | |
| return false; | |
| } | |
| return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE); | |
| } | |
| if (IsOzone()) | |
| { | |
| // Currently we only support the GLES back-end on Ozone. | |
| if (param.driver != GLESDriverType::AngleEGL) | |
| return false; | |
| // ES 3 configs do not work properly on Ozone. | |
| if (param.majorVersion > 2) | |
| return false; | |
| return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE); | |
| } | |
| if (IsLinux()) | |
| { | |
| // Currently we support the OpenGL and Vulkan back-ends on Linux. | |
| if (param.driver != GLESDriverType::AngleEGL) | |
| { | |
| return false; | |
| } | |
| switch (param.getRenderer()) | |
| { | |
| case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: | |
| case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: | |
| // Note that system info collection depends on Vulkan support. | |
| return true; | |
| default: | |
| return false; | |
| } | |
| } | |
| if (IsAndroid()) | |
| { | |
| // Currently we support the GLES and Vulkan back-ends on Linux. | |
| if (param.driver != GLESDriverType::AngleEGL) | |
| { | |
| return false; | |
| } | |
| // Some Android devices don't support backing 3.2 contexts. We should refine this to only | |
| // exclude the problematic devices. | |
| if (param.eglParameters.majorVersion == 3 && param.eglParameters.minorVersion == 2) | |
| { | |
| return false; | |
| } | |
| switch (param.getRenderer()) | |
| { | |
| case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: | |
| case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: | |
| return true; | |
| default: | |
| return false; | |
| } | |
| } | |
| // Unknown platform. | |
| return false; | |
| } | |
| bool IsConfigSupported(const PlatformParameters ¶m) | |
| { | |
| OSWindow *osWindow = OSWindow::New(); | |
| bool result = false; | |
| if (osWindow->initialize("CONFIG_TESTER", 1, 1)) | |
| { | |
| switch (param.driver) | |
| { | |
| case GLESDriverType::AngleEGL: | |
| result = IsANGLEConfigSupported(param, osWindow); | |
| break; | |
| case GLESDriverType::SystemEGL: | |
| result = IsNativeConfigSupported(param, osWindow); | |
| break; | |
| case GLESDriverType::SystemWGL: | |
| result = IsWGLConfigSupported(param, osWindow); | |
| break; | |
| } | |
| osWindow->destroy(); | |
| } | |
| OSWindow::Delete(&osWindow); | |
| return result; | |
| } | |
| bool IsPlatformAvailable(const PlatformParameters ¶m) | |
| { | |
| switch (param.getRenderer()) | |
| { | |
| case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: | |
| break; | |
| case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: | |
| #if !defined(ANGLE_ENABLE_D3D9) | |
| return false; | |
| #else | |
| break; | |
| #endif | |
| case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: | |
| #if !defined(ANGLE_ENABLE_D3D11) | |
| return false; | |
| #else | |
| break; | |
| #endif | |
| case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: | |
| case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: | |
| #if !defined(ANGLE_ENABLE_OPENGL) | |
| return false; | |
| #else | |
| break; | |
| #endif | |
| case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: | |
| #if !defined(ANGLE_ENABLE_VULKAN) | |
| return false; | |
| #else | |
| break; | |
| #endif | |
| case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: | |
| #ifndef ANGLE_ENABLE_NULL | |
| return false; | |
| #endif | |
| break; | |
| default: | |
| std::cout << "Unknown test platform: " << param << std::endl; | |
| return false; | |
| } | |
| static std::map<PlatformParameters, bool> paramAvailabilityCache; | |
| auto iter = paramAvailabilityCache.find(param); | |
| if (iter != paramAvailabilityCache.end()) | |
| { | |
| return iter->second; | |
| } | |
| else | |
| { | |
| const SystemInfo *systemInfo = GetTestSystemInfo(); | |
| bool result = false; | |
| if (systemInfo) | |
| { | |
| result = IsConfigWhitelisted(*systemInfo, param); | |
| } | |
| else | |
| { | |
| result = IsConfigSupported(param); | |
| } | |
| paramAvailabilityCache[param] = result; | |
| if (!result) | |
| { | |
| std::cout << "Skipping tests using configuration " << param | |
| << " because it is not available." << std::endl; | |
| } | |
| return result; | |
| } | |
| } | |
| } // namespace angle |