# Compute Shader shared average value

Short Question: How can i integrate a buffer variable in a compute shader over each pixel i.e. how can i ensure memory coherence in such a case?

Long Question: I've written a deferred renderer with hdr and i want to implement automatic exposure. For that purpose i orignally used mipmapping, but that is not very performant and i want to improve my knowledge about compute shaders. So i tried to write a compute shader that approximates the average luminance of a image (approximation in the sense that i don't process every pixel but e.g. only 64 x 36 samples).

That would require me to accumulate the luminance of each pixel i.e. of each shader invocation. So i created a buffer which holds my luminance value:

volatile layout(std430, binding = 0) buffer averageBlock{
float luminance;
} average;


BUT: there are no atomic operations for floats so i changed it to

uint luminance[10];


Were each entry holds a part of the luminance (i.e. the first pixel writes to entry 0, the second to 1, ... the tenth to 0, ...) to increase the value range. I then mapped the float values to ints (multiplied them with 280, since that uses the available memory range nearly completly in the edge case were everything as a luminance of 1).

I then accumulated the values with:

uint discl = uint(lum * 280.0);
int slot = int(mod(gl_GlobalInvocationID.x, 10));
memoryBarrierBuffer();
memoryBarrierBuffer();
barrier();


But it seems that this also leads to visibility problems, since when i set lum to a certain value, only a random proportion of that value is present after barrier() (maybe because between those memoryBarrier calls the atomic adds don't see the changed values of the other ones).

So how do i do this correctly? Thanks for your help!

First of all, I don't think you need volatile or memory barriers if you're just using atomic operations. Atomic operations are always supposed to be atomic regardless.