• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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