Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/gl_tests/FenceSyncTests.cpp
1693 views
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
#include "test_utils/gl_raii.h"
9
10
using namespace angle;
11
12
class FenceNVTest : public ANGLETest
13
{
14
protected:
15
FenceNVTest()
16
{
17
setWindowWidth(128);
18
setWindowHeight(128);
19
setConfigRedBits(8);
20
setConfigGreenBits(8);
21
setConfigBlueBits(8);
22
setConfigAlphaBits(8);
23
setConfigDepthBits(24);
24
}
25
};
26
27
class FenceSyncTest : public ANGLETest
28
{
29
public:
30
static constexpr uint32_t kSize = 1024;
31
32
protected:
33
FenceSyncTest()
34
{
35
setWindowWidth(kSize);
36
setWindowHeight(kSize);
37
setConfigRedBits(8);
38
setConfigGreenBits(8);
39
setConfigBlueBits(8);
40
setConfigAlphaBits(8);
41
setConfigDepthBits(24);
42
}
43
};
44
45
// FenceNV objects should respond false to glIsFenceNV until they've been set
46
TEST_P(FenceNVTest, IsFence)
47
{
48
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));
49
50
GLuint fence = 0;
51
glGenFencesNV(1, &fence);
52
EXPECT_GL_NO_ERROR();
53
54
EXPECT_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_GL_TRUE(glIsFenceNV(fence));
61
EXPECT_GL_NO_ERROR();
62
}
63
64
// Test error cases for all FenceNV functions
65
TEST_P(FenceNVTest, Errors)
66
{
67
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));
68
69
EXPECT_GL_TRUE(glTestFenceNV(10)) << "glTestFenceNV should still return TRUE for an invalid "
70
"fence and generate an INVALID_OPERATION";
71
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
72
73
GLuint fence = 20;
74
75
// glGenFencesNV should generate INVALID_VALUE for a negative n and not write anything to the
76
// fences pointer
77
glGenFencesNV(-1, &fence);
78
EXPECT_GL_ERROR(GL_INVALID_VALUE);
79
EXPECT_EQ(20u, fence);
80
81
// Generate a real fence
82
glGenFencesNV(1, &fence);
83
EXPECT_GL_NO_ERROR();
84
85
EXPECT_GL_TRUE(glTestFenceNV(fence)) << "glTestFenceNV should still return TRUE for a fence "
86
"that is not started and generate an INVALID_OPERATION";
87
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
88
89
// glGetFenceivNV should generate an INVALID_OPERATION for an invalid or unstarted fence and not
90
// modify the params
91
GLint result = 30;
92
glGetFenceivNV(10, GL_FENCE_STATUS_NV, &result);
93
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
94
EXPECT_EQ(30, result);
95
96
glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &result);
97
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
98
EXPECT_EQ(30, result);
99
100
// glSetFenceNV should generate an error for any condition that is not ALL_COMPLETED_NV
101
glSetFenceNV(fence, 0);
102
EXPECT_GL_ERROR(GL_INVALID_ENUM);
103
104
// glSetFenceNV should generate INVALID_OPERATION for an invalid fence
105
glSetFenceNV(10, GL_ALL_COMPLETED_NV);
106
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
107
}
108
109
// Test that basic usage works and doesn't generate errors or crash
110
TEST_P(FenceNVTest, BasicOperations)
111
{
112
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));
113
114
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
115
116
constexpr size_t kFenceCount = 20;
117
GLuint fences[kFenceCount] = {0};
118
glGenFencesNV(static_cast<GLsizei>(ArraySize(fences)), fences);
119
EXPECT_GL_NO_ERROR();
120
121
for (GLuint fence : fences)
122
{
123
glClear(GL_COLOR_BUFFER_BIT);
124
glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
125
}
126
127
// Finish the last fence, all fences before should be marked complete
128
glFinishFenceNV(fences[kFenceCount - 1]);
129
130
for (GLuint fence : fences)
131
{
132
GLint status = 0;
133
glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &status);
134
EXPECT_GL_NO_ERROR();
135
136
// Fence should be complete now that Finish has been called
137
EXPECT_GL_TRUE(status);
138
}
139
140
EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255);
141
}
142
143
// Sync objects should respond true to IsSync after they are created with glFenceSync
144
TEST_P(FenceSyncTest, IsSync)
145
{
146
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
147
EXPECT_GL_NO_ERROR();
148
149
EXPECT_GL_TRUE(glIsSync(sync));
150
EXPECT_GL_FALSE(glIsSync(reinterpret_cast<GLsync>(40)));
151
}
152
153
// Test error cases for all Sync function
154
TEST_P(FenceSyncTest, Errors)
155
{
156
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
157
158
// DeleteSync generates INVALID_VALUE when the sync is not valid
159
glDeleteSync(reinterpret_cast<GLsync>(20));
160
EXPECT_GL_ERROR(GL_INVALID_VALUE);
161
162
// glFenceSync generates GL_INVALID_ENUM if the condition is not GL_SYNC_GPU_COMMANDS_COMPLETE
163
EXPECT_EQ(0, glFenceSync(0, 0));
164
EXPECT_GL_ERROR(GL_INVALID_ENUM);
165
166
// glFenceSync generates GL_INVALID_ENUM if the flags is not 0
167
EXPECT_EQ(0, glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 10));
168
EXPECT_GL_ERROR(GL_INVALID_VALUE);
169
170
// glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if flags contains more
171
// than just GL_SYNC_FLUSH_COMMANDS_BIT
172
EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT | 0x2, 0));
173
EXPECT_GL_ERROR(GL_INVALID_VALUE);
174
175
// glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if the sync object is
176
// not valid
177
EXPECT_GLENUM_EQ(GL_WAIT_FAILED,
178
glClientWaitSync(reinterpret_cast<GLsync>(30), GL_SYNC_FLUSH_COMMANDS_BIT, 0));
179
EXPECT_GL_ERROR(GL_INVALID_VALUE);
180
181
// glWaitSync generates GL_INVALID_VALUE if flags is non-zero
182
glWaitSync(sync, 1, GL_TIMEOUT_IGNORED);
183
EXPECT_GL_ERROR(GL_INVALID_VALUE);
184
185
// glWaitSync generates GL_INVALID_VALUE if GLuint64 is not GL_TIMEOUT_IGNORED
186
glWaitSync(sync, 0, 0);
187
EXPECT_GL_ERROR(GL_INVALID_VALUE);
188
189
// glWaitSync generates GL_INVALID_VALUE if the sync object is not valid
190
glWaitSync(reinterpret_cast<GLsync>(30), 0, GL_TIMEOUT_IGNORED);
191
EXPECT_GL_ERROR(GL_INVALID_VALUE);
192
193
// glGetSynciv generates GL_INVALID_VALUE if bufSize is less than zero, results should be
194
// untouched
195
GLsizei length = 20;
196
GLint value = 30;
197
glGetSynciv(sync, GL_OBJECT_TYPE, -1, &length, &value);
198
EXPECT_GL_ERROR(GL_INVALID_VALUE);
199
EXPECT_EQ(20, length);
200
EXPECT_EQ(30, value);
201
202
// glGetSynciv generates GL_INVALID_VALUE if the sync object is not valid, results should be
203
// 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
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
231
TEST_P(FenceSyncTest, BasicOperations)
232
{
233
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
234
235
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
236
237
glClear(GL_COLOR_BUFFER_BIT);
238
glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
239
EXPECT_GL_NO_ERROR();
240
241
GLsizei length = 0;
242
GLint value = 0;
243
unsigned int loopCount = 0;
244
245
glFlush();
246
247
// Use 'loopCount' to make sure the test doesn't get stuck in an infinite loop
248
while (value != GL_SIGNALED && loopCount <= 1000000)
249
{
250
loopCount++;
251
252
glGetSynciv(sync, GL_SYNC_STATUS, 1, &length, &value);
253
ASSERT_GL_NO_ERROR();
254
}
255
256
ASSERT_GLENUM_EQ(GL_SIGNALED, value);
257
258
for (size_t i = 0; i < 20; i++)
259
{
260
glClear(GL_COLOR_BUFFER_BIT);
261
glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
262
EXPECT_GL_NO_ERROR();
263
}
264
}
265
266
// Test that multiple fences and draws can be issued
267
TEST_P(FenceSyncTest, MultipleFenceDraw)
268
{
269
constexpr int kNumIterations = 10;
270
constexpr int kNumDraws = 5;
271
272
// Create a texture/FBO to draw to
273
GLTexture texture;
274
glBindTexture(GL_TEXTURE_2D, texture.get());
275
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
276
ASSERT_GL_NO_ERROR();
277
GLFramebuffer fbo;
278
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
279
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
280
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
281
282
ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
283
ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
284
285
bool drawGreen = true;
286
for (int numIterations = 0; numIterations < kNumIterations; ++numIterations)
287
{
288
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
289
ASSERT_GL_NO_ERROR();
290
291
for (int i = 0; i < kNumDraws; ++i)
292
{
293
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
294
ASSERT_GL_NO_ERROR();
295
296
drawGreen = !drawGreen;
297
GLuint program = 0;
298
if (drawGreen)
299
{
300
program = greenProgram.get();
301
}
302
else
303
{
304
program = redProgram.get();
305
}
306
drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.0f);
307
ASSERT_GL_NO_ERROR();
308
309
glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
310
EXPECT_GL_NO_ERROR();
311
glDeleteSync(sync);
312
ASSERT_GL_NO_ERROR();
313
}
314
315
// Blit to the default FBO
316
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
317
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
318
glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
319
ASSERT_GL_NO_ERROR();
320
swapBuffers();
321
322
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
323
GLColor color;
324
if (drawGreen)
325
{
326
color = GLColor::green;
327
}
328
else
329
{
330
color = GLColor::red;
331
}
332
EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, color);
333
}
334
}
335
336
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FenceNVTest);
337
338
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FenceSyncTest);
339
ANGLE_INSTANTIATE_TEST_ES3(FenceSyncTest);
340
341