Skip to content

CommonStates

Chuck Walbourn edited this page Jul 12, 2016 · 33 revisions

The CommonStates class is a static class which defines the most common combinations of Direct3D rendering states.

Related tutorials: Sprites and textures

Header

#include <CommonStates.h>

Usage

Each state provides a D3D12_*_DESC structure which can be used to create a Pipeline State Object (PSO):

D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.RasterizerState = CommonStates::CullNone;
psoDesc.BlendState = CommonStates::Opaque;
psoDesc.DepthStencilState = CommonStates::DepthDefault;
...
DX::ThrowIfFailed(
    device->CreateGraphicsPipelineState(&psoDesc,
        IID_PPV_ARGS(m_pipelineState.ReleaseAndGetAddressOf())));

They are typically used with EffectPipelineStateDescription:

RenderTargetState rtState(m_deviceResources->GetBackBufferFormat(),
    m_deviceResources->GetDepthBufferFormat());

EffectPipelineStateDescription pd(
    &VertexPositionColor::InputLayout,
    CommonStates::Opaque,
    CommonStates::DepthDefault,
    CommonStates::CullNone,
    rtState);

Blending State

XNA Game Studio

  • static const D3D12_BLEND_DESC Opaque;
  • static const D3D12_BLEND_DESC AlphaBlend;
  • static const D3D12_BLEND_DESC Additive;
  • static const D3D12_BLEND_DESC NonPremultiplied;

Typical usage

For standard drawing, typically you should make use of Opaque.

For drawing alpha-blended objects, you should use AlphaBlend if using premultiplied alpha, or NonPremultiplied if using 'straight' alpha.

For multipass rendering, you'd typically use Additive.

Depth/Stencil State

XNA Game Studio

  • static const D3D12_DEPTH_STENCIL_DESC DepthNone;
  • static const D3D12_DEPTH_STENCIL_DESC DepthDefault;
  • static const D3D12_DEPTH_STENCIL_DESC DepthRead;

Typical usage

For standard rendering with a z-buffer, you should use DepthDefault.

For drawing alpha blended objects (which is typically done after all opaque objects have been drawn), use DepthRead which will respect the existing z-buffer values, but will not update them with 'closer' pixels.

For drawing objects without any depth-sort at all, use DepthNone.

Rasterizer State

XNA Game Studio

  • static const D3D12_RASTERIZER_DESC CullNone;
  • static const D3D12_RASTERIZER_DESC CullClockwise;
  • static const D3D12_RASTERIZER_DESC CullCounterClockwise;
  • static const D3D12_RASTERIZER_DESC Wireframe;

Typical usage

For default geometry winding use CullCounterClockwise. For inverted winding (typically when using assets designed for left-handed coordinates but rendering with right-handed coordinates or vice-versa), use CullClockwise.

For "double-sided" geometry, use CullNone. Keep in mind this is a potentially large performance hit, so use it sparingly.

Wireframe is a wireframe rendering mode and shows both sides of the geometry.

Sampler State

XNA Game Studio

  • static const D3D12_SAMPLER_DESC PointWrap;
  • static const D3D12_SAMPLER_DESC PointClamp;
  • static const D3D12_SAMPLER_DESC LinearWrap;
  • static const D3D12_SAMPLER_DESC LinearClamp;
  • static const D3D12_SAMPLER_DESC AnisotropicWrap;
  • static const D3D12_SAMPLER_DESC AnisotropicClamp;

These helpers return D3D12_STATIC_SAMPLER_DESC versions:

  • CommonStates::StaticPointWrap(shaderRegister, shaderVisbility, registerSpace);
  • CommonStates::StaticPointClamp(shaderRegister, shaderVisbility, registerSpace);
  • CommonStates::StaticLinearWrap(shaderRegister, shaderVisbility, registerSpace);
  • CommonStates::StaticLinearClamp(shaderRegister, shaderVisbility, registerSpace);
  • CommonStates::StaticAnisotropicWrap(shaderRegister, shaderVisbility, registerSpace);
  • CommonStates::StaticAnisotropicClamp(shaderRegister, shaderVisbility, registerSpace);

Typical usage

AnisotropicWrap is the default sampler settings for DirectX 12 and the built-in effects.

Remarks

These common states are equivalent to using the following descriptors:

Blend states

CD3DX12_DEFAULT def;

// Opaque
CD3DX12_BLEND_DESC desc(def);

// AlphaBlend
CD3DX12_BLEND_DESC desc(def);
desc.RenderTarget[0].BlendEnable = TRUE;
desc.RenderTarget[0].SrcBlend =
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
desc.RenderTarget[0].DestBlend =
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;

// Additive
CD3DX12_BLEND_DESC desc(def);
desc.RenderTarget[0].BlendEnable = TRUE;
desc.RenderTarget[0].SrcBlend =
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend =
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;

// NonPremultiplied
CD3DX12_BLEND_DESC desc(def);
desc.RenderTarget[0].BlendEnable = TRUE;
desc.RenderTarget[0].SrcBlend =
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend =
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;

Depth/Stencil states

CD3DX12_DEFAULT def;

// DepthNone
CD3DX12_DEPTH_STENCIL_DESC desc(def);
desc.DepthEnable = FALSE;
desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;

// DepthDefault
CD3DX12_DEPTH_STENCIL_DESC desc(def);
desc.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;

// DepthRead
CD3DX12_DEPTH_STENCIL_DESC desc(def);
desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;

Rasterizer states

// CullNone
CD3DX12_RASTERIZER_DESC desc(D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_NONE,
    FALSE /* FrontCounterClockwise */,
    D3D11_DEFAULT_DEPTH_BIAS,
    D3D11_DEFAULT_DEPTH_BIAS_CLAMP,
    D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
    TRUE /* DepthClipEnable */,
    TRUE /* MultisampleEnable */,
    FALSE /* AntialiasedLineEnable */,
    0 /* ForceSampleCount */,
    D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF);

// CullClockwise
CD3DX12_RASTERIZER_DESC desc(D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_FRONT,
    FALSE /* FrontCounterClockwise */,
    D3D11_DEFAULT_DEPTH_BIAS,
    D3D11_DEFAULT_DEPTH_BIAS_CLAMP,
    D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
    TRUE /* DepthClipEnable */,
    TRUE /* MultisampleEnable */,
    FALSE /* AntialiasedLineEnable */,
    0 /* ForceSampleCount */,
    D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF);

// CullCounterClockwise
CD3DX12_RASTERIZER_DESC desc(D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_BACK,
    FALSE /* FrontCounterClockwise */,
    D3D11_DEFAULT_DEPTH_BIAS,
    D3D11_DEFAULT_DEPTH_BIAS_CLAMP,
    D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
    TRUE /* DepthClipEnable */,
    TRUE /* MultisampleEnable */,
    FALSE /* AntialiasedLineEnable */,
    0 /* ForceSampleCount */,
    D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF);

// Wireframe
CD3DX12_RASTERIZER_DESC desc(D3D12_FILL_MODE_WIREFRAME, D3D12_CULL_MODE_NONE,
    FALSE /* FrontCounterClockwise */,
    D3D11_DEFAULT_DEPTH_BIAS,
    D3D11_DEFAULT_DEPTH_BIAS_CLAMP,
    D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
    TRUE /* DepthClipEnable */,
    TRUE /* MultisampleEnable */,
    FALSE /* AntialiasedLineEnable */,
    0 /* ForceSampleCount */,
    D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF);

Sampler states

// PointWrap
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_MIN_MAG_MIP_POINT,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    0, D3D12_MAX_MAXANISOTROPY, D3D12_COMPARISON_FUNC_NEVER,
    { 0, 0, 0, 0 }, 0, D3D12_FLOAT32_MAX };

// PointClamp
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_MIN_MAG_MIP_POINT,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    0, D3D12_MAX_MAXANISOTROPY, D3D12_COMPARISON_FUNC_NEVER,
    { 0, 0, 0, 0 }, 0, D3D12_FLOAT32_MAX };

// LinearWrap
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_MIN_MAG_MIP_LINEAR,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    0, D3D12_MAX_MAXANISOTROPY, D3D12_COMPARISON_FUNC_NEVER,
    { 0, 0, 0, 0 }, 0, D3D12_FLOAT32_MAX };

// LinearClamp
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_MIN_MAG_MIP_LINEAR,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    0, D3D12_MAX_MAXANISOTROPY, D3D12_COMPARISON_FUNC_NEVER,
    { 0, 0, 0, 0 }, 0, D3D12_FLOAT32_MAX };

// AnisotropicWrap
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_ANISOTROPIC,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    0, D3D12_MAX_MAXANISOTROPY, D3D12_COMPARISON_FUNC_NEVER,
    { 0, 0, 0, 0 }, 0, D3D12_FLOAT32_MAX };

// AnisotropicClamp
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_ANISOTROPIC,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    0, D3D12_MAX_MAXANISOTROPY, D3D12_COMPARISON_FUNC_NEVER,
    { 0, 0, 0, 0 }, 0, D3D12_FLOAT32_MAX };

Further reading

State objects in XNA Game Studio 4.0

Premultiplied Alpha

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Xbox One
  • Xbox Series X|S

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectX Tool Kit for DirectX 11

DirectXMesh

DirectXTex

DirectXMath

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

See also

DirectX Landing Page

Clone this wiki locally