Path: blob/main_old/src/tests/egl_tests/EGLRobustnessTest.cpp
1693 views
//1// Copyright 2016 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// EGLRobustnessTest.cpp: tests for EGL_EXT_create_context_robustness7//8// Tests causing GPU resets are disabled, use the following args to run them:9// --gtest_also_run_disabled_tests --gtest_filter=EGLRobustnessTest\*1011#include <gtest/gtest.h>1213#include "test_utils/ANGLETest.h"14#include "util/OSWindow.h"1516using namespace angle;1718class EGLRobustnessTest : public ANGLETest19{20public:21void testSetUp() override22{23mOSWindow = OSWindow::New();24mOSWindow->initialize("EGLRobustnessTest", 500, 500);25setWindowVisible(mOSWindow, true);2627const auto &platform = GetParam().eglParameters;2829std::vector<EGLint> displayAttributes;30displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);31displayAttributes.push_back(platform.renderer);32displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);33displayAttributes.push_back(platform.majorVersion);34displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);35displayAttributes.push_back(platform.minorVersion);3637if (platform.deviceType != EGL_DONT_CARE)38{39displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);40displayAttributes.push_back(platform.deviceType);41}4243displayAttributes.push_back(EGL_NONE);4445mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,46reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),47&displayAttributes[0]);48ASSERT_NE(EGL_NO_DISPLAY, mDisplay);4950ASSERT_TRUE(eglInitialize(mDisplay, nullptr, nullptr) == EGL_TRUE);5152const char *extensions = eglQueryString(mDisplay, EGL_EXTENSIONS);53if (strstr(extensions, "EGL_EXT_create_context_robustness") == nullptr)54{55std::cout << "Test skipped due to missing EGL_EXT_create_context_robustness"56<< std::endl;57return;58}5960int nConfigs = 0;61ASSERT_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs) == EGL_TRUE);62ASSERT_LE(1, nConfigs);6364std::vector<EGLConfig> allConfigs(nConfigs);65int nReturnedConfigs = 0;66ASSERT_TRUE(eglGetConfigs(mDisplay, allConfigs.data(), nConfigs, &nReturnedConfigs) ==67EGL_TRUE);68ASSERT_EQ(nConfigs, nReturnedConfigs);6970for (const EGLConfig &config : allConfigs)71{72EGLint surfaceType;73eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);7475if ((surfaceType & EGL_WINDOW_BIT) != 0)76{77mConfig = config;78mInitialized = true;79break;80}81}8283if (mInitialized)84{85mWindow =86eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), nullptr);87ASSERT_EGL_SUCCESS();88}89}9091void testTearDown() override92{93eglDestroySurface(mDisplay, mWindow);94eglDestroyContext(mDisplay, mContext);95eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);96eglTerminate(mDisplay);97EXPECT_EGL_SUCCESS();9899OSWindow::Delete(&mOSWindow);100}101102void createContext(EGLint resetStrategy)103{104const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2,105EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,106resetStrategy, EGL_NONE};107mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, contextAttribs);108ASSERT_NE(EGL_NO_CONTEXT, mContext);109110eglMakeCurrent(mDisplay, mWindow, mWindow, mContext);111ASSERT_EGL_SUCCESS();112113const char *extensionString = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));114ASSERT_NE(nullptr, strstr(extensionString, "GL_ANGLE_instanced_arrays"));115}116117void forceContextReset()118{119// Cause a GPU reset by drawing 100,000,000 fullscreen quads120GLuint program = CompileProgram(121"attribute vec4 pos;\n"122"void main() {gl_Position = pos;}\n",123"precision mediump float;\n"124"void main() {gl_FragColor = vec4(1.0);}\n");125ASSERT_NE(0u, program);126glUseProgram(program);127128GLfloat vertices[] = {129-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,1301.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,131};132133const int kNumQuads = 10000;134std::vector<GLushort> indices(6 * kNumQuads);135136for (size_t i = 0; i < kNumQuads; i++)137{138indices[i * 6 + 0] = 0;139indices[i * 6 + 1] = 1;140indices[i * 6 + 2] = 2;141indices[i * 6 + 3] = 1;142indices[i * 6 + 4] = 2;143indices[i * 6 + 5] = 3;144}145146glBindAttribLocation(program, 0, "pos");147glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, vertices);148glEnableVertexAttribArray(0);149150glViewport(0, 0, mOSWindow->getWidth(), mOSWindow->getHeight());151glClearColor(1.0, 0.0, 0.0, 1.0);152glClear(GL_COLOR_BUFFER_BIT);153glDrawElementsInstancedANGLE(GL_TRIANGLES, kNumQuads * 6, GL_UNSIGNED_SHORT, indices.data(),15410000);155156glFinish();157}158159protected:160EGLDisplay mDisplay = EGL_NO_DISPLAY;161EGLSurface mWindow = EGL_NO_SURFACE;162bool mInitialized = false;163164private:165EGLContext mContext = EGL_NO_CONTEXT;166EGLConfig mConfig = 0;167OSWindow *mOSWindow = nullptr;168};169170// Check glGetGraphicsResetStatusEXT returns GL_NO_ERROR if we did nothing171TEST_P(EGLRobustnessTest, NoErrorByDefault)172{173ANGLE_SKIP_TEST_IF(!mInitialized);174ASSERT_TRUE(glGetGraphicsResetStatusEXT() == GL_NO_ERROR);175}176177// Checks that the application gets no loss with NO_RESET_NOTIFICATION178TEST_P(EGLRobustnessTest, DISABLED_NoResetNotification)179{180ANGLE_SKIP_TEST_IF(!mInitialized);181createContext(EGL_NO_RESET_NOTIFICATION_EXT);182183if (!IsWindows())184{185std::cout << "Test disabled on non Windows platforms because drivers can't recover. "186<< "See " << __FILE__ << ":" << __LINE__ << std::endl;187return;188}189std::cout << "Causing a GPU reset, brace for impact." << std::endl;190191forceContextReset();192ASSERT_TRUE(glGetGraphicsResetStatusEXT() == GL_NO_ERROR);193}194195// Checks that resetting the ANGLE display allows to get rid of the context loss.196// Also checks that the application gets notified of the loss of the display.197// We coalesce both tests to reduce the number of TDRs done on Windows: by default198// having more than 5 TDRs in a minute will cause Windows to disable the GPU until199// the computer is rebooted.200TEST_P(EGLRobustnessTest, DISABLED_ResettingDisplayWorks)201{202// Note that on Windows the OpenGL driver fails hard (popup that closes the application)203// on a TDR caused by D3D. Don't run D3D tests at the same time as the OpenGL tests.204ANGLE_SKIP_TEST_IF(IsWindows() && isGLRenderer());205ANGLE_SKIP_TEST_IF(!mInitialized);206207createContext(EGL_LOSE_CONTEXT_ON_RESET_EXT);208209if (!IsWindows())210{211std::cout << "Test disabled on non Windows platforms because drivers can't recover. "212<< "See " << __FILE__ << ":" << __LINE__ << std::endl;213return;214}215std::cout << "Causing a GPU reset, brace for impact." << std::endl;216217forceContextReset();218ASSERT_TRUE(glGetGraphicsResetStatusEXT() != GL_NO_ERROR);219220recreateTestFixture();221ASSERT_TRUE(glGetGraphicsResetStatusEXT() == GL_NO_ERROR);222}223224GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLRobustnessTest);225ANGLE_INSTANTIATE_TEST(EGLRobustnessTest,226WithNoFixture(ES2_VULKAN()),227WithNoFixture(ES2_D3D9()),228WithNoFixture(ES2_D3D11()),229WithNoFixture(ES2_OPENGL()));230231232