A simple question about performance

Started by
5 comments, last by hplus0603 18 years, 3 months ago
Hi there. Suppose I need to set many render states and lights, but they will not be changed when the application is running. I would like to know if there is a performance difference among: 1) Setting all the render states and lights before the game loop. 2) Setting all the render states and lights in the game loop, only once per frame. Thanks in advance Edited: Sorry... I was thinking in Direct3D, but I see now that it would be better to post this in the Game Programming forum.
Advertisement
The first option is definitely better. Each state set requires a read and write to memory to set a state variable and the less of these you have the faster the application will run. If it isn't going to change, better to set it once rather than constantly resetting a value in a loop.
"Imagination is more important than knowledge" - A. Einstein
Actually, I don't think the performance loss would be large at all.

The main problem with setting renderstates, is that in order to change them, the GPU has to stop everything it is currently doing, set the state, and start over. If this happens many times per frame, it could really slow you down.

Now, if you set everything up at the begining of the frame, the GPU is idle, so it wouldn't have to stop. In addition, if the states are already set to the correct values, the calls might be skipped by the driver.

I'd recommend you Do what is easier for you in your app. The difference is so small it isn't worth the effort to build your application around this limitation. If it doesn't matter, go with the first one.
Sirob Yes.» - status: Work-O-Rama.
Quote:Original post by Aurvandil
The first option is definitely better. Each state set requires a read and write to memory to set a state variable and the less of these you have the faster the application will run. If it isn't going to change, better to set it once rather than constantly resetting a value in a loop.

Thanks Aurvandil!

Doesn't Direct3D internally configure the render states in the rendering process, to each frame? Wouldn't this be like the option 2?
Quote:Original post by sirob
Actually, I don't think the performance loss would be large at all.

The main problem with setting renderstates, is that in order to change them, the GPU has to stop everything it is currently doing, set the state, and start over. If this happens many times per frame, it could really slow you down.

Now, if you set everything up at the begining of the frame, the GPU is idle, so it wouldn't have to stop. In addition, if the states are already set to the correct values, the calls might be skipped by the driver.

I'd recommend you Do what is easier for you in your app. The difference is so small it isn't worth the effort to build your application around this limitation. If it doesn't matter, go with the first one.

Thanks sirob! Since Direct3D "checks" render states at each frame, it seems to me that the options 1 and 2 give the same performance...
Whilst your questions seem to have been answered, I thought I'd throw this in...

A general rule of thumb with state changes is "the less, the better" - so if you can reduce the number of state changing calls then that's A Good Thing™. If you can get away with changing them in an OnResetDevice() rather than OnFrameRender() that's an obvious saving.

The other thing is that, as has been said, taking the easy option is perfectly valid (for now). Consider the "Get it right, then get it tight" motto - sort your code out so that it does what you want it to do; then, if performance sucks, go back and examine where it sucks and optimize it.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Doesn't Direct3D internally configure the render states in the rendering process, to each frame? Wouldn't this be like the option 2?


Actually, Direct3D will check whether your state is redundant, and not apply it again, unless your device is created with PUREDEVICE. If it's a "pure" device then it'll skip all those checks (which may take a bit of time), but it will funnel all changes through to the card, even if the change is redundant. If you have good state management in the app, PUREDEVICE is actually faster.

If there are specific states you need, one approach is to create a state block with those states, and apply that state block when you need the device to be in that particular state. State blocks are pretty flexible; similar to display lists on OpenGL, except you can change them after they're created, and they can't actually issue geometry.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement