Forgive me, because I know this question has been asked before several times, but I’ve come across several different answers. Some people have claimed that drivers don’t do duplicate state changes, others claim that they do.
It would make sense for a driver to use kind of a lazy evaluation approach imho. Keep track of the state changes and only update the state when you actually have to render something.
Suppose I was frequently changing the following states:
-texture enables 2D, RECT
-vertex array enables
-enables for blending, lighting, two sided lighting, cull face setting, line smooth, fill mode… etc
Would it be better for my wrapper:
to check each state to see if has changed and only call glEnable() on the changed ones, or
is it more efficient to do things brute force and just set them all?
I’ve heard there is a large overhead with changing the first state and then any other states that you change at the same time incur only a small performance penalty. (this is the reason for DX state blocks)
Is it worth it (performance wise) to write a wrapper around my commonly changed OpenGL states so as to not to set the same state twice… or do most drivers already check for this as an optimization?
I realize this whole question is pretty implementation dependent… ATI and Nvidia could do 2 separate things.
Drivers often will not attempt to merge redundant state and often even trivial seeming optimizations will not be done. The philosophy is keep it simple and fast so smart applications developers will get the best performance. If a popular app or benchmark ships with some heinous misuse of the API the driver might fix that issue.
It is always advisable to eliminate your own redundant state. This way if the driver writer has optimized for well written software you will be in good shape. In addition as a general rule set state before you enable a feature, so any glEnable() call you make should come after the setup for that feature’s parameters to save redundant pipeline validation of your state.
This is generic good practice even if a specific feature or implementation does not need this, some features on most implemetations and most features on some implementations will benefit.
i’ve often wondered this myself… its good to have a solid answer. i will kestoep that glEnable bit in mind in the future as well.
still my general strategy has always been to program seperate paths for states. one path for the extremely flexibe states (like say debugging and content creation) and another straight path for the most likely state combinations when performance might be crucial.
still though, even though i usually change states pathalogically on the flexible path (just because this philosophy tends to produce much more intelligible code) i’ve never actually noticed any kind of detectable performance hit/gain between the two. of course i figure there are major states that you don’t want to full around with interleaving no matter how doing so might be easier to code with.
I have a rather good evidence of nvidia drivers using your idea. A lot of nvidia presentations imply it. The real state change seems to happen if you call the rendering command like glBegin.