Shader Stitching Performance

Hi,

Does a design that links together several shader objects to create a single shader object create less optimized shaders than a design that uses string concatenation? I’d like to provide a cache of shader objects that contains useful functions for shader authors. They would call a function from their shader, and link against the appropriate shader object, instead of concatenating a string with the function.

One concern I have is the linker may not be able to perform as many optimizations as the compiler. For example, if a user calls a function to emulate depth clamping from a vertex/fragment shader when the hardware supports depth clamping, the functions would be empty and I hope optimized away.

In general, how good should I expect the GLSL optimizer to be at things like inlining, factoring out redundant computation, etc. As good as modern C++ compilers?

Thanks,
Patrick

“In general, how good should I expect the GLSL optimizer to be at things like inlining, factoring out redundant computation, etc. As good as modern C++ compilers?”

guess it depends on the vendor and driver. noticed that on NVidia doing heavy multiple lights normalmapping and simply assign gl_FragColor = vec4(1.0,0.0,0.0,1.0) the compiler recognizes that, skips few steps and doesnt even include my uniform variables resulting in my own error messages that this or that uniform variable wasn’t located though its right there. optimizion is quite good imho.
hope to hear from others though about different experience.

You can profile GLSL source with this tool:
http://developer.amd.com/gpu/shader/Pages/default.aspx

From my testing, when code is compiled, i think the shader compiler builds a dependency tree from the relevant output values(result.color.rgb etc) and removes all code which does not affect these output values.

Don’t know about how much optimization occurs in linking stage, to be honest. It may be vendor/driver version dependant.

It has been my experience that the driver does not actually do any compiling or other operations on your GLSL shader objects until you actually Link them, at which point it concatenates them and compiles them together. You shouldn’t see any gain or loss in performance either way.

Personally, I did a concatenation operation myself on my shader objects since there was a bug at some point in the Nvidia drivers which did not handle properly dependencies across shader objects.

I can’t find where I read this, but at least one GLSL doc confirmed that the driver (can’t remember if it was AMD or NV…) doesn’t really work with shaders the same way as a C compiler works with object files.

That would be great if the compile is actually delayed until the “link” stage. How did you come to this conclusion?

Patrick

Looks like this is still a bug on ATI. If I try to link together two vertex shader objects, one with main() and another just with a function, I get “ERROR: There was no main in the program.” It doesn’t matter the order in which I link them.

Thanks for the heads up, looks like I have to concatenate strings too.

Patrick

First thing I did is actually time the OpenGL calls to compile and link shaders. The compile time was so negligible compared to the link time that I guessed this was the case.

Second, I read this from the “Release Notes for NVIDIA OpenGL Shading Language Support” :

GLSL provides for multiple shader objects to be created, assigned GLSL source text, compiled, be attached to a program object, and then link the program object.

NVIDIA’s current driver doesn’t fully compile shader objects until the program object link. At this time all the source for a single target is concatenated and then compiled.

This means (currently) there is no efficiency from compiling shader objects once and linking them in multiple program objects. Unlike earlier drivers, the code will be parsed and syntax checked during the compile phase to allow the immediate reporting of errors. Some errors may still be deferred until link, but most should be available at compile time.

So there you go :slight_smile:

Good answer. Thanks!

Patrick

FWIW, it’s also my experience ! I’ve been linking shaders (fragment & vertex) for a few years now, and apart from being bitten by drivers occasional regressions/bugs, everything works fine for me ! I did not recently test on ATI drivers, but as of october 2008, everything worked fine for me in vertex shaders linking.

Cheers.

FWIW, it’s also my experience ! I’ve been linking shaders (fragment & vertex) for a few years now, and apart from being bitten by drivers occasional regressions/bugs, everything works fine for me ! I did not recently test on ATI drivers, but as of october 2008, everything worked fine for me in vertex shaders linking.

Cheers. [/QUOTE]
I have tested with Catalyst 9.2 - 9.4 and linking multiple fragment shaders works fine (one shader contains the main function and the rest implement different functions).