glsl function pointer (or equivalent)
There are no function pointers in GLSL, but it is possible to define a structure with a list of function names:
struct functions_list {
int sin;
int cos;
int tan;
int fract;
};
const functions_list functions = functions_list(1,2,3,4);
Using this list of function names, it is possible to simulate a callback:
float callback(int func,float arg){
if(func == functions.sin)
return sin(arg);
else if(func == functions.cos)
return cos(arg);
else if(func == functions.tan)
return tan(arg);
else if (func == functions.fract)
return fract(arg);
else
return 0.0;
}
These "function pointers" can be used to simulate higher-order functions in GLSL.
GLSL does not have function pointers. Even SPIR-V doesn't have function pointers. Shaders represent a limited execution environment. And one of those limitations is the lack of a requirement for a stack. And you can't really have arbitrary function pointers without one of those.
The horribly il-advised1shader subroutines feature of GLSL 4.00 probably won't help either. It would only help if your <something calculated during runtime>
were a CPU-generated value, and that seems unlikely in your case.
The only general solution you have is a switch statement. And quite frankly, there's nothing wrong with that.
I mean, you're already going to absolutely murder your performance by doing this kind of condition anyway. No matter how it gets implemented, if different instances in the same wavefront are executing separate code, you're kinda screwed performance-wise.
Not to mention, a switch statement does not necessarily get slower based on how many conditions there are. How it gets implemented depends entirely on the hardware. If jump tables are available, it can be done reasonably efficiently (ignoring the above performance issue, of course).
Also, there is Colonel Thirty Two's idea, where you encode each function's operation as a dot-product with a constant vector. Obviously, this limits what your various functions can actually execute. But if it works in your case, it works.
1 If you want to contest this, consider that SPIR-V provides an analog to every feature of GLSL, no matter how redundant, silly, or unnecessary... except shader subroutines.