What's the best practice for StateBlock object?

Started by
3 comments, last by GameDev.net 18 years ago
1) Create one StateBlock and reuse it for capture and restore. Only recreate it for device reset. 2) Create a StateBlock for each capture and destroy it after restore. I find 2) is simple and can be used to mimic pushing/popping states but maybe it's bad because of the creation overhead? How do you use state blocks?
Advertisement
It depends what you are trying to do. There are primary two different use cases.

1. Set multiple states with only one call.
2. Use them as storage to make sure that the states are on the same values before and after a render sequence.

For the first case you will need an own block for every combinations of states you want to set. For the second case one state block, which can store everything, will be fine but if you know the states that the sequences change you can create one for each sequence that store only the states that are modified.

But you should not recreate stateblocks inside you render loop as object creation is an expensive operation.
Solution 1)
Because solution 2) will introduce an unnecessary overhead when you have to create the stateblock / delete it each frame.

Edit : here's how I do it :

// the header :// - the first one is used to restore previous states// - the second one is used to set the statesIDirect3DStateBlock9 * m_pStateBlockBackup;IDirect3DStateBlock9 * m_pStateBlock;// in the restore device object method of my framework :// create the state block for the height mapif (FAILED(hr = m_pd3dDevice->BeginStateBlock()))	   return(hr);// set the render states that you want to usem_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);// save the modified render statesif (FAILED(hr = m_pd3dDevice->EndStateBlock(&m_pStateBlock)))   return(hr);// create the state block to restore the render statesif (FAILED(hr = m_pd3dDevice->BeginStateBlock()))	   return(hr);// set the render states that you want to restorem_pd3dDevice->SetRenderState(D3DRS_LIGHTING, true);// save the modified render statesif (FAILED(hr = m_pd3dDevice->EndStateBlock(&m_pStateBlockBackup)))   return(hr);// and then, each frame, I do the following :m_pStateBlockBackup->Capture();  // save the current statesm_pStateBlock->Apply();          // set the one we need// render my entity herem_pStateBlockBackup->Apply();    // restore the previous states


This way, I only capture / restore the states that I modified, and more important : I don't re-create the stateblocks each frame.
I have a question regarding state block usage, too:
I´ve never used them, but I thought about doing so now, so I have no experience with them at all. My naive approach would have been to put a state block into my shader class, which contains all the states the shader (ID3DXEffect) needs to render correctly. I would only destroy / create state blocks on effect / shader destruction / creation. Anything wrong with that?

But there is also the ability to set render states in an .fx-file (in the technique´s passes), which I also never used, because I am pretty unsure when these state changes are applied. Are they applied every time I do a draw call using that technique and pass?
This would seem rather ineffective to me. My guess was that these state changes are applied when I call BeginPass().

Anyway, I would like to know if state blocks are useful for what I´ve described above or if I´d better do the state changes in the .fx-file.

Bump

This topic is closed to new replies.

Advertisement