always there is written that state changes affect performance. My question is what counts as a state change. What about setting a state to the same value twice? Does the OpenGL implementation recognize this and simply does nothing?
I mean is it a good thing to track all states in the application to prevent redundant state changes or is this doing a lot of work than is already done by the driver?
Two objects share the same shader, color map but have different normal maps:
- bind the program
- bind “colormap” to TMU0
- bind “normalmap0” to TMU1
- render “object0”
(5. bind “colormap” to TMU0)
- bind “normalmap0” to TMU1
- render “object1”
Step 5 binds a texture map to a TMU that is already bound to it. Does this bring a huge performance hit or is this redundant change detected?
Well, actually, what i tell you now is pure speculation, because i am no driver writer. However, i’ve seen this question come up several times, and the answer was usually something like this:
It depends on the kind of state-change. If the state-change itself is heavy-weight, like switching a shader or something else, that might have a big impact on performance, then the driver will almost certainly check for redundant state-changes.
However, if you change a state, that is very light-weight, then the driver will simply set this state, even if it is already set.
So, the gist of this is: Change your states, as you wish. It should not lead to any speed improvement, if you check for redundant state-changes. Everybody says, you should reduce state-changes, but that means, that you should group objects, that use the same configuration of states and then render them in one bunch. Only REAL state-changes hurt performance.
However, if anybody else has more inside information, i’d like to here that, too.
It should not lead to any speed improvement, if you check for redundant state-changes.
Nope. Stating the obvious, any call not done into the OpenGL driver is faster than one done.
An if-statement checking a small state cache for redundancy in your app is much faster than calling a function, jump through OpenGL32.dll, having OpenGL check the input parameters for validity (in your texture case that requires a lookup of the texture object), for redundancy and return.
If it’s simple for your application to check for redundant state, yes, do that. (This is from personal experience.)
You’d also avoid switching the ActiveTexture around, which makes two calls for the bind.
And step 6 looks redundant as well. Couldn’t resist…
Ok, at last someone, who has seen a difference! I did implement “state-change prevention” ™, but haven’t seen a difference in speed. Which of course only means, that i was not state-change limited.
But you’re right, that there is overhead involved, even with simple state changes. Still, the overhead to redundantly change a complex state won’t be very high, since the driver will prevent those changes, it will only have the “usual” overhead of calling a DLL-function etc.
yeah ive tested before
doing the check yourself is faster which is logical
also by doing the check u can also check other things eg clearing the depth buffer with glDepthMask( GL_FALSE );
Ok, got it, you mean checking the state cache for silly states.