Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/gl_tests/AtomicCounterBufferTest.cpp
1693 views
1
//
2
// Copyright 2017 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
// AtomicCounterBufferTest:
7
// Various tests related for atomic counter buffers.
8
//
9
10
#include "test_utils/ANGLETest.h"
11
#include "test_utils/gl_raii.h"
12
13
using namespace angle;
14
15
namespace
16
{
17
18
class AtomicCounterBufferTest : public ANGLETest
19
{
20
protected:
21
AtomicCounterBufferTest()
22
{
23
setWindowWidth(128);
24
setWindowHeight(128);
25
setConfigRedBits(8);
26
setConfigGreenBits(8);
27
setConfigBlueBits(8);
28
setConfigAlphaBits(8);
29
}
30
};
31
32
// Test GL_ATOMIC_COUNTER_BUFFER is not supported with version lower than ES31.
33
TEST_P(AtomicCounterBufferTest, AtomicCounterBufferBindings)
34
{
35
ASSERT_EQ(3, getClientMajorVersion());
36
GLBuffer atomicCounterBuffer;
37
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer.get());
38
if (getClientMinorVersion() < 1)
39
{
40
EXPECT_GL_ERROR(GL_INVALID_ENUM);
41
}
42
else
43
{
44
EXPECT_GL_NO_ERROR();
45
}
46
}
47
48
class AtomicCounterBufferTest31 : public AtomicCounterBufferTest
49
{};
50
51
// Linking should fail if counters in vertex shader exceed gl_MaxVertexAtomicCounters.
52
TEST_P(AtomicCounterBufferTest31, ExceedMaxVertexAtomicCounters)
53
{
54
constexpr char kVS[] =
55
"#version 310 es\n"
56
"layout(binding = 0) uniform atomic_uint foo[gl_MaxVertexAtomicCounters + 1];\n"
57
"void main()\n"
58
"{\n"
59
" atomicCounterIncrement(foo[0]);\n"
60
"}\n";
61
constexpr char kFS[] =
62
"#version 310 es\n"
63
"void main()\n"
64
"{\n"
65
"}\n";
66
67
GLuint program = CompileProgram(kVS, kFS);
68
EXPECT_EQ(0u, program);
69
}
70
71
// Counters matching across shader stages should fail if offsets aren't all specified.
72
// GLSL ES Spec 3.10.4, section 9.2.1.
73
TEST_P(AtomicCounterBufferTest31, OffsetNotAllSpecified)
74
{
75
constexpr char kVS[] =
76
"#version 310 es\n"
77
"layout(binding = 0, offset = 4) uniform atomic_uint foo;\n"
78
"void main()\n"
79
"{\n"
80
" atomicCounterIncrement(foo);\n"
81
"}\n";
82
constexpr char kFS[] =
83
"#version 310 es\n"
84
"layout(binding = 0) uniform atomic_uint foo;\n"
85
"void main()\n"
86
"{\n"
87
"}\n";
88
89
GLuint program = CompileProgram(kVS, kFS);
90
EXPECT_EQ(0u, program);
91
}
92
93
// Counters matching across shader stages should fail if offsets aren't all specified with same
94
// value.
95
TEST_P(AtomicCounterBufferTest31, OffsetNotAllSpecifiedWithSameValue)
96
{
97
constexpr char kVS[] =
98
"#version 310 es\n"
99
"layout(binding = 0, offset = 4) uniform atomic_uint foo;\n"
100
"void main()\n"
101
"{\n"
102
" atomicCounterIncrement(foo);\n"
103
"}\n";
104
constexpr char kFS[] =
105
"#version 310 es\n"
106
"layout(binding = 0, offset = 8) uniform atomic_uint foo;\n"
107
"void main()\n"
108
"{\n"
109
"}\n";
110
111
GLuint program = CompileProgram(kVS, kFS);
112
EXPECT_EQ(0u, program);
113
}
114
115
// Tests atomic counter reads using compute shaders. Used as a confidence check for the translator.
116
TEST_P(AtomicCounterBufferTest31, AtomicCounterReadCompute)
117
{
118
// Skipping due to a bug on the Adreno OpenGLES Android driver.
119
// http://anglebug.com/2925
120
ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
121
122
constexpr char kComputeShaderSource[] = R"(#version 310 es
123
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
124
125
void atomicCounterInFunction(in atomic_uint counter[3]);
126
127
layout(binding = 0, offset = 8) uniform atomic_uint ac[3];
128
129
void atomicCounterInFunction(in atomic_uint counter[3])
130
{
131
atomicCounter(counter[0]);
132
}
133
134
void main()
135
{
136
atomicCounterInFunction(ac);
137
atomicCounter(ac[gl_LocalInvocationIndex + 1u]);
138
})";
139
140
ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
141
EXPECT_GL_NO_ERROR();
142
}
143
144
// Test atomic counter read.
145
TEST_P(AtomicCounterBufferTest31, AtomicCounterRead)
146
{
147
// Skipping test while we work on enabling atomic counter buffer support in th D3D renderer.
148
// http://anglebug.com/1729
149
ANGLE_SKIP_TEST_IF(IsD3D11());
150
151
constexpr char kFS[] =
152
"#version 310 es\n"
153
"precision highp float;\n"
154
"layout(binding = 0, offset = 4) uniform atomic_uint ac;\n"
155
"out highp vec4 my_color;\n"
156
"void main()\n"
157
"{\n"
158
" my_color = vec4(0.0);\n"
159
" uint a1 = atomicCounter(ac);\n"
160
" if (a1 == 3u) my_color = vec4(1.0);\n"
161
"}\n";
162
163
ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
164
165
glUseProgram(program.get());
166
167
// The initial value of counter 'ac' is 3u.
168
unsigned int bufferData[3] = {11u, 3u, 1u};
169
GLBuffer atomicCounterBuffer;
170
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
171
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
172
173
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
174
175
drawQuad(program.get(), essl31_shaders::PositionAttrib(), 0.0f);
176
ASSERT_GL_NO_ERROR();
177
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
178
}
179
180
// Test a bug in vulkan back-end where recreating the atomic counter storage should trigger state
181
// update in the context
182
TEST_P(AtomicCounterBufferTest31, DependentAtomicCounterBufferChange)
183
{
184
// Skipping test while we work on enabling atomic counter buffer support in th D3D renderer.
185
// http://anglebug.com/1729
186
ANGLE_SKIP_TEST_IF(IsD3D11());
187
188
constexpr char kFS[] =
189
"#version 310 es\n"
190
"precision highp float;\n"
191
"layout(binding = 0, offset = 4) uniform atomic_uint ac;\n"
192
"out highp vec4 my_color;\n"
193
"void main()\n"
194
"{\n"
195
" my_color = vec4(0.0);\n"
196
" uint a1 = atomicCounter(ac);\n"
197
" if (a1 == 3u) my_color = vec4(1.0);\n"
198
" if (a1 == 19u) my_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
199
"}\n";
200
201
ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
202
203
glUseProgram(program.get());
204
205
// The initial value of counter 'ac' is 3u.
206
unsigned int bufferDataLeft[3] = {11u, 3u, 1u};
207
GLBuffer atomicCounterBuffer;
208
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
209
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferDataLeft), bufferDataLeft, GL_STATIC_DRAW);
210
211
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
212
// Draw left quad
213
glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
214
drawQuad(program.get(), essl31_shaders::PositionAttrib(), 0.0f);
215
// Draw right quad
216
unsigned int bufferDataRight[3] = {11u, 19u, 1u};
217
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferDataRight), bufferDataRight,
218
GL_STATIC_DRAW);
219
glViewport(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
220
drawQuad(program.get(), essl31_shaders::PositionAttrib(), 0.0f);
221
ASSERT_GL_NO_ERROR();
222
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
223
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, 0, GLColor::red);
224
}
225
226
// Updating atomic counter buffer's offsets was optimized based on a count of valid bindings.
227
// This test will fail if there are bugs in how we count valid bindings.
228
TEST_P(AtomicCounterBufferTest31, AtomicCounterBufferRangeRead)
229
{
230
// Skipping due to a bug on the Qualcomm driver.
231
// http://anglebug.com/3726
232
ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
233
234
// Skipping test while we work on enabling atomic counter buffer support in th D3D renderer.
235
// http://anglebug.com/1729
236
ANGLE_SKIP_TEST_IF(IsD3D11());
237
238
constexpr char kFS[] =
239
"#version 310 es\n"
240
"precision highp float;\n"
241
"layout(binding = 0, offset = 4) uniform atomic_uint ac;\n"
242
"out highp vec4 my_color;\n"
243
"void main()\n"
244
"{\n"
245
" my_color = vec4(0.0);\n"
246
" uint a1 = atomicCounter(ac);\n"
247
" if (a1 == 3u) my_color = vec4(1.0);\n"
248
"}\n";
249
250
ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
251
252
glUseProgram(program.get());
253
254
// The initial value of counter 'ac' is 3u.
255
unsigned int bufferData[] = {0u, 0u, 0u, 0u, 0u, 11u, 3u, 1u};
256
constexpr GLintptr kOffset = 20;
257
GLint maxAtomicCounterBuffers = 0;
258
GLBuffer atomicCounterBuffer;
259
260
glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &maxAtomicCounterBuffers);
261
// Repeatedly bind the same buffer (GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS + 1) times
262
// A bug in counting valid atomic counter buffers will cause a crash when we
263
// exceed GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS
264
for (int32_t i = 0; i < maxAtomicCounterBuffers + 1; i++)
265
{
266
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
267
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
268
glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer, kOffset,
269
sizeof(bufferData) - kOffset);
270
}
271
272
drawQuad(program.get(), essl31_shaders::PositionAttrib(), 0.0f);
273
ASSERT_GL_NO_ERROR();
274
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
275
}
276
277
// Updating atomic counter buffer's offsets was optimized based on a count of valid bindings.
278
// Repeatedly bind/unbind buffers across available binding points. The test will fail if
279
// there are bugs in how we count valid bindings.
280
TEST_P(AtomicCounterBufferTest31, AtomicCounterBufferRepeatedBindUnbind)
281
{
282
// Skipping test while we work on enabling atomic counter buffer support in th D3D renderer.
283
// http://anglebug.com/1729
284
ANGLE_SKIP_TEST_IF(IsD3D11());
285
286
constexpr char kFS[] =
287
"#version 310 es\n"
288
"precision highp float;\n"
289
"layout(binding = 0, offset = 4) uniform atomic_uint ac;\n"
290
"out highp vec4 my_color;\n"
291
"void main()\n"
292
"{\n"
293
" my_color = vec4(0.0);\n"
294
" uint a1 = atomicCounter(ac);\n"
295
" if (a1 == 3u) my_color = vec4(1.0);\n"
296
"}\n";
297
298
ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
299
300
glUseProgram(program.get());
301
302
constexpr int32_t kBufferCount = 16;
303
// The initial value of counter 'ac' is 3u.
304
unsigned int bufferData[3] = {11u, 3u, 1u};
305
GLBuffer atomicCounterBuffer[kBufferCount];
306
// Populate atomicCounterBuffer[0] with valid data and the rest with nullptr
307
for (int32_t bufferIndex = 0; bufferIndex < kBufferCount; bufferIndex++)
308
{
309
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer[bufferIndex]);
310
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData),
311
(bufferIndex == 0) ? bufferData : nullptr, GL_STATIC_DRAW);
312
}
313
314
GLint maxAtomicCounterBuffers = 0;
315
glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &maxAtomicCounterBuffers);
316
317
// Cycle through multiple buffers
318
for (int32_t i = 0; i < kBufferCount; i++)
319
{
320
constexpr int32_t kBufferIndices[kBufferCount] = {7, 12, 15, 5, 13, 14, 1, 2,
321
0, 6, 4, 9, 8, 11, 3, 10};
322
int32_t bufferIndex = kBufferIndices[i];
323
324
// Randomly bind/unbind buffers to/from different binding points,
325
// capped by GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS
326
for (int32_t bufferCount = 0; bufferCount < maxAtomicCounterBuffers; bufferCount++)
327
{
328
constexpr uint32_t kBindingSlotsSize = kBufferCount;
329
constexpr uint32_t kBindingSlots[kBindingSlotsSize] = {1, 3, 4, 14, 15, 9, 0, 6,
330
12, 11, 8, 5, 10, 2, 7, 13};
331
332
uint32_t bindingSlotIndex = bufferCount % kBindingSlotsSize;
333
uint32_t bindingSlot = kBindingSlots[bindingSlotIndex];
334
uint32_t bindingPoint = bindingSlot % maxAtomicCounterBuffers;
335
bool even = (bufferCount % 2 == 0);
336
int32_t bufferId = (even) ? 0 : atomicCounterBuffer[bufferIndex];
337
338
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, bindingPoint, bufferId);
339
}
340
}
341
342
// Bind atomicCounterBuffer[0] to slot 0 and verify result
343
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer[0]);
344
drawQuad(program.get(), essl31_shaders::PositionAttrib(), 0.0f);
345
ASSERT_GL_NO_ERROR();
346
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
347
}
348
349
// Test atomic counter increment and decrement.
350
TEST_P(AtomicCounterBufferTest31, AtomicCounterIncrementAndDecrement)
351
{
352
constexpr char kCS[] =
353
"#version 310 es\n"
354
"layout(local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
355
"layout(binding = 0, offset = 4) uniform atomic_uint ac[2];\n"
356
"void main()\n"
357
"{\n"
358
" atomicCounterIncrement(ac[0]);\n"
359
" atomicCounterDecrement(ac[1]);\n"
360
"}\n";
361
362
ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
363
364
glUseProgram(program.get());
365
366
// The initial value of 'ac[0]' is 3u, 'ac[1]' is 1u.
367
unsigned int bufferData[3] = {11u, 3u, 1u};
368
GLBuffer atomicCounterBuffer;
369
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
370
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
371
372
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
373
374
glDispatchCompute(1, 1, 1);
375
EXPECT_GL_NO_ERROR();
376
377
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
378
379
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
380
void *mappedBuffer =
381
glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_READ_BIT);
382
memcpy(bufferData, mappedBuffer, sizeof(bufferData));
383
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
384
385
EXPECT_EQ(11u, bufferData[0]);
386
EXPECT_EQ(4u, bufferData[1]);
387
EXPECT_EQ(0u, bufferData[2]);
388
}
389
390
// Tests multiple atomic counter buffers.
391
TEST_P(AtomicCounterBufferTest31, AtomicCounterMultipleBuffers)
392
{
393
GLint maxAtomicCounterBuffers = 0;
394
glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &maxAtomicCounterBuffers);
395
constexpr unsigned int kBufferCount = 3;
396
// ES 3.1 table 20.45 only guarantees 1 atomic counter buffer
397
ANGLE_SKIP_TEST_IF(maxAtomicCounterBuffers < static_cast<int>(kBufferCount));
398
399
constexpr char kComputeShaderSource[] = R"(#version 310 es
400
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
401
layout(binding = 0) uniform atomic_uint ac1;
402
layout(binding = 1) uniform atomic_uint ac2;
403
layout(binding = 2) uniform atomic_uint ac3;
404
405
void main()
406
{
407
atomicCounterIncrement(ac1);
408
atomicCounterIncrement(ac2);
409
atomicCounterIncrement(ac3);
410
})";
411
412
ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
413
414
glUseProgram(program);
415
416
GLBuffer atomicCounterBuffers[kBufferCount];
417
418
for (unsigned int ii = 0; ii < kBufferCount; ++ii)
419
{
420
GLuint initialData[1] = {ii};
421
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffers[ii]);
422
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(initialData), initialData, GL_STATIC_DRAW);
423
424
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, ii, atomicCounterBuffers[ii]);
425
}
426
427
glDispatchCompute(1, 1, 1);
428
EXPECT_GL_NO_ERROR();
429
430
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
431
432
for (unsigned int ii = 0; ii < kBufferCount; ++ii)
433
{
434
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffers[ii]);
435
GLuint *mappedBuffer = static_cast<GLuint *>(
436
glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), GL_MAP_READ_BIT));
437
EXPECT_EQ(ii + 1, mappedBuffer[0]);
438
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
439
}
440
}
441
442
// Test atomic counter array of array.
443
TEST_P(AtomicCounterBufferTest31, AtomicCounterArrayOfArray)
444
{
445
// Fails on D3D. Some counters are double-incremented while some are untouched, hinting at a
446
// bug in index translation. http://anglebug.com/3783
447
ANGLE_SKIP_TEST_IF(IsD3D11());
448
449
// Nvidia's OpenGL driver fails to compile the shader. http://anglebug.com/3791
450
ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA());
451
452
// Intel's Windows OpenGL driver crashes in this test. http://anglebug.com/3791
453
ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
454
455
constexpr char kCS[] = R"(#version 310 es
456
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
457
layout(binding = 0) uniform atomic_uint ac[7][5][3];
458
459
void f0(in atomic_uint ac)
460
{
461
atomicCounterIncrement(ac);
462
}
463
464
void f1(in atomic_uint ac[3])
465
{
466
atomicCounterIncrement(ac[0]);
467
f0(ac[1]);
468
int index = 2;
469
f0(ac[index]);
470
}
471
472
void f2(in atomic_uint ac[5][3])
473
{
474
// Increment all in ac[0], ac[1] and ac[2]
475
for (int i = 0; i < 3; ++i)
476
{
477
for (int j = 0; j < 2; ++j)
478
{
479
f0(ac[i][j]);
480
}
481
f0(ac[i][2]);
482
}
483
484
// Increment all in ac[3]
485
f1(ac[3]);
486
487
// Increment all in ac[4]
488
for (int i = 0; i < 2; ++i)
489
{
490
atomicCounterIncrement(ac[4][i]);
491
}
492
f0(ac[4][2]);
493
}
494
495
void f3(in atomic_uint ac[7][5][3])
496
{
497
// Increment all in ac[0], ac[1], ac[2] and ac[3]
498
f2(ac[0]);
499
for (int i = 1; i < 4; ++i)
500
{
501
f2(ac[i]);
502
}
503
504
// Increment all in ac[5][0], ac[5][1], ac[5][2] and ac[5][3]
505
for (int i = 0; i < 4; ++i)
506
{
507
f1(ac[5][i]);
508
}
509
510
// Increment all in ac[5][4][0], ac[5][4][1] and ac[5][4][2]
511
f0(ac[5][4][0]);
512
for (int i = 1; i < 3; ++i)
513
{
514
f0(ac[5][4][i]);
515
}
516
517
// Increment all in ac[6]
518
for (int i = 0; i < 5; ++i)
519
{
520
for (int j = 0; j < 2; ++j)
521
{
522
atomicCounterIncrement(ac[6][i][j]);
523
}
524
atomicCounterIncrement(ac[6][i][2]);
525
}
526
}
527
528
void main()
529
{
530
// Increment all in ac except ac[4]
531
f3(ac);
532
533
// Increment all in ac[4]
534
f2(ac[4]);
535
})";
536
537
constexpr uint32_t kAtomicCounterRows = 7;
538
constexpr uint32_t kAtomicCounterCols = 5;
539
constexpr uint32_t kAtomicCounterDepth = 3;
540
constexpr uint32_t kAtomicCounterCount =
541
kAtomicCounterRows * kAtomicCounterCols * kAtomicCounterDepth;
542
543
GLint maxAtomicCounters = 0;
544
glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTERS, &maxAtomicCounters);
545
EXPECT_GL_NO_ERROR();
546
547
// Required minimum is 8 by the spec
548
EXPECT_GE(maxAtomicCounters, 8);
549
ANGLE_SKIP_TEST_IF(static_cast<uint32_t>(maxAtomicCounters) < kAtomicCounterCount);
550
551
ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
552
glUseProgram(program.get());
553
554
// The initial value of atomic counters is 0, 1, 2, ...
555
unsigned int bufferData[kAtomicCounterCount] = {};
556
for (uint32_t index = 0; index < kAtomicCounterCount; ++index)
557
{
558
bufferData[index] = index;
559
}
560
561
GLBuffer atomicCounterBuffer;
562
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
563
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
564
565
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
566
567
glDispatchCompute(1, 1, 1);
568
EXPECT_GL_NO_ERROR();
569
570
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
571
572
unsigned int result[kAtomicCounterCount] = {};
573
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
574
void *mappedBuffer =
575
glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(bufferData), GL_MAP_READ_BIT);
576
memcpy(result, mappedBuffer, sizeof(bufferData));
577
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
578
579
for (uint32_t index = 0; index < kAtomicCounterCount; ++index)
580
{
581
EXPECT_EQ(result[index], bufferData[index] + 1) << "index " << index;
582
}
583
}
584
585
// Test inactive atomic counter
586
TEST_P(AtomicCounterBufferTest31, AtomicCounterInactive)
587
{
588
constexpr char kFS[] =
589
"#version 310 es\n"
590
"precision highp float;\n"
591
592
// This inactive atomic counter should be removed by RemoveInactiveInterfaceVariables
593
"layout(binding = 0) uniform atomic_uint inactive;\n"
594
595
"out highp vec4 my_color;\n"
596
"void main()\n"
597
"{\n"
598
" my_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
599
"}\n";
600
601
ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
602
glUseProgram(program);
603
604
drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
605
ASSERT_GL_NO_ERROR();
606
607
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
608
}
609
610
// Test inactive memoryBarrierAtomicCounter
611
TEST_P(AtomicCounterBufferTest31, AtomicCounterMemoryBarrier)
612
{
613
constexpr char kFS[] =
614
"#version 310 es\n"
615
"precision highp float;\n"
616
// This inactive atomic counter should be removed by RemoveInactiveInterfaceVariables
617
"layout(binding = 0) uniform atomic_uint inactive;\n"
618
"out highp vec4 my_color;\n"
619
"void main()\n"
620
"{\n"
621
" my_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
622
// This barrier should be removed by RemoveAtomicCounterBuiltins because
623
// there are no active atomic counters
624
" memoryBarrierAtomicCounter();\n"
625
"}\n";
626
627
ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
628
glUseProgram(program);
629
630
drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
631
ASSERT_GL_NO_ERROR();
632
633
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
634
}
635
636
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AtomicCounterBufferTest);
637
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AtomicCounterBufferTest31);
638
ANGLE_INSTANTIATE_TEST_ES3_AND_ES31(AtomicCounterBufferTest);
639
ANGLE_INSTANTIATE_TEST_ES31_AND(AtomicCounterBufferTest31,
640
WithDirectSPIRVGeneration(ES31_VULKAN()));
641
642
} // namespace
643
644