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 #include "test_utils/ANGLETest.h"
8
9 using namespace angle;
10
11 class FenceNVTest : public ANGLETest
12 {
13 protected:
FenceNVTest()14 FenceNVTest()
15 {
16 setWindowWidth(128);
17 setWindowHeight(128);
18 setConfigRedBits(8);
19 setConfigGreenBits(8);
20 setConfigBlueBits(8);
21 setConfigAlphaBits(8);
22 setConfigDepthBits(24);
23 }
24 };
25
26 class FenceSyncTest : public ANGLETest
27 {
28 protected:
FenceSyncTest()29 FenceSyncTest()
30 {
31 setWindowWidth(128);
32 setWindowHeight(128);
33 setConfigRedBits(8);
34 setConfigGreenBits(8);
35 setConfigBlueBits(8);
36 setConfigAlphaBits(8);
37 setConfigDepthBits(24);
38 }
39 };
40
41 // FenceNV objects should respond false to glIsFenceNV until they've been set
TEST_P(FenceNVTest,IsFence)42 TEST_P(FenceNVTest, IsFence)
43 {
44 if (!extensionEnabled("GL_NV_fence"))
45 {
46 std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl;
47 return;
48 }
49
50 GLuint fence = 0;
51 glGenFencesNV(1, &fence);
52 EXPECT_GL_NO_ERROR();
53
54 EXPECT_EQ(GL_FALSE, glIsFenceNV(fence));
55 EXPECT_GL_NO_ERROR();
56
57 glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
58 EXPECT_GL_NO_ERROR();
59
60 EXPECT_EQ(GL_TRUE, glIsFenceNV(fence));
61 EXPECT_GL_NO_ERROR();
62 }
63
64 // Test error cases for all FenceNV functions
TEST_P(FenceNVTest,Errors)65 TEST_P(FenceNVTest, Errors)
66 {
67 if (!extensionEnabled("GL_NV_fence"))
68 {
69 std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl;
70 return;
71 }
72
73 // glTestFenceNV should still return TRUE for an invalid fence and generate an INVALID_OPERATION
74 EXPECT_EQ(GL_TRUE, glTestFenceNV(10));
75 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
76
77 GLuint fence = 20;
78
79 // glGenFencesNV should generate INVALID_VALUE for a negative n and not write anything to the fences pointer
80 glGenFencesNV(-1, &fence);
81 EXPECT_GL_ERROR(GL_INVALID_VALUE);
82 EXPECT_EQ(20u, fence);
83
84 // Generate a real fence
85 glGenFencesNV(1, &fence);
86 EXPECT_GL_NO_ERROR();
87
88 // glTestFenceNV should still return TRUE for a fence that is not started and generate an INVALID_OPERATION
89 EXPECT_EQ(GL_TRUE, glTestFenceNV(fence));
90 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
91
92 // glGetFenceivNV should generate an INVALID_OPERATION for an invalid or unstarted fence and not modify the params
93 GLint result = 30;
94 glGetFenceivNV(10, GL_FENCE_STATUS_NV, &result);
95 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
96 EXPECT_EQ(30, result);
97
98 glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &result);
99 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
100 EXPECT_EQ(30, result);
101
102 // glSetFenceNV should generate an error for any condition that is not ALL_COMPLETED_NV
103 glSetFenceNV(fence, 0);
104 EXPECT_GL_ERROR(GL_INVALID_ENUM);
105
106 // glSetFenceNV should generate INVALID_OPERATION for an invalid fence
107 glSetFenceNV(10, GL_ALL_COMPLETED_NV);
108 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
109 }
110
111 // Test that basic usage works and doesn't generate errors or crash
TEST_P(FenceNVTest,BasicOperations)112 TEST_P(FenceNVTest, BasicOperations)
113 {
114 if (!extensionEnabled("GL_NV_fence"))
115 {
116 std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl;
117 return;
118 }
119
120 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
121
122 GLuint fences[20] = { 0 };
123 glGenFencesNV(static_cast<GLsizei>(ArraySize(fences)), fences);
124 EXPECT_GL_NO_ERROR();
125
126 for (GLuint fence : fences)
127 {
128 glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
129
130 glClear(GL_COLOR_BUFFER_BIT);
131 }
132
133 glFinish();
134
135 for (GLuint fence : fences)
136 {
137 GLint status = 0;
138 glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &status);
139 EXPECT_GL_NO_ERROR();
140
141 // Fence should be complete now that Finish has been called
142 EXPECT_EQ(GL_TRUE, status);
143 }
144
145 EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255);
146 }
147
148 // FenceSync objects should respond true to IsSync after they are created with glFenceSync
TEST_P(FenceSyncTest,IsSync)149 TEST_P(FenceSyncTest, IsSync)
150 {
151 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
152 EXPECT_GL_NO_ERROR();
153
154 EXPECT_EQ(GL_TRUE, glIsSync(sync));
155 EXPECT_EQ(GL_FALSE, glIsSync(reinterpret_cast<GLsync>(40)));
156 }
157
158 // Test error cases for all FenceSync function
TEST_P(FenceSyncTest,Errors)159 TEST_P(FenceSyncTest, Errors)
160 {
161 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
162
163 // DeleteSync generates INVALID_VALUE when the sync is not valid
164 glDeleteSync(reinterpret_cast<GLsync>(20));
165 EXPECT_GL_ERROR(GL_INVALID_VALUE);
166
167 // glFenceSync generates GL_INVALID_ENUM if the condition is not GL_SYNC_GPU_COMMANDS_COMPLETE
168 EXPECT_EQ(0, glFenceSync(0, 0));
169 EXPECT_GL_ERROR(GL_INVALID_ENUM);
170
171 // glFenceSync generates GL_INVALID_ENUM if the flags is not 0
172 EXPECT_EQ(0, glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 10));
173 EXPECT_GL_ERROR(GL_INVALID_VALUE);
174
175 // glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if flags contains more than just GL_SYNC_FLUSH_COMMANDS_BIT
176 EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT | 0x2, 0));
177 EXPECT_GL_ERROR(GL_INVALID_VALUE);
178
179 // glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if the sync object is not valid
180 EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(reinterpret_cast<GLsync>(30), GL_SYNC_FLUSH_COMMANDS_BIT, 0));
181 EXPECT_GL_ERROR(GL_INVALID_VALUE);
182
183 // glWaitSync generates GL_INVALID_VALUE if flags is non-zero
184 glWaitSync(sync, 1, GL_TIMEOUT_IGNORED);
185 EXPECT_GL_ERROR(GL_INVALID_VALUE);
186
187 // glWaitSync generates GL_INVALID_VALUE if GLuint64 is not GL_TIMEOUT_IGNORED
188 glWaitSync(sync, 0, 0);
189 EXPECT_GL_ERROR(GL_INVALID_VALUE);
190
191 // glWaitSync generates GL_INVALID_VALUE if the sync object is not valid
192 glWaitSync(reinterpret_cast<GLsync>(30), 0, GL_TIMEOUT_IGNORED);
193 EXPECT_GL_ERROR(GL_INVALID_VALUE);
194
195 // glGetSynciv generates GL_INVALID_VALUE if bufSize is less than zero, results should be untouched
196 GLsizei length = 20;
197 GLint value = 30;
198 glGetSynciv(sync, GL_OBJECT_TYPE, -1, &length, &value);
199 EXPECT_GL_ERROR(GL_INVALID_VALUE);
200 EXPECT_EQ(20, length);
201 EXPECT_EQ(30, value);
202
203 // glGetSynciv generates GL_INVALID_VALUE if the sync object tis not valid, results should be untouched
204 glGetSynciv(reinterpret_cast<GLsync>(30), GL_OBJECT_TYPE, 1, &length, &value);
205 EXPECT_GL_ERROR(GL_INVALID_VALUE);
206 EXPECT_EQ(20, length);
207 EXPECT_EQ(30, value);
208 }
209
210 // Test usage of glGetSynciv
TEST_P(FenceSyncTest,BasicQueries)211 TEST_P(FenceSyncTest, BasicQueries)
212 {
213 GLsizei length = 0;
214 GLint value = 0;
215 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
216
217 glGetSynciv(sync, GL_SYNC_CONDITION, 1, &length, &value);
218 EXPECT_GL_NO_ERROR();
219 EXPECT_EQ(GL_SYNC_GPU_COMMANDS_COMPLETE, value);
220
221 glGetSynciv(sync, GL_OBJECT_TYPE, 1, &length, &value);
222 EXPECT_GL_NO_ERROR();
223 EXPECT_EQ(GL_SYNC_FENCE, value);
224
225 glGetSynciv(sync, GL_SYNC_FLAGS, 1, &length, &value);
226 EXPECT_GL_NO_ERROR();
227 EXPECT_EQ(0, value);
228 }
229
230 // Test that basic usage works and doesn't generate errors or crash
TEST_P(FenceSyncTest,BasicOperations)231 TEST_P(FenceSyncTest, BasicOperations)
232 {
233 // TODO(geofflang): Figure out why this is broken on Intel OpenGL
234 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
235 {
236 std::cout << "Test skipped on Intel OpenGL." << std::endl;
237 return;
238 }
239
240 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
241
242 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
243
244 glClear(GL_COLOR_BUFFER_BIT);
245 glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
246 EXPECT_GL_NO_ERROR();
247
248 GLsizei length = 0;
249 GLint value = 0;
250 unsigned int loopCount = 0;
251
252 glFlush();
253
254 // Use 'loopCount' to make sure the test doesn't get stuck in an infinite loop
255 while (value != GL_SIGNALED && loopCount <= 1000000)
256 {
257 loopCount++;
258
259 glGetSynciv(sync, GL_SYNC_STATUS, 1, &length, &value);
260 ASSERT_GL_NO_ERROR();
261 }
262
263 ASSERT_GLENUM_EQ(GL_SIGNALED, value);
264
265 for (size_t i = 0; i < 20; i++)
266 {
267 glClear(GL_COLOR_BUFFER_BIT);
268 glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
269 EXPECT_GL_NO_ERROR();
270 }
271 }
272
273 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
274 ANGLE_INSTANTIATE_TEST(FenceNVTest,
275 ES2_D3D9(),
276 ES2_D3D11(),
277 ES3_D3D11(),
278 ES2_OPENGL(),
279 ES3_OPENGL(),
280 ES2_OPENGLES(),
281 ES3_OPENGLES());
282 ANGLE_INSTANTIATE_TEST(FenceSyncTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
283