Hi all – I’m running into an odd error using NVIDIA drivers on Mac OS X Snow Leopard. The app actually exits during compile, with the following error text:
(0) : fatal error C9999: Nested functions, aborting!
Cg compiler terminated due to fatal error
This same shader code compiles and executes fine with NVIDIA’s Windows driver, not even a warning. Only the OS X Snow Leopard drivers are the issue.
If you really use nested functions then you should know that GLSL does not allow anything like that. The possible reason why it works on NVIDIA Windows drivers is because NVIDIA tends to not really care about the restrictions of GLSL as they use the same backend compiler for GLSL as they use for Cg, which have different syntax.
Just spent a bit going over the spec, and I don’t see where nested functions are disallowed. Can you quote the relevant spec language, or point me to the section?
Here’s what I read:
A function call returning a value is an expression (section 5.9).
A function-definition contains a statement-list, which contains a statement, which contains a simple-statement, which contains an expression-statement (section 6).
These definitions are consistent in spec versions 1.20 through 4.00.
I’ll go back and check my shader to ensure that my nested functions actually return values; if they return void, that’s the only way I can see that I might be in violation of the spec.
Yes, mbentrup is right. You confuse two different things:
nested function calls, i.e. calling a function from another function is allowed (actually the main() is also a function so not allowing it would mean that there is no possibility to make user defined functions).
nested functions (nested function definitions) which are not allowed neither in C nor in GLSL
I was once told by someone from nVidia that C9999 errors are not supposed to happen and are considered to be compiler-errors.
I once had one myself, and nVidia was extremely quick to take a look at it, just because I had postet the “C9999” part in the topics headline, such that someone from nVidia saw it.
So, maybe post it in nVidias forum or something like that, maybe they ARE interested to see your particular shader.
I’m guessing that this is what the error meant by “nested functions.”
That makes sense. Anyway, you should believe much more in the MacOSX driver as there the OpenGL driver is developed by Apple and only the low level stuff is maybe provided by NVIDIA, but the GLSL compiler is definitely Apple’s work. That’s the difference, because NVIDIA GLSL compiler usually allows much more things than it is specified in the GL spec.
AFAIK NVIDIA supports recursion so maybe they exposed this not only for Cg and CUDA but also for GLSL. Still if this is the case, your GLSL code is invalid.
Thanks, all. There is no recursion in my shader; the language spec is very clear that this is not allowed.
Yes, I might be confused on the difference between a “nested function definition” and a “nested function call”. I know what the latter is, and I believe GLSL allows it.
But I’m not clear on what a “nested function definition” is. Can someone post an example?
Just taking a guess… Does the following qualify as a nested function definition?
I’m using shader composition with a scene graph. I’m dealing with several hundred lines of code in dozens of shader source files, individually compiled and combined / linked together into several different program objects. I agree it would be valuable to create a small OpenGL-only app that can reproduce the problem, it would be a great diagnostic tool for this project, but currently it doesn’t exist.
In my first post on this thread, I included a link to a bug report from the VTK project. So that would be one way for people to obtain code that reproduces the issue.
Just to put a cap on this… An associate noticed that the VTK issue seems to be related to use of discard. As an experiment, I commented out all calls to discard in my shaders. The compiler crash went away.
I’m now in the process of rearchitecting the project to use alpha test to discard fragments (instead of calling discard). This is undesirable for a number of reasons, but keeps the project moving forward rather than spending time writing reproducer code and waiting for a driver/compiler fix from (first) NVIDIA and (then) Apple.