Edit

kc3-lang/angle/src/tests/test_utils/angle_test_instantiate.cpp

Branch :

  • Show log

    Commit

  • Author : Tobin Ehlis
    Date : 2019-11-13 11:36:35
    Hash : c1776c61
    Message : Vulkan:Add Swiftshader configs Add Swiftshader configs to existing test instantiation macros for all ESX variants. This causes Swiftshader to be used to run end2end tests. Added detection code to know when tests are running on Swiftshader and skipping a number of fails initially. Note that when running ANGLE end2end tests within Chromium build on Win32 bots there were crashes with Swiftshader config for tests that should have been skipped. Due to this, just skipping Swiftshader configs on Win32 for now. Bug: angleproject:4081 Bug: angleproject:4092 Change-Id: I32527a62304c5fad90f645b372edf9411ca2b212 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1914126 Commit-Queue: Tobin Ehlis <tobine@google.com> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/tests/test_utils/angle_test_instantiate.cpp
  • //
    // Copyright 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 "common/system_utils.h"
    #include "gpu_info_util/SystemInfo.h"
    #include "test_utils/angle_test_configs.h"
    #include "util/EGLWindow.h"
    #include "util/OSWindow.h"
    #include "util/test_utils.h"
    
    #if defined(ANGLE_PLATFORM_WINDOWS)
    #    include <VersionHelpers.h>
    #    include "util/windows/WGLWindow.h"
    #endif  // defined(ANGLE_PLATFORM_WINDOWS)
    
    namespace angle
    {
    namespace
    {
    bool IsANGLEConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
    {
        std::unique_ptr<angle::Library> eglLibrary;
    
    #if defined(ANGLE_USE_UTIL_LOADER)
        eglLibrary.reset(
            angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ApplicationDir));
    #endif
    
        EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);
        ConfigParameters configParams;
        bool result =
            eglWindow->initializeGL(osWindow, eglLibrary.get(), param.eglParameters, configParams);
        eglWindow->destroyGL();
        EGLWindow::Delete(&eglWindow);
        return result;
    }
    
    bool IsWGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
    {
    #if defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
        std::unique_ptr<angle::Library> openglLibrary(
            angle::OpenSharedLibrary("opengl32", angle::SearchType::SystemDir));
    
        WGLWindow *wglWindow = WGLWindow::New(param.majorVersion, param.minorVersion);
        ConfigParameters configParams;
        bool result =
            wglWindow->initializeGL(osWindow, openglLibrary.get(), param.eglParameters, configParams);
        wglWindow->destroyGL();
        WGLWindow::Delete(&wglWindow);
        return result;
    #else
        return false;
    #endif  // defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
    }
    
    bool IsNativeConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
    {
        // Not yet implemented.
        return false;
    }
    
    std::map<PlatformParameters, bool> gParamAvailabilityCache;
    
    bool IsAndroidDevice(const std::string &deviceName)
    {
        if (!IsAndroid())
        {
            return false;
        }
        SystemInfo *systemInfo = GetTestSystemInfo();
        if (systemInfo->machineModelName == deviceName)
        {
            return true;
        }
        return false;
    }
    
    bool HasSystemVendorID(VendorID vendorID)
    {
        SystemInfo *systemInfo = GetTestSystemInfo();
        // Unfortunately sometimes GPU info collection can fail.
        if (systemInfo->activeGPUIndex < 0 || systemInfo->gpus.empty())
        {
            return false;
        }
        return systemInfo->gpus[systemInfo->activeGPUIndex].vendorId == vendorID;
    }
    }  // namespace
    
    std::string gSelectedConfig;
    bool gSeparateProcessPerConfig = false;
    
    SystemInfo *GetTestSystemInfo()
    {
        static SystemInfo *sSystemInfo = nullptr;
        if (sSystemInfo == nullptr)
        {
            sSystemInfo = new SystemInfo;
            if (!GetSystemInfo(sSystemInfo))
            {
                std::cerr << "Warning: incomplete system info collection.\n";
            }
    
            // On dual-GPU Macs we want the active GPU to always appear to be the
            // high-performance GPU for tests.
            // We can call the generic GPU info collector which selects the
            // non-Intel GPU as the active one on dual-GPU machines.
            if (IsOSX())
            {
                GetDualGPUInfo(sSystemInfo);
            }
    
            // Print complete system info when available.
            // Seems to trip up Android test expectation parsing.
            // Also don't print info when a config is selected to prevent test spam.
            if (!IsAndroid() && gSelectedConfig.empty())
            {
                PrintSystemInfo(*sSystemInfo);
            }
        }
        return sSystemInfo;
    }
    
    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 IsWindows7()
    {
    #if defined(ANGLE_PLATFORM_WINDOWS)
        return ::IsWindows7OrGreater() && !::IsWindows8OrGreater();
    #else
        return false;
    #endif
    }
    
    bool IsFuchsia()
    {
    #if defined(ANGLE_PLATFORM_FUCHSIA)
        return true;
    #else
        return false;
    #endif
    }
    
    bool IsNexus5X()
    {
        return IsAndroidDevice("Nexus 5X");
    }
    
    bool IsNexus6P()
    {
        return IsAndroidDevice("Nexus 6P");
    }
    
    bool IsNexus9()
    {
        return IsAndroidDevice("Nexus 9");
    }
    
    bool IsPixelXL()
    {
        return IsAndroidDevice("Pixel XL");
    }
    
    bool IsPixel2()
    {
        return IsAndroidDevice("Pixel 2");
    }
    
    bool IsPixel2XL()
    {
        return IsAndroidDevice("Pixel 2 XL");
    }
    
    bool IsNVIDIAShield()
    {
        return IsAndroidDevice("SHIELD Android TV");
    }
    
    bool IsIntel()
    {
        return HasSystemVendorID(kVendorID_Intel);
    }
    
    bool IsAMD()
    {
        return HasSystemVendorID(kVendorID_AMD);
    }
    
    bool IsNVIDIA()
    {
    #if defined(ANGLE_PLATFORM_ANDROID)
        // NVIDIA Shield cannot detect vendor ID (http://anglebug.com/3541)
        if (IsNVIDIAShield())
        {
            return true;
        }
    #endif
        return HasSystemVendorID(kVendorID_NVIDIA);
    }
    
    bool IsConfigWhitelisted(const SystemInfo &systemInfo, const PlatformParameters &param)
    {
        VendorID vendorID = systemInfo.gpus[systemInfo.activeGPUIndex].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;
        }
    
        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 IsNVIDIA(vendorID);
                        default:
                            return false;
                    }
                case GLESDriverType::SystemWGL:
                    // AMD does not support the ES compatibility extensions.
                    return !IsAMD(vendorID);
                default:
                    return false;
            }
        }
    
        if (IsOSX())
        {
            // We do not support non-ANGLE bindings 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;
            }
    
            // Currently we only support the OpenGL back-end on OSX.
            return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE);
        }
    
        if (IsFuchsia())
        {
            // We do not support non-ANGLE bindings on Fuchsia.
            if (param.driver != GLESDriverType::AngleEGL)
            {
                return false;
            }
    
            // Currently we only support the Vulkan back-end on Fuchsia.
            return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
        }
    
        if (IsOzone())
        {
            // We do not support non-ANGLE bindings on Ozone.
            if (param.driver != GLESDriverType::AngleEGL)
                return false;
    
            // ES 3 configs do not work properly on Ozone.
            if (param.majorVersion > 2)
                return false;
    
            // Currently we only support the GLES back-end on Ozone.
            return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE);
        }
    
        if (IsLinux())
        {
            // We do not support non-ANGLE bindings on Linux.
            if (param.driver != GLESDriverType::AngleEGL)
            {
                return false;
            }
    
            // Currently we support the OpenGL and Vulkan back-ends on Linux.
            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())
        {
            // We do not support non-ANGLE bindings on Android.
            if (param.driver != GLESDriverType::AngleEGL)
            {
                return false;
            }
    
            // Nexus Android devices don't support backing 3.2 contexts
            if (param.eglParameters.majorVersion == 3 && param.eglParameters.minorVersion == 2)
            {
                if (IsNexus5X() || IsNexus6P())
                {
                    return false;
                }
            }
    
            // Currently we support the GLES and Vulkan back-ends on Android.
            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 &param)
    {
        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 &param)
    {
        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;
    #elif defined(ANGLE_IS_32_BIT_CPU)
                // http://anglebug.com/4092
                //  Currently hitting crashes in SwS w/ 32-bit Windows so skipping for now
                if (IsWindows() && (param.eglParameters.deviceType ==
                                    EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE))
                {
                    return false;
                }
                break;
    #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;
        }
    
        bool result = false;
    
        auto iter = gParamAvailabilityCache.find(param);
        if (iter != gParamAvailabilityCache.end())
        {
            result = iter->second;
        }
        else
        {
            if (!gSelectedConfig.empty())
            {
                std::stringstream strstr;
                strstr << param;
                if (strstr.str() == gSelectedConfig)
                {
                    result = true;
                }
            }
            else
            {
                const SystemInfo *systemInfo = GetTestSystemInfo();
    
                if (systemInfo)
                {
                    result = IsConfigWhitelisted(*systemInfo, param);
                }
                else
                {
                    result = IsConfigSupported(param);
                }
            }
    
            gParamAvailabilityCache[param] = result;
    
            // Enable this unconditionally to print available platforms.
            if (!gSelectedConfig.empty())
            {
                if (result)
                {
                    std::cout << "Test Config: " << param << "\n";
                }
            }
            else if (!result)
            {
                std::cout << "Skipping tests using configuration " << param
                          << " because it is not available.\n";
            }
        }
    
        // Disable all tests in the parent process when running child processes.
        if (gSeparateProcessPerConfig)
        {
            return false;
        }
        return result;
    }
    
    std::vector<std::string> GetAvailableTestPlatformNames()
    {
        std::vector<std::string> platformNames;
    
        for (const auto &iter : gParamAvailabilityCache)
        {
            if (iter.second)
            {
                std::stringstream strstr;
                strstr << iter.first;
                platformNames.push_back(strstr.str());
            }
        }
    
        // Keep the list sorted.
        std::sort(platformNames.begin(), platformNames.end());
    
        return platformNames;
    }
    }  // namespace angle