1 //
2 // Copyright 2015 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 // BindGeneratesResourceTest.cpp : Tests of the GL_CHROMIUM_bind_generates_resource extension.
8
9 #include "test_utils/ANGLETest.h"
10
11 namespace angle
12 {
13 class ContextLostTest : public ANGLETest<>
14 {
15 protected:
ContextLostTest()16 ContextLostTest() {}
17
testSetUp()18 void testSetUp() override
19 {
20 if (IsEGLClientExtensionEnabled("EGL_EXT_create_context_robustness"))
21 {
22 setContextResetStrategy(EGL_LOSE_CONTEXT_ON_RESET_EXT);
23 }
24 else
25 {
26 setContextResetStrategy(EGL_NO_RESET_NOTIFICATION_EXT);
27 }
28 }
29 };
30
31 // GL_CHROMIUM_lose_context is implemented in the frontend
TEST_P(ContextLostTest,ExtensionStringExposed)32 TEST_P(ContextLostTest, ExtensionStringExposed)
33 {
34 EXPECT_TRUE(EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
35 }
36
37 // Use GL_CHROMIUM_lose_context to lose a context and verify using GL_EXT_robustness
TEST_P(ContextLostTest,BasicUsageEXT)38 TEST_P(ContextLostTest, BasicUsageEXT)
39 {
40 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
41 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_robustness") ||
42 !IsEGLClientExtensionEnabled("EGL_EXT_create_context_robustness"));
43
44 glLoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET, GL_INNOCENT_CONTEXT_RESET);
45 EXPECT_GL_NO_ERROR();
46 EXPECT_GLENUM_EQ(glGetGraphicsResetStatusEXT(), GL_GUILTY_CONTEXT_RESET);
47
48 // Errors should be continually generated
49 for (size_t i = 0; i < 10; i++)
50 {
51 glBindTexture(GL_TEXTURE_2D, 0);
52 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
53 }
54 }
55
56 // Use GL_CHROMIUM_lose_context to lose a context and verify using GL_KHR_robustness
TEST_P(ContextLostTest,BasicUsageKHR)57 TEST_P(ContextLostTest, BasicUsageKHR)
58 {
59 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
60 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_KHR_robustness") ||
61 !IsEGLClientExtensionEnabled("EGL_EXT_create_context_robustness"));
62
63 glLoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET, GL_INNOCENT_CONTEXT_RESET);
64 EXPECT_GL_NO_ERROR();
65 EXPECT_GLENUM_EQ(glGetGraphicsResetStatusKHR(), GL_GUILTY_CONTEXT_RESET);
66
67 // Errors should be continually generated
68 for (size_t i = 0; i < 10; i++)
69 {
70 glBindTexture(GL_TEXTURE_2D, 0);
71 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
72 }
73 }
74
75 // When context is lost, polling queries such as glGetSynciv with GL_SYNC_STATUS should always
76 // return GL_SIGNALED
TEST_P(ContextLostTest,PollingQuery)77 TEST_P(ContextLostTest, PollingQuery)
78 {
79 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
80 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
81
82 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
83 EXPECT_GL_NO_ERROR();
84
85 glLoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET, GL_INNOCENT_CONTEXT_RESET);
86 EXPECT_GL_NO_ERROR();
87
88 GLint syncStatus = 0;
89 glGetSynciv(sync, GL_SYNC_STATUS, 1, nullptr, &syncStatus);
90 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
91 EXPECT_GLENUM_EQ(syncStatus, GL_SIGNALED);
92
93 // Check that the query fails and the result is unmodified for other queries
94 GLint syncCondition = 0xBADF00D;
95 glGetSynciv(sync, GL_SYNC_CONDITION, 1, nullptr, &syncCondition);
96 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
97 EXPECT_GLENUM_EQ(syncCondition, 0xBADF00D);
98 }
99
100 // When context is lost, polling queries such as glGetSynciv with GL_SYNC_STATUS should always
101 // return GL_SIGNALED
TEST_P(ContextLostTest,ParallelCompileReadyQuery)102 TEST_P(ContextLostTest, ParallelCompileReadyQuery)
103 {
104 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
105 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_KHR_parallel_shader_compile"));
106
107 GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple());
108 GLuint fs = CompileShader(GL_FRAGMENT_SHADER, essl1_shaders::fs::UniformColor());
109
110 GLuint program = glCreateProgram();
111 glAttachShader(program, vs);
112 glAttachShader(program, fs);
113 glLinkProgram(program);
114
115 EXPECT_GL_NO_ERROR();
116
117 glLoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET, GL_INNOCENT_CONTEXT_RESET);
118 EXPECT_GL_NO_ERROR();
119
120 GLint shaderCompletionStatus = 0;
121 glGetShaderiv(vs, GL_COMPLETION_STATUS_KHR, &shaderCompletionStatus);
122 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
123 EXPECT_GLENUM_EQ(shaderCompletionStatus, GL_TRUE);
124
125 GLint programCompletionStatus = 0;
126 glGetProgramiv(program, GL_COMPLETION_STATUS_KHR, &programCompletionStatus);
127 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
128 EXPECT_GLENUM_EQ(programCompletionStatus, GL_TRUE);
129
130 // Check that the query fails and the result is unmodified for other queries
131 GLint shaderType = 0xBADF00D;
132 glGetShaderiv(vs, GL_SHADER_TYPE, &shaderType);
133 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
134 EXPECT_GLENUM_EQ(shaderType, 0xBADF00D);
135
136 GLint linkStatus = 0xBADF00D;
137 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
138 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
139 EXPECT_GLENUM_EQ(linkStatus, 0xBADF00D);
140 }
141
142 class ContextLostTestES32 : public ContextLostTest
143 {};
144
145 // Use GL_CHROMIUM_lose_context to lose a context and verify using GLES 3.2 function
TEST_P(ContextLostTestES32,BasicUsage)146 TEST_P(ContextLostTestES32, BasicUsage)
147 {
148 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
149 ANGLE_SKIP_TEST_IF(!IsEGLClientExtensionEnabled("EGL_EXT_create_context_robustness"));
150
151 glLoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET, GL_INNOCENT_CONTEXT_RESET);
152 EXPECT_GL_NO_ERROR();
153 EXPECT_GLENUM_EQ(glGetGraphicsResetStatus(), GL_GUILTY_CONTEXT_RESET);
154
155 // Errors should be continually generated
156 for (size_t i = 0; i < 10; i++)
157 {
158 glBindTexture(GL_TEXTURE_2D, 0);
159 EXPECT_GL_ERROR(GL_CONTEXT_LOST);
160 }
161 }
162
163 class ContextLostSkipValidationTest : public ANGLETest<>
164 {
165 protected:
ContextLostSkipValidationTest()166 ContextLostSkipValidationTest() {}
167
testSetUp()168 void testSetUp() override
169 {
170 if (IsEGLClientExtensionEnabled("EGL_EXT_create_context_robustness"))
171 {
172 setContextResetStrategy(EGL_LOSE_CONTEXT_ON_RESET_EXT);
173 setNoErrorEnabled(true);
174 }
175 else
176 {
177 setContextResetStrategy(EGL_NO_RESET_NOTIFICATION_EXT);
178 }
179 }
180 };
181
182 // Use GL_CHROMIUM_lose_context to lose a context and verify
TEST_P(ContextLostSkipValidationTest,LostNoErrorGetProgram)183 TEST_P(ContextLostSkipValidationTest, LostNoErrorGetProgram)
184 {
185 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
186
187 GLuint program = glCreateProgram();
188
189 glLoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET, GL_INNOCENT_CONTEXT_RESET);
190
191 GLint val = 0;
192 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &val); // Should not crash.
193 }
194
195 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
196 // tests should be run against.
197 ANGLE_INSTANTIATE_TEST(ContextLostTest,
198 WithRobustness(ES2_NULL()),
199 WithRobustness(ES2_D3D9()),
200 WithRobustness(ES2_D3D11()),
201 WithRobustness(ES3_D3D11()),
202 WithRobustness(ES2_VULKAN()),
203 WithRobustness(ES3_VULKAN()));
204
205 ANGLE_INSTANTIATE_TEST(ContextLostSkipValidationTest,
206 WithRobustness(ES2_NULL()),
207 WithRobustness(ES2_D3D9()),
208 WithRobustness(ES2_D3D11()),
209 WithRobustness(ES3_D3D11()),
210 WithRobustness(ES2_VULKAN()),
211 WithRobustness(ES3_VULKAN()));
212
213 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContextLostTestES32);
214 ANGLE_INSTANTIATE_TEST(ContextLostTestES32, WithRobustness(ES32_VULKAN()));
215
216 } // namespace angle
217