While debugging my system, I found out that all the shaders I used were never compiled. All the GLSL Programs were happily linked and working like a charm.
I have searched the entire code base for calls to glCompileShader
, but none were found.
My question then is: Is this a specific behaviour of the implementation I am working with? Is shader compilation carried out implicitly when linking a program? Is it optional? If that is the case, what advantages are there in doing it explicitly, apart from retrieving the error log?
I could not find any case such as mine in the documentation, if I missed something can you please point me to it?
My vendor is NVIDIA (driver 337.88)
EDIT: Also, I am NOT using glCreateShaderProgram()
, but simply glCreateProgram()
for the creation of shader programs.
OpenGL has three ways to compile shader text into usable OpenGL objects. All of these forms of compilation produce a Program Object.
Now, GLSL code can be pre-compiled to SPIR-V offline using the shaderc toolchain. The developers would do this ahead of time and ship the SPIR-V bytecode with their app. Then at runtime the SPIR-V gets submitted to the Vulkan driver and compiled the rest of the way to GPU machine code.
This was mostly resolved in the comments (thanks to @Andon, @derhass, and others), but since it's an interesting question, let me summarize it in an answer, and add some more data.
Not taking pre-compiled shaders into consideration, you need to compile your shaders by calling glCompileShader()
before linking the program with glLinkProgram()
. Based on the data I collected, skipping the glCompileShader()
call works fine on:
It fails on:
So this behavior seems clearly isolated to NVIDIA. The specs say that compiling the shaders before linking is necessary. From the 3.3 specs:
Linking will also fail if one or more of the shader objects, attached to program are not compiled successfully.
The 4.4 specs are a little less clear, turning the possible error conditions into a list that starts with:
Linking can fail ...
Normally can suggests that behavior is optional, but I'm not sure that this is the intention here. It looks to me like the specs were just reformatted, and the intended behavior has not changed. So IMHO, this is a bug. Not a very severe one, because all legal usage still works, but I don't think what NVIDIA is doing strictly follows the specs.
In any case, calling glCompileShader()
before glLinkProgram()
is necessary for your code to work across platforms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With