glBindTexture Optimization

Hi there!

I read in SIGGRAPH 2000 Course “Advanced Graphics Programming Techniques Using OpenGL” that:

The details of switching textures varies depending on your OpenGL implementation, but suffice it to say that OpenGL implementations are inevitably optimized to maximize texturing performance for whatever texture is currently bound so changing textures is something to minimize. Real-world applications often derive significant performance gains by sorting by texture the objects that they render to minimize the number of glBindTexture() commands required to render the scene

… My question is: Does calling glBindTexture twice for the same TextureObjectID produce slowdown? (I want to know if the current OpenGL 2.0 implementation skips the command glBindTexture if the TextureObjectID passed is the same as the previous one.)

The reason I need this answer is because my engine is display-list based (for the majority of the objects, except the particle system, since I like the fact that all GL states are saved) and I cannot skip a glBindTexture manually (with a C++ IF, for example, saving the state) since DL cannot be modified of course. Therefore I wanted to know if I will improve perfomance or not by sorting the objects by texture, even though the number of glBindTexture calls is not reduced.

Thanks so much!
Rod

Does calling glBindTexture twice for the same TextureObjectID produce slowdown?
The OpenGL specification document does not include a statement that calling glBindTexture with the same texture object will induce a slowdown. It also does not say that it won’t. It is implementation-defined behavior.

…then what has everyone’s experiences proven!?

will calling glBindTexture cause a slowdown generally? i thought it was unnoticeable…

It was very noticeable for me. It’s a recommended performance enhancement to make as less GL calls as possible.
I’m sure calling glColorXX and some other func like glLoadIenity doesn’t matter, but other calls should be avoided. Avoid glGetInteger, glGetFloat entirely.

It will help for any GPU you have.

theres a saying along the lines of
the fastest code is the code that is not executed
ie dont call any functions unnecessary if youre concerned about speed

…then what has everyone’s experiences proven!?
That you should optimize later. Get it working now, then profile to see where you should bother optimizing.

Thanks Korval,
but the thing is that I’ve already gotten it working. I am now working on redesigning my whole engine, so I was wondering if to include a glBindTexture optimization or not…

Thanks

I am now working on redesigning my whole engine
If your redesigned engine isn’t working yet, then you aren’t yet at the point where you should be optimizing it.

Furthermore, all it would take to change it is to keep a global/static variable around that says what the previous value was and check it in a wrapper around glBindTexture. Hardly an onerous change.

Thanks for your answer.

Originally posted by Korval:
If your redesigned engine isn’t working yet, then you aren’t yet at the point where you should be optimizing it.
:! yes I know… but I am trying to avoid pitfalls… I already changed the design of my engine many times during the last weeks… so I was expecting to collect some information before continuing coding, and recoding…

Maybe I wasn’t specific enough:
Since I am using DL I got the following two options:

  1. Include glBindTexture inside DL expecting that consecutive glBindTexture calls won’t affect so much (even though if it is same TextID, when calling the same DL multiple consecutive times).
  2. Exclude the glBindTexture calls out of the DL, and use a wrapper storing the previous value of the TextID. (although I’ve heard from some members of this forum that glBindTexture produces less performance hit if put INSIDE Display Lists)

I guess I’ll try both and see if there is any difference.

Cheers

Since I am using DL
Once again, you’re optimizing at the wrong time.

You shouldn’t be thinking about display lists unless you have already proven that you need them.

What if you spend all this time on bind texture and find out that it didn’t matter?

Knuth: “We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.”

Redundant state changes hurt performance. A well designed application will not send redundant state changes. A moderately well designed application will filter redundant changes before sending them to the GL. A badly designed application depends on the GL to handle this efficiently, and we try, with limited success.

To [redundantly] answer the original question, yes, binding textures (even the same texture) can hurt performance – but as Korval says, you might never come up against this particular speed limit if you’re fill-limited or geometry limited, etc…

OTOH, most apps I’ve worked on were greatly affected by API calls and state changes – esp. those calls that adversely affect SIMD hardware (e.g., lighting enable, where a state change could cause all units to flush and load the new state).

Frankly, I wouldn’t expect driver writers to spend too much time optimizing this simple case because if textures come in randomly, there won’t be much gain, and if they’re sorted, then the app developer is probably on top of the issue. The kind of win I’d expect them to look for is some kind of binning/batching on the fly, which is hard.

As for premature optimization, it’s a mixed bag. If you’re building a general purpose engine, you can’t simply load one database and see where the bottlenecks are. The bottlenecks may change, even across parts of one big database. And so good/efficient design paths are also important early on (just don’t waste time or box yourself into a corner). I’d personally say that blind adherence to any single credo is the root of all evil. :wink: