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 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));
45
46 GLuint fence = 0;
47 glGenFencesNV(1, &fence);
48 EXPECT_GL_NO_ERROR();
49
50 EXPECT_GL_FALSE(glIsFenceNV(fence));
51 EXPECT_GL_NO_ERROR();
52
53 glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
54 EXPECT_GL_NO_ERROR();
55
56 EXPECT_GL_TRUE(glIsFenceNV(fence));
57 EXPECT_GL_NO_ERROR();
58 }
59
60 // Test error cases for all FenceNV functions
TEST_P(FenceNVTest,Errors)61 TEST_P(FenceNVTest, Errors)
62 {
63 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));
64
65 EXPECT_GL_TRUE(glTestFenceNV(10)) << "glTestFenceNV should still return TRUE for an invalid "
66 "fence and generate an INVALID_OPERATION";
67 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
68
69 GLuint fence = 20;
70
71 // glGenFencesNV should generate INVALID_VALUE for a negative n and not write anything to the
72 // fences pointer
73 glGenFencesNV(-1, &fence);
74 EXPECT_GL_ERROR(GL_INVALID_VALUE);
75 EXPECT_EQ(20u, fence);
76
77 // Generate a real fence
78 glGenFencesNV(1, &fence);
79 EXPECT_GL_NO_ERROR();
80
81 EXPECT_GL_TRUE(glTestFenceNV(fence)) << "glTestFenceNV should still return TRUE for a fence "
82 "that is not started and generate an INVALID_OPERATION";
83 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
84
85 // glGetFenceivNV should generate an INVALID_OPERATION for an invalid or unstarted fence and not
86 // modify the params
87 GLint result = 30;
88 glGetFenceivNV(10, GL_FENCE_STATUS_NV, &result);
89 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
90 EXPECT_EQ(30, result);
91
92 glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &result);
93 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
94 EXPECT_EQ(30, result);
95
96 // glSetFenceNV should generate an error for any condition that is not ALL_COMPLETED_NV
97 glSetFenceNV(fence, 0);
98 EXPECT_GL_ERROR(GL_INVALID_ENUM);
99
100 // glSetFenceNV should generate INVALID_OPERATION for an invalid fence
101 glSetFenceNV(10, GL_ALL_COMPLETED_NV);
102 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
103 }
104
105 // Test that basic usage works and doesn't generate errors or crash
TEST_P(FenceNVTest,BasicOperations)106 TEST_P(FenceNVTest, BasicOperations)
107 {
108 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));
109
110 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
111
112 constexpr size_t kFenceCount = 20;
113 GLuint fences[kFenceCount] = {0};
114 glGenFencesNV(static_cast<GLsizei>(ArraySize(fences)), fences);
115 EXPECT_GL_NO_ERROR();
116
117 for (GLuint fence : fences)
118 {
119 glClear(GL_COLOR_BUFFER_BIT);
120 glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
121 }
122
123 // Finish the last fence, all fences before should be marked complete
124 glFinishFenceNV(fences[kFenceCount - 1]);
125
126 for (GLuint fence : fences)
127 {
128 GLint status = 0;
129 glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &status);
130 EXPECT_GL_NO_ERROR();
131
132 // Fence should be complete now that Finish has been called
133 EXPECT_GL_TRUE(status);
134 }
135
136 EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255);
137 }
138
139 // Sync objects should respond true to IsSync after they are created with glFenceSync
TEST_P(FenceSyncTest,IsSync)140 TEST_P(FenceSyncTest, IsSync)
141 {
142 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
143 EXPECT_GL_NO_ERROR();
144
145 EXPECT_GL_TRUE(glIsSync(sync));
146 EXPECT_GL_FALSE(glIsSync(reinterpret_cast<GLsync>(40)));
147 }
148
149 // Test error cases for all Sync function
TEST_P(FenceSyncTest,Errors)150 TEST_P(FenceSyncTest, Errors)
151 {
152 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
153
154 // DeleteSync generates INVALID_VALUE when the sync is not valid
155 glDeleteSync(reinterpret_cast<GLsync>(20));
156 EXPECT_GL_ERROR(GL_INVALID_VALUE);
157
158 // glFenceSync generates GL_INVALID_ENUM if the condition is not GL_SYNC_GPU_COMMANDS_COMPLETE
159 EXPECT_EQ(0, glFenceSync(0, 0));
160 EXPECT_GL_ERROR(GL_INVALID_ENUM);
161
162 // glFenceSync generates GL_INVALID_ENUM if the flags is not 0
163 EXPECT_EQ(0, glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 10));
164 EXPECT_GL_ERROR(GL_INVALID_VALUE);
165
166 // glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if flags contains more
167 // than just GL_SYNC_FLUSH_COMMANDS_BIT
168 EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT | 0x2, 0));
169 EXPECT_GL_ERROR(GL_INVALID_VALUE);
170
171 // glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if the sync object is
172 // not valid
173 EXPECT_GLENUM_EQ(GL_WAIT_FAILED,
174 glClientWaitSync(reinterpret_cast<GLsync>(30), GL_SYNC_FLUSH_COMMANDS_BIT, 0));
175 EXPECT_GL_ERROR(GL_INVALID_VALUE);
176
177 // glWaitSync generates GL_INVALID_VALUE if flags is non-zero
178 glWaitSync(sync, 1, GL_TIMEOUT_IGNORED);
179 EXPECT_GL_ERROR(GL_INVALID_VALUE);
180
181 // glWaitSync generates GL_INVALID_VALUE if GLuint64 is not GL_TIMEOUT_IGNORED
182 glWaitSync(sync, 0, 0);
183 EXPECT_GL_ERROR(GL_INVALID_VALUE);
184
185 // glWaitSync generates GL_INVALID_VALUE if the sync object is not valid
186 glWaitSync(reinterpret_cast<GLsync>(30), 0, GL_TIMEOUT_IGNORED);
187 EXPECT_GL_ERROR(GL_INVALID_VALUE);
188
189 // glGetSynciv generates GL_INVALID_VALUE if bufSize is less than zero, results should be
190 // untouched
191 GLsizei length = 20;
192 GLint value = 30;
193 glGetSynciv(sync, GL_OBJECT_TYPE, -1, &length, &value);
194 EXPECT_GL_ERROR(GL_INVALID_VALUE);
195 EXPECT_EQ(20, length);
196 EXPECT_EQ(30, value);
197
198 // glGetSynciv generates GL_INVALID_VALUE if the sync object is not valid, results should be
199 // untouched
200 glGetSynciv(reinterpret_cast<GLsync>(30), GL_OBJECT_TYPE, 1, &length, &value);
201 EXPECT_GL_ERROR(GL_INVALID_VALUE);
202 EXPECT_EQ(20, length);
203 EXPECT_EQ(30, value);
204 }
205
206 // Test usage of glGetSynciv
TEST_P(FenceSyncTest,BasicQueries)207 TEST_P(FenceSyncTest, BasicQueries)
208 {
209 GLsizei length = 0;
210 GLint value = 0;
211 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
212
213 glGetSynciv(sync, GL_SYNC_CONDITION, 1, &length, &value);
214 EXPECT_GL_NO_ERROR();
215 EXPECT_EQ(GL_SYNC_GPU_COMMANDS_COMPLETE, value);
216
217 glGetSynciv(sync, GL_OBJECT_TYPE, 1, &length, &value);
218 EXPECT_GL_NO_ERROR();
219 EXPECT_EQ(GL_SYNC_FENCE, value);
220
221 glGetSynciv(sync, GL_SYNC_FLAGS, 1, &length, &value);
222 EXPECT_GL_NO_ERROR();
223 EXPECT_EQ(0, value);
224 }
225
226 // Test that basic usage works and doesn't generate errors or crash
TEST_P(FenceSyncTest,BasicOperations)227 TEST_P(FenceSyncTest, BasicOperations)
228 {
229 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
230
231 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
232
233 glClear(GL_COLOR_BUFFER_BIT);
234 glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
235 EXPECT_GL_NO_ERROR();
236
237 GLsizei length = 0;
238 GLint value = 0;
239 unsigned int loopCount = 0;
240
241 glFlush();
242
243 // Use 'loopCount' to make sure the test doesn't get stuck in an infinite loop
244 while (value != GL_SIGNALED && loopCount <= 1000000)
245 {
246 loopCount++;
247
248 glGetSynciv(sync, GL_SYNC_STATUS, 1, &length, &value);
249 ASSERT_GL_NO_ERROR();
250 }
251
252 ASSERT_GLENUM_EQ(GL_SIGNALED, value);
253
254 for (size_t i = 0; i < 20; i++)
255 {
256 glClear(GL_COLOR_BUFFER_BIT);
257 glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
258 EXPECT_GL_NO_ERROR();
259 }
260 }
261
262 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
263 // tests should be run against.
264 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FenceNVTest);
265 ANGLE_INSTANTIATE_TEST_ES3(FenceSyncTest);
266