m3v3rik m3v3rik - 1 year ago 47
iOS Question

What is the right approach to creating an UberShader using function_constants in Metal?

I just learnt about function_constants in "What's new in Metal" video from WWDC 2016 and it mentioned UberShaders quite a few times. I want to create a fragment uber shader that can be used for different kind of passes, like simplePassThrough, defferred etc. Below is how I want to use it.

constant int passType [[function_constant(0)]];
constant bool simplePassThrough = (passType == 0);
constant bool forwardShading = (passType == 1);
constant bool deferredShading = (passType == 2);

fragment FragmentOutStruct UberFragmentShader()
FragmentOutputStruct frgOut;
if (simplePassThrough) {
// Update frgOut
} else if (forwardShading) {
// Update frgOut
} else if (deferredShading) {
// Update frgOut
return frgOut;

Is this the right approach here? Will my final compiled MTLFunction see too many branches if I use this approach?

Answer Source

This is a legitimate use case for function constants, and will have no branching cost at runtime. This is because the compiler will eliminate code it determines can never be executed (e.g., because it is equivalent to if(false) { ... }).