Jump to content


DX10/DX11 Object States Caching: the Just Cause 2 way ...


22 replies to this topic

#21 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 05 December 2011 - 03:22 PM

View PostAnthonyW, on 03 December 2011 - 05:50 PM, said:

My system would definitely still work in a multiplatform way, I just chose to use D3D11 types to make it obvious. 'StateKey' is already multiplatform in the example above. The two state objects that are parameters to GetStateKey() simply need to be made in a platform independent way as well... and then you can hide the implementation behind an interface of some sort.

Here's how it could look if written more properly.

struct RasterizerState { /* ... for all intents and purposes, you could just copy D3D11_RASTERIZER_DESC ... */ };
struct DepthStencilState { /* ... again, copy D3D11 */ };

struct IRenderStateManager
{
	virtual StateKey GetStateKey(RasterizerState raster, DepthStencilState depth) = 0;
	virtual void BindState(StateKey key) = 0;
}

The D3D implementation would be almost exactly as the previous sample, except that it would have to map or convert from our platform independent state objects to the D3D11 equivalents before rendering.

The OpenGL implementation could instead look something more like.

class OpenGLRenderStateManager : public IRenderStateManager
{
	std::vector<RasterizerState> rasterizerStates;
	std::vector<DepthStencilState> depthStencilStates;
	StateKey currentStateKey;										   // currentState (for state caching)

public:
	virtual StateKey GetStateKey(RasterizerState raster, DepthStencilState depth)
	{
		// pretty much the same as for D3D only we're storing our StateStructs directly, instead of storing the ID3D11*State objects in our std::vectors (since obviously, opengl doesn't have a direct equivalent)
	}

	virtual void BindState(StateKey key)
	{
		if (key == currentStateKey)
			return;

		BindDepthStencilState(key);
		BindRasterizerState(key);

		currentStateKey = key;
	}

private:
	void BindDepthStencilState(StateKey key)
	{
		if (key.depthStencilIndex == currentStateKey.depthStencilIndex)
			return;

		DepthStencilState& newState = depthStencilStates[key.depthStencilStateIndex];
		DepthStencilState& currentState = depthStencilStates[currentStateKey];

		if (newState.DepthEnable != currentState.DepthEnable)
		{
			if (newState.DepthEnable)
				glEnable(GL_DEPTH_TEST);
			else
				glDisable(GL_DEPTH_TEST);
		}

		// ... other states
	}
}

Hope this help. Anyway, I purchased GPU Pro from Amazon, I expect it to arrive Monday. So... I'll read it and get back to you. Although, the system I've described should work reasonably well for you.

Best of luck.

Yeah I know your approach and it was my first idea. Then during my research and because I wanted to have something flexible and simple enough to map states accross different platforms (e.g. consoles too) in the most transparent way, I've found the approach described in gpu pro to be quite interesting to experiment with. It is actually part of the whole description of the approaches that the guys that developed Just Cause took to implement many other things, not only states management. So, have a look in the post-mortem part of GPU Pro.

#22 AnthonyW

    New Member

  • Members
  • Pip
  • 6 posts

Posted 06 December 2011 - 02:48 AM

Ah, sounds cool. Guess I'll just have to wait until the book arrives. :)

#23 SuperPixel

    Valued Member

  • Members
  • PipPipPipPip
  • 306 posts

Posted 07 December 2011 - 12:12 PM

View PostAnthonyW, on 06 December 2011 - 02:48 AM, said:

Ah, sounds cool. Guess I'll just have to wait until the book arrives. :)

Once you've read about the state management part I'd like to discuss with you about it :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users