Compute Shader issue with calls to imageLoad() and subsequent ImageStore()

So, I’ve got this weird situation. I have a compute shader that does scatter-writes to a texture. Shader code looks like:

#version 430

layout(local_size_x = 32, local_size_y = 32) in;
layout(r32f, binding = 0) uniform coherent volatile restrict image2D depths_inout;
layout(r32ui, binding = 1) uniform coherent volatile restrict uimage2D uweights_out;

void main()
  vec2 in_coords = vec2(gl_GlobalInvocationID.xy);
  if( someCondition(...) )
    ivec2 out_coords = CalculateCoords(...);
    imageAtomicAdd( uweights_out, out_coords, 1);
    float depth = imageLoad( depths_inout, out_coords ).x;
    depth += 20.0;
    imageStore(depths_out, out_coords, vec4(depth));

I bind the images in C++ as:

glBindImageTexture(0, depths_inout_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
glBindImageTexture(1, uweughts_out_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);

… and I initialize depths_inout_texture and uweights_out with zeros.

So, effectively, you would expect that depth[some_index] == 20* uweights_out[some_index].
Unfortunately not.
The uweights_integer values are set correctly.
The depths though are mostly set to 20 even though uweights_out might contain a value higher than one.
So this smells of bad sync.

I’ve added barrier() calls before every texture access in the shader, and [b]glImageBarrier/b after each compute dispatch. Still no luck.

Any idea what the problem might be?


Hmm thinking about it, I’m afraid I can’t just do that… All sorts of synchronization misery can occur between the imageLoad call and imageStore. The only way it seems to be atomicAdd, which would mean that I’d need to convert the depths to uints first…

you can’t send depth image as image2D.

[QUOTE=Hellice;1285713]you can’t send depth image as image2D.

Well, it’s not really a proper depth buffer texture, just an R32F one. But that’s really useful info as I might have tried to use such a texture later, thanks! :slight_smile: