问题
Is there an implicit synchronization in the following GL code?
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(prg);
glUniform1f(loc, a);
glDrawArrays(GL_TRIANGLES, 0, N);
glUniform1f(loc, b); // <-- Implicit synchronization??
glDrawArrays(GL_TRIANGLES, 0, N);
swapBuffers();
回答1:
As always, OpenGL implementations can handle things the way they like, as long as it results in the correct behavior. So there's really no way to say how it has to work.
That being said, updating uniforms is a common operation, and forcing a synchronization between GPU and CPU for uniform updates would be horrible for performance.
The easiest way to picture how this most likely works in reality is that the OpenGL calls you make are encoded in a command stream that is later executed by the GPU. When you make a glUniform()
call, this will generate a command to update the uniform value, and append that command to the command stream. It will be executed by the GPU later, along with the draw calls that are also part of the same command stream.
Only when the GPU executes the command, which will mostly happen long after the glUniform()
call returns, will the actual value used by the GPU be updated.
回答2:
Most likely no.
On most of the modern multithreaded driver implementations your whole frame, including glDraw*
call may be asynchronous. So, CPU is almost always few frames ahead of GPU.
Sync only sometimes happens when querying states (glGet*
) or doing big memory transfers, like buffer updates.
Of course, details depend on concrete vendor's software and hardware implementations, OS, and even driver version, etc.
See also:
NVidia -- Detecting CPU-GPU Sync Points [PDF]
P.S. The new APIs are being developed to address those (and more) problems, mostly by giving a programmer explicit control over the sync process:
- OpenGL 4 --> Vulkan
- DirectX 11 --> Directx 12
来源:https://stackoverflow.com/questions/30783891/implicit-synchronization-with-gluniform