glClientWaitSync
Makes the CPU wait (up to a timeout) until a fence is signalled, or just checks it with timeout 0.
Signature
GLenum glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
How it works
Blocks the calling thread until the fence signals or timeout nanoseconds pass. With a ring of three regions the fence is almost always signalled already, so the wait costs nothing; if it is not, the wait is the right thing to do, because the GPU is still reading the memory you want to change.
With timeout 0 it does not wait at all: a cheap way to poll, for example to check whether a readback is ready before mapping it.
Parameters
The fence from glFenceSync.
GL_SYNC_FLUSH_COMMANDS_BIT (recommended) or 0.
Maximum wait in nanoseconds (1'000'000 = 1 ms). 0 = just check.
Return value
GL_ALREADY_SIGNALED (it was done before the call), GL_CONDITION_SATISFIED (it became done during the wait), GL_TIMEOUT_EXPIRED (still not done), or GL_WAIT_FAILED (an error).
Tips & pitfalls
Without GL_SYNC_FLUSH_COMMANDS_BIT the fence may still be sitting in a driver queue that was never sent to the GPU, and the wait can last until the timeout.
glWaitSync is the GPU-side version: it makes the GPU, not the CPU, wait (useful between two contexts).
Errors
When the call is invalid it does nothing and sets an error, which glGetError returns:
- GL_INVALID_VALUE
- sync is not a fence, or flags has unknown bits.
Example
1if (fence[k]) {
2 while (glClientWaitSync(fence[k], GL_SYNC_FLUSH_COMMANDS_BIT, 1'000'000) == GL_TIMEOUT_EXPIRED) {}
3 glDeleteSync(fence[k]);
4}
5memcpy(mapped + k * regionSize, data, regionSize); // safe now