Sign in to follow this  
jdub

Managing State

Recommended Posts

I am noticing that a lot of errors are cropping up in my directX application because I am setting values (depth/stencil state, raster state, etc.) when doing rendering operations and then forgetting to unset those values.  In d3d9, it appears that issues similar to this could be managed using state blocks.  I'm wonder: what is the best way to implement the same functionality in d3d11?  Are there any existing implementations in use that people find to work well?

Share this post


Link to post
Share on other sites

I wrap up every API in a stateless abstraction. e.g. at the lowest level, every renderable object is made up of (or dynamically creates per frame) DrawItems similar to below.

The renderer then just knows how to consume these DrawItems, which fully define the underlying API state, so it's impossible to accidentally forget to unset some previous state.

enum DrawType { Linear, Indexed, Indirect; }
struct Resources { vertex/instance/texture/cbuffer pointers };
struct DrawItem { u8 raster; u8 depthStencil; u8 blend; u8 primitive; u8 drawType; u16 shader; u16 inputLayout; Resources* bind; u32 vertexCount; u32 vbOffset; u32 ibOffset; };
typedef vector<DrawItem*> DrawList;

Share this post


Link to post
Share on other sites

Although not being as explicit as possible, the following approach may make a transition from the existing implementation easier:

 

Based on what Hodgman has written above, but for cases where not the entire state vector is put into each DrawItem, a reasonable default setting can be defined (perhaps dependent on the active graphic pipeline stage). Any explicitly set state overrides its default equivalent, of course. From the low level renderer's point of view, each draw call then has an entire set of state.

 

In practice, at the beginning of the draw call processing, the default set of states is copied onto a local set of states. The state as available by DrawItem is then written "piecewise" onto the local set. Then the local set is compared with the state set that represents the current GPU state, and any difference cause a call to the render context as well as adapting the latter set accordingly.

Edited by haegarr

Share this post


Link to post
Share on other sites

In practice, at the beginning of the draw call processing, the default set of states is copied onto a local set of states. The state as available by DrawItem is then written "piecewise" onto the local set. Then the local set is compared with the state set that represents the current GPU state, and any difference cause a call to the render context as well as adapting the latter set accordingly.

I actually do this kind of "layering" earlier, and the result is a "compiled" DrawItem structure biggrin.png
Often I have multiple state vectors being overlaid, such as defaults on the bottom, shaders-specific defaults on top of that, then material states, then per-object states, then per-pass overrides.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this