Pipeline states
Stride gives you total control over the graphics pipeline state. This includes:
- rasterizer state
- depth and stencil state
- blend state
- effects
- input layout
- output description
State is compiled into immutable PipelineState objects, which describe the whole pipeline. They are then bound using a CommandList.
Code: Create state objects
// Creating pipeline state object
var pipelineStateDescription = new PipelineStateDescription();
var pipelineState = PipelineState.New(GraphicsDevice, ref pipelineStateDescription);
// Applying the state to the pipeline
CommandList.SetPipelineState(pipelineState);
The MutablePipelineState class let you set states independently, while caching the underlying pipeline states.
Code: Mutable pipeline state
// Creating the pipeline state object
var mutablePipelineState = new MutablePipelineState();
// Setting values and rebuilding
mutablePipelineState.State.BlendState = BlendStates.AlphaBlend
mutablePipelineState.Update
// Applying the state to the pipeline
CommandList.SetPipelineState(mutablePipelineState.CurrentState);
Rasterizer state
The rasterizer can be set using the RasterizerState property. A set of predefined descriptions is held by the RasterizerStates class. They deal with the cull mode, and should be enough for most use cases:
Code: Set the cull mode
pipelineStateDescription.RasterizerState = RasterizerStates.CullNone;
pipelineStateDescription.RasterizerState = RasterizerStates.CullFront;
pipelineStateDescription.RasterizerState = RasterizerStates.CullBack;
You can create your own custom state. For the list of options and default values, see the RasterizerStateDescription API documentation.
Code: Custom rasterizer states
var rasterizerStateDescription = new RasterizerStateDescription(CullMode.Front);
rasterizerStateDescription.ScissorTestEnable = true; // enables the scissor test
pipelineStateDescription.RasterizerState = rasterizerStateDescription;
Depth and stencil states
The DepthStencilState property contains the depth and stencil states. A set of commonly used states is defined by the DepthStencilStates class:
- Default: depth read and write with a less-than comparison
- DefaultInverse: read and write with a greater-or-equals comparison
- DepthRead: read only with a less-than comparison
- None: neither read nor write
Code: Setting the depth state
pipelineStateDescription.DepthStencilState = DepthStencilStates.Default;
pipelineStateDescription.DepthStencilState = DepthStencilStates.DefaultInverse;
pipelineStateDescription.DepthStencilState = DepthStencilStates.DepthRead;
pipelineStateDescription.DepthStencilState = DepthStencilStates.None;
You can also set custom depth and stencil states. For the list of options and default values, see the DepthStencilStateDescription API documentation.
Code: Custom depth and stencil state
// depth test is enabled but it doesn't write
var depthStencilStateDescription = new DepthStencilStateDescription(true, false);
pipelineStateDescription.DepthStencilState = depthStencilStateDescription;
The stencil reference isn't part of the PipelineState. It's set using SetStencilReference(Int32).
Code: Set the stencil reference
CommandList.SetStencilReference(2);
Blend state
The BlendState and SampleMask properties control blending. The BlendStates class defines a set of commonly used blend states:
- Additive: sums the colors
- AlphaBlend: sums the colors using the alpha of the source on the destination color
- NonPremultiplied: sums using the alpha of the source on both colors
- Opaque: replaces the color
Code: Set the blend state
// Set common blend states
pipelineStateDescription.BlendState = BlendStates.Additive;
pipelineStateDescription.BlendState = BlendStates.AlphaBlend;
pipelineStateDescription.BlendState = BlendStates.NonPremultiplied;
pipelineStateDescription.BlendState = BlendStates.Opaque;
// Set the sample mask
pipelineStateDescription.SampleMask = 0xFFFFFFFF;
You can set custom depth and blend states. For a list of options and default values, see the BlendStateDescription API documentation.
Code: Custom blend state
// create the object describing the blend state per target
var blendStateRenderTargetDescription = new BlendStateRenderTargetDescription();
blendStateRenderTargetDescription.BlendEnable = true;
blendStateRenderTargetDescription.ColorSourceBlend = Blend.SourceColor;
// etc.
// create the blendStateDescription object
var blendStateDescription = new BlendStateDescription(Blend.SourceColor, Blend.InverseSourceColor);
blendStateDescription.AlphaToCoverageEnable = true; // enable alpha to coverage
blendStateDescription.RenderTargets[0] = blendStateRenderTargetDescription;
pipelineStateDescription.BlendState = blendStateDescription;
The blend factor isn't part of the PipelineState. It's set using SetBlendFactor(Color4).
Code: Set the blend factor
CommandList.SetBlendFactor(Color4.White);
Effects
The pipeline state also includes the shaders you want to use for drawing. To bind an Effect to the pipeline, set the EffectBytecode and RootSignature properties of the PipelineStateDescription to the matching values of the effect.
An EffectBytecode contains the actual shader programs. For more information, see Effects and Shaders.
The RootSignature describes the number and kind of resources expected by the effect. The next chapter covers how to bind resources to the pipeline.
Code: Bind an effect
var effectInstance = new EffectInstance(EffectSystem.LoadEffect("MyEffect").WaitForResult());
pipelineStateDescription.EffectBytecode = effectInstance.Effect.Bytecode;
pipelineStateDescription.RootSignature = effectInstance.RootSignature;
Input layout
The pipeline state describes the layout in which vertices are sent to the device through the InputElements and PrimitiveType properties.
The Draw vertices page describes how to create custom vertex buffers and their VertexDeclaration in more detail.
Code: Set an input layout
VertexDeclaration vertexDeclaration = ...
pipelineStateDescription.InputElements = vertexDeclaration.CreateInputElements();
pipelineStateDescription.PrimitiveType = PrimitiveType.TriangleStrip;
Output description
The Output property of the PipelineStateDescription defines the number and PixelFormat of all bound render textures.
For information on how to bind render textures to the pipeline, see Textures and render textures.
Code: Create an output description
var renderOutputDescription = new RenderOutputDescription(GraphicsDevice.Presenter.BackBuffer.Format, GraphicsDevice.Presenter.DepthStencilBuffer.Format);
pipelineStateDescription.Output = renderOutputDescription;
You can use the CaptureState(CommandList) to retrieve the output description last set on a CommandList. This is especially useful in combination with MutablePipelineState, when the render target might not be known up front.
Code: Capture output description
mutablePipelineState.State.Output.CaptureState(CommandList);
mutablePipelineState.Update();