Archived

This topic is now archived and is closed to further replies.

State changes: avoid as much as possible?

This topic is 5443 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''ve read that to speed up an application as that one should avoid as many state changes as possible. Ofcourse, this is logical, but what if you call glDisable on a state that already was disabled? For example, if I have GL_TEXTURE_2D disabled, and then call glDisable(GL_TEXTURE_2D), will OpenGL then only change a boolean, or will it go deeper down and make many more calls? Would it be wiser to check a state with glIsEnabled, and act accordingly? Thank you!

Share this post


Link to post
Share on other sites
I''m curious too. How big of a deal is it to make a call like: glEnable (GL_LIGHTING)?

Or: glEnable (DEPTH_TEST)?

Or any of the other ones. Sometimes, I feel that the call is only setting a switch, and the expense of the call is pretty much nonexistent.

Share this post


Link to post
Share on other sites
>>Ofcourse, this is logical, but what if you call glDisable on a state that already was disabled?<<

even if its already disabled dont call it, it will hurt performance do the checking yourself
eg

void setglLighting( const bool on )
{

if ( !on && gl_lighting_currently_enabled )
{
glDisable( GL_LIGHTING );
gl_lighting_currently_enabled=false;
return;
}
if ( on && !gl_lighting_currently_enabled )
{
glEnable( GL_LIGHTING );
gl_lighting_currently_enabled=true;
}

http://uk.geocities.com/sloppyturds/kea/kea.html
http://uk.geocities.com/sloppyturds/gotterdammerung.html

Share this post


Link to post
Share on other sites
Working for 4 months at my engine, I can safely tell you that state changes are totally inexpensive. I enable/disable lighting (and backface cooling, z buffer, etc. at LEAST 3 times/frame (sometimes even 20 times) and there is no penalty whatsoever.
And this is on a Vanta TNT2 8 MB

Share this post


Link to post
Share on other sites
Well, that''s good to hear. But 3 or 20 times isn''t that much. Let''s say you have lots of things, say, hundreds of billboarded trees, many many objects, etc. Let''s say each object has it''s own set of rendering parameters. Short of sorting the objects according to state criteria, each object needs to undergo a set of state changes before being rendered. Let''s just say that you''ve got 1,000 objects. Let''s say each object has 10 state parameters associated with it. That would be 10,000 state changes per frame.

Share this post


Link to post
Share on other sites
Think of what the call is doing (or might be doing if you aren''t familiar with the details of a typical rendering pipeline) and you can guess what is going to be expensive and what isn''t.

Binding a different texture will be expensive because it involves moving data around internally.

Turning texturing/lighting/depth r/w/rasterization on/off isn''t going to be that expensive because it just involves skipping over a section of the pipeline.

Changing one of the 3 main matrices will be a little more expensive because the data has to be sent across the bus, you don''t want to repeat that unecessarily too often.

And so on and so forth...

------------
- outRider -

Share this post


Link to post
Share on other sites
quote:
Original post by bishop_pass
Well, that''s good to hear. But 3 or 20 times isn''t that much. Let''s say you have lots of things, say, hundreds of billboarded trees, many many objects, etc. Let''s say each object has it''s own set of rendering parameters. Short of sorting the objects according to state criteria, each object needs to undergo a set of state changes before being rendered. Let''s just say that you''ve got 1,000 objects. Let''s say each object has 10 state parameters associated with it. That would be 10,000 state changes per frame.


That''s exactly what I am doing
My 3D objects have this flags (on or off):

Alpha blended
Have transparency
Recive light (or have the same light no matter what, like for light sources)

The objects that have transparency need alpha testing, and the backface culling is disabled.
I usually have about 10-20 objects in the scene (it is an isometric engine), but they can be drawn 3 times, when the shadows are enabled, and they are near the water (reflections).
Sure, not all the state changes take place when drawing the shadows and reflections, but, still...
So, I can have about 200 state changes per frame, and there is no difference.



Height Map Editor | Eternal lands

Share this post


Link to post
Share on other sites
quote:

Turning texturing/lighting/depth r/w/rasterization on/off isn''t going to be that expensive because it just involves skipping over a section of the pipeline.


If it only were that easy. It''s not what the new state itself means to the pipe, it''s about how expensive the actual state change is. Turning, say, texturing on and off is not just to set/reset a bit and then skip/not skip that part of the pipe. Say I have a certain state setup which fully uses the hardware, and then I enable something that was previously disabled. The driver must now perform an analysis of the new state setup and determine whether it can perform it in hardware or must fall back on a software solution. It''s this analysis you should avoid by not doing redundant state changes.

Share this post


Link to post
Share on other sites
I had the same problem.. I decided that the best thing to do was to find out how time consuming each state change call was. Them in order from most expensive, I made my engine so that it relatively cheaply renders the object in order according to the state changes... Now this definately isn''t the way to go when you end up with large overdraw, but if you have overdraw, you have other things to worry about...

The way I have my engine set up, Everything is drawn in groups based on its texture. The way I have my textures set, up this also indirectly sorts the objects by if they need shadowing/lighting/ect. Just a thought....



"The only thing worse than not having that new _______ , is when some rich kid has it, but can''t and/or doesn''t appreciate it."-me
Tazzel3d ~ Dwiel

Share this post


Link to post
Share on other sites
quote:

Say I have a certain state setup which fully uses the hardware, and then I enable something that was previously disabled. The driver must now perform an analysis of the new state setup and determine whether it can perform it in hardware or must fall back on a software solution. It''s this analysis you should avoid by not doing redundant state changes.



On drivers for specific cards this shouldn''t be an issue. If the driver is written for a specific card then it shouldn''t have to test anything or query the card for any information, it should be hardcoded.

Unified drivers can also avoid this. Once a rendering context is created the driver can query the card for what it supports and save that information. If any unified driver queries the card every time you turn on 3D textures to see if it supports it then someone somewhere is an idiot. Once a rendering context is created there''s no way the user can switch cards while it is active so this only needs to be done once.

------------
- outRider -

Share this post


Link to post
Share on other sites
Thanks people, I got a lot of answers here. But what about the function glIsEnabled()? Does this return a simple boolean that is kept within the OGL state machine, or does it also go down to the driver to check on the state?

Raduprv, a different question, you are talking about fillrate, I assume that has to do with filling up huge polygons. Can performance be increased by splitting up the polygon and drawing all small ones?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Structural
Raduprv, a different question, you are talking about fillrate, I assume that has to do with filling up huge polygons. Can performance be increased by splitting up the polygon and drawing all small ones?


No performance might actually decrease because there are more polygons to transform. Fill rate is how fast your pixel pipeline works.

Share this post


Link to post
Share on other sites
quote:

On drivers for specific cards this shouldn''t be an issue. If the driver is written for a specific card then it shouldn''t have to test anything or query the card for any information, it should be hardcoded.


Hardcoded or not, it still have to determine whether it can do it or not in hardware. I don''t know exactly what you meant by hardcoded, if you mean to check for combinations of states, or check individual states, or anything else. But one thing is clear, you can''t check individual states to determine what to do. An example, unless I''m wrong, both texturing and polygon stipple is supported by the hardware on GF2. But since polygon stipple eats a texture unit, the driver will fall back on software if all texture units are used by texturing and polygon stipple it used. So it''s not individual states, but combination of stated, which makes it more complicated.

Even though redundant state changes should be avoided is possible, there are other bottlenecks that are likely to show up before. Algorithmic and fillrate bottlenecks for example.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
How and why should a polygon stipple use up a texture unit?
Stipple is in screen space .. hmm maybe using some form of auto texgen..
Are u really sure its uses a texture unit?

Share this post


Link to post
Share on other sites
I''m not 100% sure, but almost. You can see polygon stipple as a form of texturing, so it''s not a complete surprise it uses a texture unit of all things. I assume they did so because it was an minor modification to the texture units (in fact, it may even be possible to get away with no modification), and get hardware suport for polygon stipple almost for free (free as in no extra silicon needed), but at the cost of not being able to use a texture unit. An OK tradeoff if you have at least three texture units, but maybe a bit too restrictive if you only have two.

Share this post


Link to post
Share on other sites