When using compute shaders, some workgroups can be faster than others, for example when all invocations within one group go into the 'if' case, where on another workgroup the invocations go into the 'if' and the 'else' case. My question: are the workgroups be released which have finished their work while others are still working? And can these warps be used at that time for other shaders? Or are they blocked till all workgroups within that dispatch compute call are finished? Is that hardware specific or driver specific?
Yes resources will be availiable for the next command from the command queue, be it compute or other type of shader, even when the previous dispatch operations have not finished.
For this reason, if subsequent shaders rely on output of a previous shader, these need to have barriers in place or wait until the command queue is empty and and the operations are finished (glFinish).
// Even at this point, shader1 could still have workgroups being processed... shader2 will either be in the command queue or currently being have workgroups being processed...
To use glFinish()...
glFinish(); // Program will wait here until all GL operations in command queue are finished (queue will be empty)...
// At this point, all of shader1's workgroups have finished...
You could use glFlush if you wish to process the commands without stalling the program, however this will not guarantee that subsequent commands are not being processed prematurely to what you think (since program is not stalled, it only empties the command queue telling GL to process what was in the queue and empty the queue).
glFlush tells GL to process all the commands that have been queued up to that point and clears the queue upto that point. Main program thread is not halted, and can carry on filling up (a now empty) command queue (while GL processes the 'flushed' operations).
glFinish tells GL to process all the commands that have been queued (like flush), but stalls the calling thread until GL is finished processing (which, in the example code, will prevent the second dispatch call until GL is finished processing its queue of commands, i.e no overlapping operations). When program continues, the queue will be empty and operations will have been processed.
As mentioned above, for compute shaders this is especially important if the input of shader2 relies on the output of shader1.