… aka Dealing with the C0204 error
Hi everyone!
To startup, just a little bit of context… I use since several years shaders that use #define directives to adapt to the underlying hardware, #defines that are generally passed manually to the compiler by concatenation to the shader content. For instance:
#define SOME_FLAG // This line may be added dynamically regarding current hardware
#ifdef SOME_FLAG
#version 120
[...]
#else
#version 150
[...]
#endif
[...]
Another typical exemple is for cross GL / GLES shaders, the GL_ES define being brought by the driver, according to the spec:
#ifdef GL_ES
precision mediump float;
[...]
#else
#version 150
[...]
#endif
[...]
1 - The problem
The thing is, this code is invalid (from what I understand), since the #version directive shall be the first one to appear (cf. “The #version directive must appear before anything else in a shader”). I works with NVIDIA cards and drivers that were pretty compliant until recently, but it seems that on recent drivers those shaders no longer compile, and throw the error C0204: version directive must be first statement and may not be repeated.
2 - The solution
Actually I do not ask for help to get a solution to this issue, I just need to build a pre-compilation system that extracts and concatenates the proper portions of code to make it valid regarding version declaration (and I have to deal with the inconsistent line numbers in error logs :p). Another faster fix is to never define the version in the shader files but always dynamically as a pre-concatenated string before compilation.
2 - The real question
No, the real question is: Why?
Why does the version declaration needs to be the first directive? I mean, the general use of shaders is to define everything in one file, so what’s the point of having access to the VERSION definition, since we normally already wrote it and there can be the only one? And what’s the point of defining implicitly (again according to the spec) GL_ES since we’re supposed to know it already?
So yes, my question is rather: can someone explain me the point of this particular element of the spec? I’m sure there’s a pretty good reason to it, I just don’t understand it. And when you don’t understand a standard, you don’t use it properly
Thanks guys!