# How to change render states only when necessary?

Earlier, I have been setting render states (shaders, shader resources, etc.) without checking if it is really necessary. Maybe they had been bound earlier and I could use them without setting them again.

So now I am checking for currently set render state before setting it. If there is a mismatch, then I set it. Setting a pixel shader for example:

typedef ID3D11DeviceContext*        DeviceContext;

if(context!=nullptr){
if(s!=nullptr)
s->Release();
}
}


I wonder if it is a welcome practice to get current render state from the device context context so often, or should I roll my own solution for checking them? Keeping pointers for currently bound states for example and checking with those?

I ask this now, because I only started implementing this for some states (PSSetshader and PSSetShaderresources), and I have a lot more, so I would opt-out early if this method could be problematic.

• Speculation: DirectX was written by really smart people... there's a good chance they do this check also. – david van brink Dec 3 '14 at 21:49
• @davidvanbrink You will want to do this state checking even under DirectX. While it was written by smart people, it was also written by people who understand that engineers are going to develop engines on top of it. They leave state shadowing up to the client because we might implement it in specific ways they can never anticipate. – Steven Dec 4 '14 at 3:49

PSGetShader (and in general, all state getters in D3D) are not intended to be called at high frequency. You should do dirty state tracking, and you should implement it yourself. Using PSGetShader will at a minimum create the additional overhead of the AddRef which you don't need for dirty state tracking.
• If you already know when you need to change state (versus only what state is required), then you can bypass events altogether and just set the state immediately. The fact that the question asks about state tracking suggests that at run-time the engine does not know what needs to change, just what needs to be set. So e.g. to render the Enemy mesh, you know that it requires CharacterPS to be set, but you don't know what's currently set. If you just drew Player mesh, you might not need to change. If you just drew DungeonWalls, you probably do. Ordering might not be deterministic. – MooseBoys Dec 3 '14 at 23:12