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 7 8[vertex shader passthrough] 9 10[fragment shader] 11#version 330 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 16layout(binding = 0) buffer bufblock { 17 int value; 18}; 19 20/* GL_ARB_shader_atomic_counters requires at least 8 total counters. */ 21layout(binding = 0) uniform atomic_uint mask[7]; 22layout(binding = 0) uniform atomic_uint fail; 23 24out vec4 color; 25 26const uint max_index = uint(mask.length()) * 32u + 31u; 27 28void main() 29{ 30 uint x = uint(gl_FragCoord.x); 31 uint y = uint(gl_FragCoord.y); 32 uint local_index = y * 32u + x; 33 34 int new_value = (x < 32u && y < uint(mask.length())) 35 ? int(4u * local_index) : 0x7fffffff; 36 37 int f = atomicExchange(value, new_value); 38 uint i = uint(f) / 4u; 39 uint bit = i % 32u; 40 int c = int(i / 32u); 41 uint m = 1u << bit; 42 43 if (i <= max_index) { 44 /* If the bit was already set, the test fails. */ 45 uint r = atomicCounterOrARB(mask[c], m); 46 if ((r & m) != 0u) 47 atomicCounterIncrement(fail); 48 49 if (bit == local_index) 50 atomicCounterIncrement(fail); 51 52 color = vec4(0.0, 1.0, 0.0, 1.0); 53 } else { 54 color = vec4(0.0, 0.0, 1.0, 1.0); 55 } 56} 57 58[test] 59atomic counters 8 60 61ssbo 0 32 62ssbo 0 subdata int 0 65536 63 64clear color 0.5 0.5 0.5 0.5 65clear 66 67draw rect -1 -1 2 2 68 69probe atomic counter 0 == 4294967295 70probe atomic counter 1 == 4294967295 71probe atomic counter 2 == 4294967295 72probe atomic counter 3 == 4294967295 73probe atomic counter 4 == 4294967295 74probe atomic counter 5 == 4294967295 75probe atomic counter 6 == 4294967295 76probe atomic counter 7 == 0 77