Precompiled GLSL?

Compiling GLSL programs for my app is taking a significant amount of time at startup.
Is there a way to precompile them, or do I need to switch to Cg?

Cg doesn’t compile shaders either.
Only OpenGL ES do have compiled shaders AFAIK.

(The “ASM” shader interface is NOT ASM, it just looks like ASM but it’s converted into chip specific microcodes, so it’s compiled in the drivers anyway.)

There is no way to pre-compile GLSL shaders AFAIK simply because there is no common micro-architecture dictated by ARB and hence each vendor has his own micro-codes.

You could probably take generated assembly code and use some tool on it that would convert such assembly into ARB_fragment_program / ARB_vertex_program compatible assembly. You would have to create such tool yourself.
Still, this doesn’t make too much sense, since as Ingenu said, assembly shader needs to be compiled, too. Furthermore - by making such conversion you will have slower shaders, since GLSL compiler can optimize shader for GPU it’s running on.

You should probably review your shader architecture. If there are some common parts in shaders then make separate shader objects out of it. Compile separately and then just link.

Originally posted by k_szczech:

Still, this doesn’t make too much sense, since as Ingenu said, assembly shader needs to be compiled, too.

Altrough the assembly shader is compiled to GPU microcode, such compilation is significantly faster than compiling equivalent GLSL code. In case where application startup time is more important than maximal speed of the shaders (e.g. during evelopment), use of assembly shaders makes sense.


You should probably review your shader architecture. If there are some common parts in shaders then make separate shader objects out of it. Compile separately and then just link.

Unfortunatelly current Nvidia drivers do most of the work during program linking so the advantage of such approach is probably small.

Altrough the assembly shader is compiled to GPU microcode, such compilation is significantly faster than compiling equivalent GLSL code.
Theoretically. The “assembly” language doesn’t represent the hardware necessarily. Sure, it doesn’t have the linking step that glslang does, and it doesn’t have function calls, but that’s about it.

Originally posted by Korval:
Theoretically. The “assembly” language doesn’t represent the hardware necessarily.
My experience is that for current hw and drivers the assembly level shader is compiled significantly faster than corresponding GLSL.

Current Nvidia drivers even compile the GLSL into assembly which is then converted into microcode so in that case the assembly will be faster because it avoids one step of that conversion.


Sure, it doesn’t have the linking step that glslang does, and it doesn’t have function calls, but that’s about it.

The GLSL compiler has more complicated input and needs to decide things the assembly shader can have hinted or decided by someone else (e.g how to implement some branch in simple instructions, how to inline some function). Additionally the GLSL compiler can apply optimizations that are not possible on the assembly level and this will consume additional time. While the compiler can become faster, the amount and complexity of optimizations done by it will also probably increase so the compilation time will probably not decrease significantly in the future.

To me a good intermediate approach would be:

  • compile/link GLSL as usual
  • then ask the card for to dump its internal representation of the complete shader as a binary blob.
  • save blob to disk. Next time the app tries first to load the blob to the card, if error happens (card changed, driver changed, or whatever) go back to step 1.

That way, only the first start is slow, and the GLSL high level is kept.

What one needs is a binary format for shaders that will allow to skip the parsing and much of analysis steps. The best format would be one that can be fed by the optimization routine without modification, like SSA.

@Zbuffer - yeah, Battlefield 2 does something like that. That’s DirectX though, which makes it nice and easy to compile to a binary format.
Do you know of any way to obtain the “binary blob” in OpenGL? (if it’s nVidia only that’s fine for me)

Do you know of any way to obtain the “binary blob” in OpenGL?
No, but there have been discussions in the ARB for exposing such functionality.