Skip to content

CommonStates

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

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

Related tutorials: Sprites and textures

Header

#include <CommonStates.h>

Initialization

The CommonStates constructor requires a Direct3D 12 device.

std::unique_ptr<CommonStates> states;
states = std::make_unique<CommonStates>(device);

For exception safety, it is recommended you make use of the C++ RAII pattern and use a std::unique_ptr or std::shared_ptr

Many methods of this class are static. You do not need to create an instance of CommonStates to use them.

Usage

The static methods provide 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.

Static Sampler State

XNA Game Studio

Each of these takes a shaderRegister, a shaderVisibility which defaults to D3D12_SHADER_VISIBILITY_ALL, and registerSpace which defaults to 0.

  • static const D3D12_STATIC_SAMPLER_DESC StaticPointWrap(shaderRegister, shaderVisbility, registerSpace);
  • static const D3D12_STATIC_SAMPLER_DESC StaticPointClamp(shaderRegister, shaderVisbility, registerSpace);
  • static const D3D12_STATIC_SAMPLER_DESC StaticLinearWrap(shaderRegister, shaderVisbility, registerSpace);
  • static const D3D12_STATIC_SAMPLER_DESC StaticLinearClamp(shaderRegister, shaderVisbility, registerSpace);
  • static const D3D12_STATIC_SAMPLER_DESC StaticAnisotropicWrap(shaderRegister, shaderVisbility, registerSpace);
  • static const D3D12_STATIC_SAMPLER_DESC StaticAnisotropicClamp(shaderRegister, shaderVisbility, registerSpace);

Typical usage

The static sampler used by SpriteBatch if you don't provide an explicit sampler descriptor is StaticLinearClamp.

StaticAnisotropicWrap is the default static sampler in DirectX 12.

Sampler state

This class also provides heap-based descriptors for use with Effects and to override the default SpriteBatch static sampler.

  • D3D12_GPU_DESCRIPTOR_HANDLE PointWrap() const;
  • D3D12_GPU_DESCRIPTOR_HANDLE PointClamp() const;
  • D3D12_GPU_DESCRIPTOR_HANDLE LinearWrap() const;
  • D3D12_GPU_DESCRIPTOR_HANDLE LinearClamp() const;
  • D3D12_GPU_DESCRIPTOR_HANDLE AnisotropicWrap() const;
  • D3D12_GPU_DESCRIPTOR_HANDLE AnisotropicClamp() const;

To use these you must provide the CommonStates Heap to the command-list. Usage for the built-in shaders is typically in conjunction with a DescriptorHeap of texture descriptors as follows:

ID3D12DescriptorHeap* heaps[] = { resourceDescriptors->Heap(), states->Heap() };
commandList->SetDescriptorHeaps(_countof(heaps), heaps);

You can also refer to these heap samplers by index using SamplerIndex

  • PointWrap
  • PointClamp
  • LinearWrap
  • LinearClamp
  • AnisotropicWrap
  • AnisotropicClamp

Because SamplerIndex is strongly-named enum to avoid conflicts with the method names, to use it as an integer requires an explicit cast: static_cast<int>( SamplerIndex::AnisotropicWrap )

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