Reading back data with the CPU, that is the results of some GPU work

Hi,

I would like to do some work on the GPU and then do some CPU work with the results. How should I do that ?

// Execute work on the GPU
glUseProgram(program_id);
glBindImageTexture(slot, textureId..., GL_WRITE_ONLY);
glDrawElements(slot, textureId...);
glUseProgram(0);
glBindImageTexture(slot, 0..., GL_WRITE_ONLY);

// Synchronization code (see text below)
sync();

// Read data back and do something with it with the CPU
glBindBuffer(GL_TEXTURE_BUFFER, bufferId associated with my texture);
void *ptr = glMapBuffer(GL_TEXTURE_BUFFER, GL_READ_ONLY);
// do something with ptr
glUnmapBuffer(GL_TEXTURE_BUFFER);
glBindBuffer(GL_TEXTURE_BUFFER, 0);

How should sync() be implemented? Is it necessary - at all?

I tried glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) but that doesn’t work (AMD Radeon R9 290X, tried all latest drivers). GL_SHADER_IMAGE_ACCESS_BARRIER_BIT ensures that subsequent shader memory accesses are synchronized, that is, that imageLoad() or imageStore() performed from within a shader in a GL command issued after the barrier, are synchronized. So it seems fair that it doesn’t work.

Shall I use GL_BUFFER_UPDATE_BARRIER_BIT instead ? Here is the doc for GL_BUFFER_UPDATE_BARRIER_BIT :

Reads or writes via glBufferSubData, glCopyBufferSubData, or glGetBufferSubData, or to buffer object memory mapped by glMapBuffer or glMapBufferRange after the barrier will reflect data written by shaders prior to the barrier. Additionally, writes via these commands issued after the barrier will wait on the completion of any shader writes to the same memory initiated prior to the barrier.

This looks promising, but the last part of this paragraph worries me: Additionally, writes (so, I understand: not reads!) via these commands issued after the barrier will wait on the completion of any shader writes to the same memory initiated prior to the barrier. Does this mean that if I just read data (glMapBuffer used with GL_READ_ONLY), glMapBuffer will not wait for my shader to complete ? Shall I use glFenceSync to explicitly wait for my shader to complete, and then call glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT) ?

Thanks for your insight,
Fred