Dx11 Renderstate

Started by
5 comments, last by TheChubu 7 years, 9 months ago

Hellow everyone.

I learn dx11 recently, and find the dx11 render state is strange, why the render state is designed to an object?

I think the context->setRS(xxx) is more flexible to use. such as depth enable, I just only to store depth enable = true,

setMaterial(material)
{
if(material.context.depthenable == true); context->setRS(depthenable, true);

else context->setRS(depthenable, false);

}

Some Book, sb, create some render state which is often used like blend, back face cull, it start to look a little better, but good times

don't last long, since the object encapsule several sub state,

when I want to use a new state which is a little different from those created states (such as blend-add is very similar to blend-alpha),

I have to create a new one.

I don't know how to easy to handle the dx11 render state object. Who can show me how you use these ridiculous things?

Advertisement
You could create your own state manager to make things easy and flexible. It's investing once but you can make it exactly as you want and need it. That way you can also make sure you don't do any redundant state setting.

As for the "ridiculous", I personally think it's pretty useful to be able to change states :)

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

You could create your own state manager to make things easy and flexible. It's investing once but you can make it exactly as you want and need it. That way you can also make sure you don't do any redundant state setting.

As for the "ridiculous", I personally think it's pretty useful to be able to change states :)

How to make one?

This topic might be interesting, just as an example.

Even though it's d3d9, the idea should be perfectly reusable:

http://www.gamedev.net/topic/647102-state-manager-code-review-suggestions/

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This might help:

https://irlans.wordpress.com/2015/08/25/reducing-reduntant-state-changes-from-directx-11-0/

I learn dx11 recently, and find the dx11 render state is strange, why the render state is designed to an object?

Because of performance. Setting one at a time takes a lot more cycles as opposed to setting all of them at once.
Furthermore many parameters are actually inter-linked with each other, even if they appear completely unrelated:

  • For example modern GPUs require shaders to know the vertex layout (Input Assembly in D3D11 terms).
  • Depth write settings interact with alpha testing (to know whether to disable early Z optimization).
  • Cull mode interacts with shaders if the shader uses SV_IsFrontFace.
  • On certain mobile GPUs, blending modes are patched into the shaders.
  • Cull mode interacts with stencil (i.e. two sided stencil)

Because of these dependencies at the implementation level with seemingly unrelated features, changing the setting one by one would have to trigger a lot of flushing, whereas changing everything in one go allows for resolving all the dependencies because all of the data is supplied together (and validated beforehand by making the object immutable!).

TL;DR: Performance.

setMaterial(material)
{
if(material.context.depthenable == true); context->setRS(depthenable, true);
else context->setRS(depthenable, false);
}
I don't know how to easy to handle the dx11 render state object. Who can show me how you use these ridiculous things?


You're approaching it the wrong way, the D3D9 way. In order to approach the D3D11 way, you need to create your object beforehand:


struct Material
{
    bool mDepthEnabled;
    bool mDepthWriteEnabled;
    // ... many other settings

    ID3D11RasterizerState *mRasterizerState;
    ID3D11BlendState *mBlendState;
    ID3D11DepthStencilState *mDepthStencilState;

    //Always call after you're done modifying the material.
    void flush()
    {
        SAFE_RELEASE( mRasterizerState );
        SAFE_RELEASE( mBlendState );
        SAFE_RELEASE( mDepthStencilState );
        D3D11_RASTERIZER_DESC rasterizerDesc;
        D3D11_RENDER_TARGET_BLEND_DESC blendDesc;
        D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
        depthStencilDesc.DepthEnable = mDepthEnabled;
        depthStencilDesc.DepthWriteMask = mDepthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ZERO : D3D11_DEPTH_WRITE_MASK_ALL;

        //...Fill ALL the other settings...

        device->CreateRasterizerState( rasterizerDesc, &mRasterizerState );
        device->CreateBlendState( blendDesc, &mBlendState );
        device->CreateDepthStencilState( depthStencilDesc, &mDepthStencilState );
    }
};

void setMaterial( material )
{
     //ASSUME material already has been flushed.
     assert( material->mRasterizerState && "You forgot to call flush!" );
     device->RSSetState( material->mRasterizerState ); //You could check if this is redundant. If it is, avoid calling again
     device->OMSetBlendState( material->mBlendState );//You could check if this is redundant. If it is, avoid calling again
     device->OMSetDepthStencilState( material->mDepthStencilState );//You could check if this is redundant. If it is, avoid calling again
}

The idea is simple: Create the material. Once it's set, initialize the D3D11 structures. This is all done at loading time, not every frame. Once that's done, don't modify the material frequently (at least the parts that need flushing). If you need to change parameters very often, it's better to use multiple materials instead.

Moreover, think that you wont have *that* many crazy combinations of state. The APIs tend to be way, way more flexible than what you really need. Its not about providing everything the API allows you to do, but to restrict it to an useful subset of features.

With all render passes and materials known before hand (and you will know them), you can easily create all the state objects you'll need. After that you can proceed like Mathias suggested, switching them (whole) as necessary.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

This topic is closed to new replies.

Advertisement