What optimization are made for uniforms?

Hi there,
As the title of the topic states, I’m curious to know how the uniform-related behaviours are optimized. In particular I know that unused uniform are “deleted”, but what I’m particularly interested into is:

  • If the value passed to the uniform is exactly the same between two frames, there are some optimizations involved or not?
  • If I have two shader program, says A and B, what are the implication of:

Scenario 1


A.use()
upload value U in one uniform (say u1)
B.use()
upload same U in a uniform in B
A.use()
upload value U in the same uniform u1

vs

Scenario 2


A.use()
upload value U in one uniform (say u1)
A.use()  // I know it's pointless, but assume I have to call use again.
upload value U in the same uniform u1
B.use()
upload same U in a uniform in B

?
I assume that the second is better, but to which extent? No optimization is made for scenario 1?

Note: I’m aware of the fact that both Scenario 1 and 2 can be better written sorting the operations per program, but I’m interested in the otherwise case

AFAICT, neither the GL nor the GLSL spec suggest any course of action in case of setting the same values repeatedly - and frankly I wouldn’t expect them to. From the API user’s perspective (i.e. GL developers, not implementors) it’s entirely an implementation detail. I guess it depends on how expensive determining the current state of program-specific storage is.

If the value passed to the uniform is exactly the same between two frames, there are some optimizations involved or not?

What I can tell you is that you still have the completely unnecessary overhead of calling glUniform*() - if you know you don’t have to change the current program’s state, just don’t do it. Don’t count on implementations in that regard.

If I have two shader program, says A and B, what are the implication […]

In scenario 1, programs A and B will have distinct states and thus both calls will update uniforms in different programs. Since you made program B current before the second time you make A current, the latter would not be redundant, albeit completely unnecessary overhead. Setting the same value again is redundant but ideally a no-op - still I would strongly advise against this practice.

Scenario 2 is worse because here youhave a two redundant state changes, first the repeated call to glUseProgram() and the redundant call to glUniform*(). Making B current and setting a uniform in B is fine and necessary if the value of U in B is actually different.