1[require]
2GL >= 3.3
3GLSL >= 3.30
4GL_ARB_shader_storage_buffer_object
5GL_ARB_shader_atomic_counters
6GL_ARB_shader_atomic_counter_ops
7GL_ARB_gpu_shader5
8
9[vertex shader passthrough]
10
11[fragment shader]
12#extension GL_ARB_shader_storage_buffer_object: require
13#extension GL_ARB_shader_atomic_counters: require
14#extension GL_ARB_shader_atomic_counter_ops: require
15#extension GL_ARB_gpu_shader5: require
16
17layout(binding = 0) buffer bufblock {
18	int value;
19};
20
21/* GL_ARB_shader_atomic_counters requires at least 8 total counters. */
22layout(binding = 0) uniform atomic_uint mask[7];
23layout(binding = 0) uniform atomic_uint fail;
24
25out vec4 color;
26
27void main()
28{
29	/* According to issue #22 of the GL_ARB_shader_image_load_store, the
30	 * return result of atomic operations in helper invocations is
31	 * undefined.  To avoid a possible infinite loop (below) in a helper
32	 * invocation, bail out now.
33	 */
34	if (gl_SampleMaskIn[0] == 0)
35		return;
36
37	/* Each of 32 * N fragments should see a unique value.  Each value
38	 * observed is tracked in "mask."  The test automatically fails if a
39	 * duplicate value is observed.  After the shaders are done running,
40	 * the mask values will be probed to ensure that all possible values
41	 * were observed.
42	 */
43	int f;
44
45	/* This is an open-coded atomicAdd. */
46	do {
47		f = value;
48	} while (f != atomicCompSwap(value, f, f + 4));
49
50	uint i = uint(f) / 4u;
51	uint bit = i % 32u;
52	int c = int(i / 32u);
53	uint m = 1u << bit;
54
55	if (c < mask.length()) {
56		/* If the bit was already set, the test fails. */
57		if ((atomicCounterOrARB(mask[c], m) & m) != 0u)
58			atomicCounterIncrement(fail);
59
60		color = vec4(0.0, 1.0, 0.0, 1.0);
61	} else {
62		color = vec4(0.0, 0.0, 1.0, 1.0);
63	}
64}
65
66[test]
67atomic counters 8
68
69ssbo 0 32
70ssbo 0 subdata float 0 0.0
71
72clear color 0.5 0.5 0.5 0.5
73clear
74
75draw rect -1 -1 2 2
76
77probe atomic counter 0 == 4294967295
78probe atomic counter 1 == 4294967295
79probe atomic counter 2 == 4294967295
80probe atomic counter 3 == 4294967295
81probe atomic counter 4 == 4294967295
82probe atomic counter 5 == 4294967295
83probe atomic counter 6 == 4294967295
84probe atomic counter 7 == 0
85