1layout(local_size_x = 64) in; 2 3layout(metal, binding = 0) buffer ssbo { 4 atomicUint globalCounter; 5}; 6 7workgroup atomic_uint localCounter; // atomic_uint is a synonym for atomicUint 8 9void main() { 10 // Initialize the local counter. 11 if (sk_LocalInvocationID.x == 0) { 12 atomicStore(localCounter, 0); 13 } 14 15 // Synchronize the threads in the workgroup so they all see the initial value. 16 workgroupBarrier(); 17 18 // All threads increment the counter. 19 atomicAdd(localCounter, 1); 20 21 // Synchronize the threads again to ensure they have all executed the increment 22 // and the following load reads the same value across all threads in the 23 // workgroup. 24 workgroupBarrier(); 25 26 // Add the workgroup-only tally to the global counter. 27 if (sk_LocalInvocationID.x == 0) { 28 atomicAdd(globalCounter, atomicLoad(localCounter)); 29 } 30} 31