Reputation: 8238
I have some math functions written in GLSL and I want to use them in TES, geometry and fragment stages of the same shader program. All of them are pretty valid for all these shader types, and for now the code is just copy-pasted across shader files.
I want to extract the functions from the shader files and put them into a separate file, yielding a shader "library". I can see at least two ways to do it:
Is it possible to compile shader source only once (with appropriate restrictions), link it to a shader program and use it in any stage of the pipeline? I mean something like this:
GLuint shaderLib = glCreateShader(GL_LIBRARY_SHADER);
//...add source and compile....
glAttachShader(shProg, vertexShader);
glAttachShader(shProg, tesShader);
glAttachShader(shProg, geomShader);
glAttachShader(shProg, fragShader);
glAttachShader(shProg, shaderLib);
glLinkProgram(shProg); // Links OK; vertex, TES, geom and frag shader successfully use functions from shaderLib.
Of course, library shader should not have in
or out
global variables, but it may use uniform
s. Also, function prototypes should be declared before usage in each shader source, as it is possible to do when linking several shaders of the same type into one program.
And if the above is not possible, then WHY? Such "library" shaders look very logical for the C-like compilation model of GLSL.
Upvotes: 1
Views: 1269
Reputation: 31
All the high level constructs of structs, functions, linking of modules, etc, are mostly all just niceties that the APIs provide to make your life easier on input. HLSL for example allows you to do use #include's, but to do something similar in GLSL you need to perform that pre-process step yourself.
When the GPU has to execute your shader it is running the same code hundreds, thousands, if not millions of times per frame - the driver will have converted your shader into its own HW specific instruction set and optimised it down to the smallest number of instructions practicable to guarantee best performance of their instruction caches and shader engines.
Upvotes: 0
Reputation: 473407
Is it possible to compile shader source only once (with appropriate restrictions), link it to a shader program and use it in any stage of the pipeline?
No. I'd suggest, if you have to do this, to just add the text to the various shaders. Well, don't add it directly to the actual string; instead, add it to the list of shader strings you provide via glShaderSource/glCreateShaderProgram
.
And if the above is not possible, then WHY?
Because each shader stage is separate.
It should be noted that not even Vulkan changes this. Well, not the way you want. It does allows you to have the reverse: multiple shader stages all in a single SPIR-V module. But it doesn't (at the API level) allow you to have multiple modules provide code for a single stage.
Upvotes: 2