Path: blob/main_old/src/tests/test_utils/angle_test_instantiate.cpp
1693 views
//1// Copyright 2014 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// angle_test_instantiate.cpp: Adds support for filtering parameterized7// tests by platform, so we skip unsupported configs.89#include "test_utils/angle_test_instantiate.h"1011#include <algorithm>12#include <array>13#include <iostream>14#include <map>1516#include "angle_gl.h"17#include "common/debug.h"18#include "common/platform.h"19#include "common/system_utils.h"20#include "common/third_party/base/anglebase/no_destructor.h"21#include "gpu_info_util/SystemInfo.h"22#include "test_utils/angle_test_configs.h"23#include "util/EGLWindow.h"24#include "util/OSWindow.h"25#include "util/test_utils.h"2627#if defined(ANGLE_PLATFORM_WINDOWS)28# include <VersionHelpers.h>29# include "util/windows/WGLWindow.h"30#endif // defined(ANGLE_PLATFORM_WINDOWS)3132#if defined(ANGLE_PLATFORM_APPLE)33# include "test_utils/angle_test_instantiate_apple.h"34#endif3536namespace angle37{38namespace39{40bool IsAngleEGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow)41{42std::unique_ptr<angle::Library> eglLibrary;4344#if defined(ANGLE_USE_UTIL_LOADER)45eglLibrary.reset(46angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ModuleDir));47#endif4849EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);50ConfigParameters configParams;51bool result =52eglWindow->initializeGL(osWindow, eglLibrary.get(), angle::GLESDriverType::AngleEGL,53param.eglParameters, configParams);54eglWindow->destroyGL();55EGLWindow::Delete(&eglWindow);56return result;57}5859bool IsSystemWGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow)60{61#if defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)62std::unique_ptr<angle::Library> openglLibrary(63angle::OpenSharedLibrary("opengl32", angle::SearchType::SystemDir));6465WGLWindow *wglWindow = WGLWindow::New(param.majorVersion, param.minorVersion);66ConfigParameters configParams;67bool result =68wglWindow->initializeGL(osWindow, openglLibrary.get(), angle::GLESDriverType::SystemWGL,69param.eglParameters, configParams);70wglWindow->destroyGL();71WGLWindow::Delete(&wglWindow);72return result;73#else74return false;75#endif // defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)76}7778bool IsSystemEGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow)79{80#if defined(ANGLE_USE_UTIL_LOADER)81std::unique_ptr<angle::Library> eglLibrary;8283eglLibrary.reset(OpenSharedLibraryWithExtension(GetNativeEGLLibraryNameWithExtension(),84SearchType::SystemDir));8586EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);87ConfigParameters configParams;88bool result =89eglWindow->initializeGL(osWindow, eglLibrary.get(), angle::GLESDriverType::SystemEGL,90param.eglParameters, configParams);91eglWindow->destroyGL();92EGLWindow::Delete(&eglWindow);93return result;94#else95return false;96#endif97}9899bool IsAndroidDevice(const std::string &deviceName)100{101if (!IsAndroid())102{103return false;104}105SystemInfo *systemInfo = GetTestSystemInfo();106if (systemInfo->machineModelName == deviceName)107{108return true;109}110return false;111}112113bool IsAndroid9OrNewer()114{115if (!IsAndroid())116{117return false;118}119SystemInfo *systemInfo = GetTestSystemInfo();120if (systemInfo->androidSdkLevel >= 28)121{122return true;123}124return false;125}126127GPUDeviceInfo *GetActiveGPUDeviceInfo()128{129SystemInfo *systemInfo = GetTestSystemInfo();130// Unfortunately sometimes GPU info collection can fail.131if (systemInfo->gpus.empty())132{133return nullptr;134}135return &systemInfo->gpus[systemInfo->activeGPUIndex];136}137138bool HasSystemVendorID(VendorID vendorID)139{140GPUDeviceInfo *gpuInfo = GetActiveGPUDeviceInfo();141142return gpuInfo && gpuInfo->vendorId == vendorID;143}144145bool HasSystemDeviceID(VendorID vendorID, DeviceID deviceID)146{147GPUDeviceInfo *gpuInfo = GetActiveGPUDeviceInfo();148149return gpuInfo && gpuInfo->vendorId == vendorID && gpuInfo->deviceId == deviceID;150}151152using ParamAvailabilityCache = std::map<PlatformParameters, bool>;153154ParamAvailabilityCache &GetAvailabilityCache()155{156static angle::base::NoDestructor<std::unique_ptr<ParamAvailabilityCache>>157sParamAvailabilityCache(new ParamAvailabilityCache());158return **sParamAvailabilityCache;159}160161constexpr size_t kMaxConfigNameLen = 100;162std::array<char, kMaxConfigNameLen> gSelectedConfig;163} // namespace164165bool gEnableANGLEPerTestCaptureLabel = false;166167bool IsConfigSelected()168{169return gSelectedConfig[0] != 0;170}171172#if !defined(ANGLE_PLATFORM_APPLE)173// For Apple platform, see angle_test_instantiate_apple.mm174bool IsMetalTextureSwizzleAvailable()175{176return false;177}178179bool IsMetalCompressedTexture3DAvailable()180{181return false;182}183#endif184185SystemInfo *GetTestSystemInfo()186{187static SystemInfo *sSystemInfo = nullptr;188if (sSystemInfo == nullptr)189{190sSystemInfo = new SystemInfo;191if (!GetSystemInfo(sSystemInfo))192{193std::cerr << "Warning: incomplete system info collection.\n";194}195196// On dual-GPU Macs we want the active GPU to always appear to be the197// high-performance GPU for tests.198// We can call the generic GPU info collector which selects the199// non-Intel GPU as the active one on dual-GPU machines.200if (IsOSX())201{202GetDualGPUInfo(sSystemInfo);203}204205// Print complete system info when available.206// Seems to trip up Android test expectation parsing.207// Also don't print info when a config is selected to prevent test spam.208if (!IsAndroid() && !IsConfigSelected())209{210PrintSystemInfo(*sSystemInfo);211}212}213return sSystemInfo;214}215216bool IsAndroid()217{218#if defined(ANGLE_PLATFORM_ANDROID)219return true;220#else221return false;222#endif223}224225bool IsLinux()226{227#if defined(ANGLE_PLATFORM_LINUX)228return true;229#else230return false;231#endif232}233234bool IsOSX()235{236#if defined(ANGLE_PLATFORM_MACOS)237return true;238#else239return false;240#endif241}242243bool IsIOS()244{245#if defined(ANGLE_PLATFORM_IOS)246return true;247#else248return false;249#endif250}251252bool IsARM64()253{254// _M_ARM64 is Windows-specific, while __aarch64__ is for other platforms.255#if defined(_M_ARM64) || defined(__aarch64__)256return true;257#else258return false;259#endif260}261262bool IsOzone()263{264#if defined(USE_OZONE) && (defined(USE_X11) || defined(ANGLE_USE_VULKAN_DISPLAY))265// We do not have a proper support for Ozone/Linux yet. Still, we need to figure out how to266// properly initialize tests and differentiate between X11 and Wayland. Probably, passing a267// command line argument could be sufficient. At the moment, run tests only for X11 backend268// as we don't have Wayland support in Angle. Yes, this is a bit weird to return false, but269// it makes it possible to continue angle tests with X11 regardless of the Chromium config270// for linux, which is use_x11 && use_ozone. Also, IsOzone is a bit vague now. It was only271// expected that angle could run with ozone/drm backend for ChromeOS. And returning true272// for desktop Linux when USE_OZONE && USE_X11 are both defined results in incorrect tests'273// expectations. We should also rework them and make IsOzone less vague.274//275// TODO(crbug.com/angleproject/4977): make it possible to switch between X11 and Wayland on276// Ozone/Linux builds. Probably, it's possible to identify the WAYLAND backend by checking277// the WAYLAND_DISPLAY or XDG_SESSION_TYPE env vars. And also make the IsOzone method less278// vague (read the comment above).279return false;280#elif defined(USE_OZONE)281return true;282#else283return false;284#endif285}286287bool IsWindows()288{289#if defined(ANGLE_PLATFORM_WINDOWS)290return true;291#else292return false;293#endif294}295296bool IsWindows7()297{298#if defined(ANGLE_PLATFORM_WINDOWS)299return ::IsWindows7OrGreater() && !::IsWindows8OrGreater();300#else301return false;302#endif303}304305bool IsFuchsia()306{307#if defined(ANGLE_PLATFORM_FUCHSIA)308return true;309#else310return false;311#endif312}313314bool IsNexus5X()315{316return IsAndroidDevice("Nexus 5X");317}318319bool IsNexus9()320{321return IsAndroidDevice("Nexus 9");322}323324bool IsPixelXL()325{326return IsAndroidDevice("Pixel XL");327}328329bool IsPixel2()330{331return IsAndroidDevice("Pixel 2");332}333334bool IsPixel2XL()335{336return IsAndroidDevice("Pixel 2 XL");337}338339bool IsPixel4()340{341return IsAndroidDevice("Pixel 4");342}343344bool IsNVIDIAShield()345{346return IsAndroidDevice("SHIELD Android TV");347}348349bool IsIntel()350{351return HasSystemVendorID(kVendorID_Intel);352}353354bool IsIntelUHD630Mobile()355{356return HasSystemDeviceID(kVendorID_Intel, kDeviceID_UHD630Mobile);357}358359bool IsAMD()360{361return HasSystemVendorID(kVendorID_AMD);362}363364bool IsARM()365{366return HasSystemVendorID(kVendorID_ARM);367}368369bool IsSwiftshaderDevice()370{371return HasSystemDeviceID(kVendorID_GOOGLE, kDeviceID_Swiftshader);372}373374bool IsNVIDIA()375{376#if defined(ANGLE_PLATFORM_ANDROID)377// NVIDIA Shield cannot detect vendor ID (http://anglebug.com/3541)378if (IsNVIDIAShield())379{380return true;381}382#endif383return HasSystemVendorID(kVendorID_NVIDIA);384}385386bool IsQualcomm()387{388return IsNexus5X() || IsNexus9() || IsPixelXL() || IsPixel2() || IsPixel2XL();389}390391bool IsConfigAllowlisted(const SystemInfo &systemInfo, const PlatformParameters ¶m)392{393VendorID vendorID =394systemInfo.gpus.empty() ? 0 : systemInfo.gpus[systemInfo.activeGPUIndex].vendorId;395396// We support the default and null back-ends on every platform.397if (param.driver == GLESDriverType::AngleEGL)398{399if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)400return true;401if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE)402return true;403}404405// TODO: http://crbug.com/swiftshader/145406// Swiftshader does not currently have all the robustness features407// we need for ANGLE. In particular, it is unable to detect and recover408// from infinitely looping shaders. That bug is the tracker for fixing409// that and when resolved we can remove the following code.410// This test will disable tests marked with the config WithRobustness411// when run with the swiftshader Vulkan driver and on Android.412if ((param.isSwiftshader() || IsSwiftshaderDevice()) &&413param.eglParameters.robustness == EGL_TRUE)414{415return false;416}417418if (IsWindows())419{420switch (param.driver)421{422case GLESDriverType::AngleEGL:423switch (param.getRenderer())424{425case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:426case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:427return true;428case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:429// Note we disable AMD OpenGL testing on Windows due to using a very old and430// outdated card with many driver bugs. See http://anglebug.com/5123431return !IsAMD();432case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:433if (IsARM64())434{435return param.getDeviceType() ==436EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;437}438return true;439case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:440// ES 3.1+ back-end is not supported properly.441if (param.eglParameters.majorVersion == 3 &&442param.eglParameters.minorVersion > 0)443{444return false;445}446447// Win ES emulation is currently only supported on NVIDIA.448return IsNVIDIA(vendorID);449default:450return false;451}452case GLESDriverType::SystemWGL:453// AMD does not support the ES compatibility extensions.454return !IsAMD(vendorID);455default:456return false;457}458}459460#if defined(ANGLE_PLATFORM_APPLE)461if (IsOSX() || IsIOS())462{463// We do not support non-ANGLE bindings on OSX.464if (param.driver != GLESDriverType::AngleEGL)465{466return false;467}468469switch (param.getRenderer())470{471case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:472// ES 3.1+ back-end is not supported properly.473if (param.majorVersion == 3 && param.minorVersion > 0)474{475return false;476}477return true;478case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:479if (!IsMetalRendererAvailable())480{481return false;482}483return true;484case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:485// OSX does not support native vulkan486return param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;487default:488return false;489}490}491#endif // #if defined(ANGLE_PLATFORM_APPLE)492493if (IsFuchsia())494{495// We do not support non-ANGLE bindings on Fuchsia.496if (param.driver != GLESDriverType::AngleEGL)497{498return false;499}500501// ES 3 configs do not work properly on Fuchsia ARM.502// TODO(anglebug.com/4352): Investigate missing features.503if (param.majorVersion > 2 && IsARM())504return false;505506// Loading swiftshader is not brought up on Fuchsia.507// TODO(anglebug.com/4353): Support loading swiftshader vulkan ICD.508if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE)509return false;510511// Currently we only support the Vulkan back-end on Fuchsia.512return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);513}514515if (IsOzone())516{517// We do not support non-ANGLE bindings on Ozone.518if (param.driver != GLESDriverType::AngleEGL)519return false;520521// ES 3 configs do not work properly on Ozone.522if (param.majorVersion > 2)523return false;524525// Currently we only support the GLES back-end on Ozone.526return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE);527}528529if (IsLinux() || IsAndroid())530{531// We do not support WGL bindings on Linux/Android. We do support system EGL.532switch (param.driver)533{534case GLESDriverType::SystemEGL:535return param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;536case GLESDriverType::SystemWGL:537return false;538default:539break;540}541}542543if (IsLinux())544{545ASSERT(param.driver == GLESDriverType::AngleEGL);546547// Currently we support the OpenGL and Vulkan back-ends on Linux.548switch (param.getRenderer())549{550case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:551return true;552case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:553// http://issuetracker.google.com/173004081554return !IsIntel() || param.eglParameters.asyncCommandQueueFeatureVulkan != EGL_TRUE;555default:556return false;557}558}559560if (IsAndroid())561{562ASSERT(param.driver == GLESDriverType::AngleEGL);563564// Nexus Android devices don't support backing 3.2 contexts565if (param.eglParameters.majorVersion == 3 && param.eglParameters.minorVersion == 2)566{567if (IsNexus5X())568{569return false;570}571}572573// Currently we support the GLES and Vulkan back-ends on Android.574switch (param.getRenderer())575{576case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:577return true;578case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:579// Swiftshader's vulkan frontend doesn't build on Android.580if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE)581{582return false;583}584if (!IsAndroid9OrNewer())585{586return false;587}588if (param.eglParameters.supportsVulkanViewportFlip == EGL_FALSE)589{590return false;591}592return true;593default:594return false;595}596}597598// Unknown platform.599return false;600}601602bool IsConfigSupported(const PlatformParameters ¶m)603{604OSWindow *osWindow = OSWindow::New();605bool result = false;606if (osWindow->initialize("CONFIG_TESTER", 1, 1))607{608switch (param.driver)609{610case GLESDriverType::AngleEGL:611result = IsAngleEGLConfigSupported(param, osWindow);612break;613case GLESDriverType::SystemEGL:614result = IsSystemEGLConfigSupported(param, osWindow);615break;616case GLESDriverType::SystemWGL:617result = IsSystemWGLConfigSupported(param, osWindow);618break;619}620621osWindow->destroy();622}623624OSWindow::Delete(&osWindow);625return result;626}627628bool IsPlatformAvailable(const PlatformParameters ¶m)629{630// Disable "null" device when not on ANGLE or in D3D9.631if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)632{633if (param.driver != GLESDriverType::AngleEGL)634return false;635if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)636return false;637}638639switch (param.getRenderer())640{641case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:642break;643644case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:645#if !defined(ANGLE_ENABLE_D3D9)646return false;647#else648break;649#endif650651case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:652#if !defined(ANGLE_ENABLE_D3D11)653return false;654#else655break;656#endif657658case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:659case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:660#if !defined(ANGLE_ENABLE_OPENGL)661return false;662#else663break;664#endif665666case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:667#if !defined(ANGLE_ENABLE_VULKAN)668return false;669#else670break;671#endif672673case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:674#if !defined(ANGLE_ENABLE_METAL)675return false;676#else677break;678#endif679680case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:681#if !defined(ANGLE_ENABLE_NULL)682return false;683#else684break;685#endif686687default:688std::cout << "Unknown test platform: " << param << std::endl;689return false;690}691692bool result = false;693694auto iter = GetAvailabilityCache().find(param);695if (iter != GetAvailabilityCache().end())696{697result = iter->second;698}699else700{701if (IsConfigSelected())702{703std::stringstream strstr;704strstr << param;705if (strstr.str() == std::string(gSelectedConfig.data()))706{707result = true;708}709}710else711{712const SystemInfo *systemInfo = GetTestSystemInfo();713714if (systemInfo)715{716result = IsConfigAllowlisted(*systemInfo, param);717}718else719{720result = IsConfigSupported(param);721}722}723724GetAvailabilityCache()[param] = result;725726// Enable this unconditionally to print available platforms.727if (IsConfigSelected())728{729if (result)730{731std::cout << "Test Config: " << param << "\n";732}733}734else if (!result)735{736std::cout << "Skipping tests using configuration " << param737<< " because it is not available.\n";738}739}740return result;741}742743std::vector<std::string> GetAvailableTestPlatformNames()744{745std::vector<std::string> platformNames;746747for (const auto &iter : GetAvailabilityCache())748{749if (iter.second)750{751std::stringstream strstr;752strstr << iter.first;753platformNames.push_back(strstr.str());754}755}756757// Keep the list sorted.758std::sort(platformNames.begin(), platformNames.end());759760return platformNames;761}762763void SetSelectedConfig(const char *selectedConfig)764{765gSelectedConfig.fill(0);766strncpy(gSelectedConfig.data(), selectedConfig, kMaxConfigNameLen - 1);767}768} // namespace angle769770771