Subroutine API with subroutine arrays


According to the spec, the subroutine API supports subroutine arrays with dynamic indexing.
What I want to achieve with this is multi-material deferred shading. I store the material index in the G-Buffer and then use it in the lighting phase as an index to the subroutine array to select the material.

There is only one major caveat with this: subroutine uniforms have to be “reloaded” each time I bind the program. While this may not be an issue if you just use a single “material” and “light” subroutine uniform as an example, and you bind the appropriate subroutine to them on a per-object basis. However, as I have to make per-fragment decisions about what material or light to use, I have to have potentially large subroutine uniform arrays.

I don’t really understand why subroutine uniform state has this strange behavior. The ARB’s argument was that one may use two rendering contexts with different subroutines attached to the uniforms. Well, if this is the only reason why they chosen not to make subroutine uniform state program state then I’m completely disappointed. In my vision, if I would have to use the same program with different subroutine bindings, then I would simply replicate the program in the other context and manage it separately. I agree that this is kind of waste of resources, but less waste than forcing the application programmer to update a potentially large number of subroutine uniform values.

Is there any better way to achieve my idea?

The program state of subroutine variables also struck me as odd when I read the spec. If they wanted to allow multiple thread access to the same shader, then a “subroutine state object” would seem to be the logical choice, especially considering how much of the global context state has been migrating towards objects. That way only the id needs to be rebound - but even that seems a bit out of character for OpenGL.

As for your problem, perhaps keep a persistent copy of the subroutine states in application-side buffers? This could save the effort of rebuilding these arrays for each stage, each time the shader is invoked.

Agree. Actually I designed my OpenGL C++ wrapper to have some subroutine uniform object style thing called SubroutineUniformList, but it still can have an overhead if I have many subroutines.
However, I’ll have to do some tests to see whether this really incurs a performance hit. Maybe I’m just too worried.