State Change guarding

Started by
1 comment, last by S1CA 17 years, 10 months ago
Does D3D state change function keeps track of the current state and discard a change that is the same? For example:

pD3Device->SetRenderState( <StateTypeA>, <StateA> );
pD3Device->SetRenderState( <StateTypeA>, <StateA> );

Will D3D know if the second call is redudant internally or do we have to do something like this:

//assume some state saving mechanism

if ( StateType == <StateTypeA> )
{
if ( State != <StateA> )
{
pD3Device->SetRenderState( <StateTypeA>, <StateA> );
}
}

What about for OpenGL?
Advertisement
Yes, it keeps track for you. If you ever look at the debug runtime output, you will probably see a massive stream of messages like this:

Direct3D9: (WARN) :Ignoring redundant SetRenderState 27

By the way, the same goes for sampler states, too. If you have render states and/or sampler states embedded in effect files, it is possible to get these messages generated from there, too.

However, it would be advisable to keep track of these yourself, so that you can avoid the overhead of making a useless D3D call. The memory and processing footprint of doing this should be really low, anyways.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
1) D3D does filter redundant state for you, so:

SetRenderState( A, valueA ) // set on device
SetRenderState( A, valueA ) // filtered
SetRenderState( A, valueA ) // filtered
DrawSomething()

will indeed be filtered out.


2) IIRC with a pure device (D3DCREATE_PUREDEVICE), this filtering might not be performed for you.


3) D3D's state filtering is a trivial "don't call the driver if the state is already set to that value" test, what it won't fix is situations like:

SetRenderState( A, valueA ) // set on device
SetRenderState( A, valueB ) // set on device
SetRenderState( A, valueA ) // set on device
SetRenderState( A, valueB ) // set on device - only value that gets used
DrawSomething()

or

SetRenderState( A, valueA ) // set on device
SetRenderState( A, valueA ) // filtered
SetRenderState( A, valueB ) // set on device - only value that gets used
SetRenderState( A, valueB ) // filtered


4) So, trivial "if (value != currentValue[state])" tests aren't really going to buy you much on a non-pure device apart from avoiding some calls into the D3D DLL.

If you're going to spend time on state filtering, it's more worthwhile to implement a cleverer scheme that takes *groups* of state into account, perhaps 'diffing' between groups of state, perhaps clever stack based schemes, etc - it's even better if you can apply application specific knowledge to the problem (you know which states are coming next, and how they group together...)


5) I don't know enough about the inner workings of OpenGL, so can't offer anything about that (the OpenGL forum on here probably has someone who'll know...).


[edit] heh, Dustin beat me to it.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

This topic is closed to new replies.

Advertisement