OpenGL State Sorting

Started by
8 comments, last by Fingers_ 16 years, 1 month ago
Greetings everyone, I am currently trying to implement a scenegraph that does some state sorting. But I am having a bit of trouble pinpointing which state changes are the most expensive computationally. For example, Which is faster, binding a texture (glBindTexture()) or doing a simple transformation (glTranslate(), etc). I know its a long shot, but is there a list of GL and the amount of computations required for changing a state? Thanks for your time.
------------Anything prior to 9am should be illegal.
Advertisement
Quote:I know its a long shot, but is there a list of GL and the amount of computations required for changing a state?


I'm not sure such a chart would be useful since the amount of effort for each state change will vary quite a bit depending on what video card (if any) and driver combination you happen to be using. For example, some drivers will use 3DNow or SSE to perform their transforms, some will use hardware on the card, and others (mostly very old PCs) will do it entirely in software.

Generally speaking, though, texture binds tend to be quite expensive, whereas matrix operations are very cheap, to answer your specific question.
Ah ok,

How would these fit into the grand scheme of things:

(Most Expensive) Texture Binds
(Least Expensive) Matrix Transforms


- glEnable() / glDisable() calls? (Blending, Depth, etc) ?????
- glTexEnvf() (texture mode changes, multi texturing, etc) ??????
- perspective <-> ortho changes (2D/3D drawing) ????


Those are pretty much the majority of my GL interactions.
------------Anything prior to 9am should be illegal.
Quote:Original post by RealMarkP
Ah ok,

How would these fit into the grand scheme of things:

(Most Expensive) Texture Binds
(Least Expensive) Matrix Transforms


- glEnable() / glDisable() calls? (Blending, Depth, etc) ?????
- glTexEnvf() (texture mode changes, multi texturing, etc) ??????
- perspective <-> ortho changes (2D/3D drawing) ????


Those are pretty much the majority of my GL interactions.


There is a very good thread on the subject here: http://www.gamedev.net/community/forums/topic.asp?topic_id=416620

Generally speaking, the short answer is: don't worry about it. Keep really expensive stuff like texture changes and buffer clears down, but other then that you really should only worry about it if you're seriously strapped for CPU cycles.

I found a really good blog posting on this subject:

http://home.comcast.net/~tom_forsyth/blog.wiki.html
-----------------------------------Indium Studios, Inc.
After a while, my position on that have not changed much.
All half-decent drivers won't give you meaningful performance in non-realistic test cases so you're out of luck with that kind of measurement since observation will probably screw the system.

Previously "Krohm"

I also read about the cost of state changes, especially glBindTexture(), and came to the same conclusion, that implementing a texture-state oriented scene-graph for my game engine would be the most sensible thing to do.

I ran a few tests however and can't confirm the supposedly high cost associated with glBindTexture(). Creating a test scene with 18000 sprites using different textures and thereby prompting many glBindTexture() calls yielded 30fps.
Having 18000 sprites using the same texture and implementing a software texture sate check
if (currentTexture != boundTexture)
glBindTexture()

Didn't provide any performance improvement.

You might also want to read up on another one of TomF blog entries:
http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BScene%20Graphs%20-%20just%20say%20no%5D%5D

So right now I think that creating a scene-graph for the sole purpose of supporting some kind of minimal state change mechanism may not be worth the extra trouble of rewamping my engine.
I think that state changes may not be the issue if you only get 30fps when rendering 36000 triangles (or 18000 quads). That's obviously dependant on your hardware, but you should check that something else isn't causing this behaviour before writing off state sorting.
I used a particle system to create that many sprites quickly, and all of those perform a little displacement processing, especially GL transformations, so that's probably where alot of GPU cycles go.
The CPU isn't quite maxed out, so I don't think that the 30fps with or without calling glBindTexture() is due to a CPU bottleneck.

The way I coded it, I'm pretty sure that glBindTexture() gets called once for each sprite per frame when using different textures, and only being called once per frame, when using the same texture.
If bound texture state is that expensive to change, shouldn't there be at least a very small performance benifit for the latter approach?

I don't know. Maybe my test is still flawed, for some reason. Maybe someone can come up with a better benchmark for this.

Still, even if there was a slight performance gain, I'm not sure if it would merit changing the engine design, possibly making it less intuitive and more complicated, just to gain a few FPS. Especially since OpenGL 3.0 is right around the corner and different chips and drivers seem to optimize differently.
Your particle system's performance is probably limited by fillrate if there's a lot of overdraw. Have you tried making the particles very small, or running at a low resolution? The video driver may also be smart and ignore the glBindTexture if you try to bind a texture that's already bound (in case multiple consecutive particles use the same texture).

This topic is closed to new replies.

Advertisement