Compiling shader in separate thread

Hi! Question, is it posible in some way to compile and link a shader in a separate thread than the one rendering in modern opengl implementations? (say… 3.1+ ?)


Create two contexts, one for each thread, and let them share their lists (wglShareLists). Now you may create and compile shaders in thread B while you do rendering in thread A. Once a shader is successfully compiled and linked, notify thread A so it can actually use this shader from then on.

skynet: Have you ever gotten this to work efficiently?

For my part, I noticed that doing OpenGL operations in the second shared context delayed other OpenGL commands in the “primary” context. It seemed like there is some kind of global lock that the driver takes when it compiles a shader.

No, admittedly I have never done this. It just seems to me the only viable way.
But I do have experienced the kind of problems you describe. I did some multithreaded rendering via NV_gpu_affinity (two unrelated threads rendering in two unrelated contexts on two separate GPUs). Profiling showed that my app was spending alot of time in threading/locking/syncing functions of the OS. I was told that this is due to threadsafing inside the driver and that it will take time to change the driver to see the scaling I was looking for (I was hoping for roughly the double performance).

Even with the delays - creating and compiling a shader is just a few commands with one of them being costly, so the impact on other contexts will probably be minimal as it will mailny occupy one of CPU cores for compilation.

Unless there’s something I don’t know and shader compilation itself needs frequent communication with GPU :slight_smile:

I seen that on a really software composed on 4 viewports with 2 contexts, one for a fast rendering and the other one for the slow renderer… That was just awful! The main issue was debugging

I changed the architecture to have just one thread of the OpenGL context and one for software interface with a message system.

When you use two contexts, you have to use wglMakeCurrent which is probably the slowest OpenGL function! All the states and objects are reset … => it kills your renderer!

Anyway, it would be great to have a way to compile shaders on other thread, the new Direct3D deferred context would be great!

the new Direct3D deferred context would be great!

That’s totally unnecessary for compiling shaders in another thread. All that needs to be done is for the OpenGL implementation to recognize the difference between functions that modify context state and functions that don’t. The ones that don’t (like creating programs) can be done asynchronously without problems.