Pipeline states

Xenko gives you total control over the graphics pipeline state. This includes:

  • rasterizer state
  • depth and stencil state
  • blend state
  • effects
  • input layout
  • output descriptionState is compiled into immutable PipelineState objects, which describe the whole pipeline. They are then bound using a CommandList.

Code: Create state objects

  1. // Creating pipeline state object
  2. var pipelineStateDescription = new PipelineStateDescription();
  3. var pipelineState = PipelineState.New(GraphicsDevice, ref pipelineStateDescription);
  4. // Applying the state to the pipeline
  5. CommandList.SetPipelineState(pipelineState);

The MutablePipelineState class let you set states independently, while caching the underlying pipeline states.

Code: Mutable pipeline state

  1. // Creating the pipeline state object
  2. var mutablePipelineState = new MutablePipelineState();
  3. // Setting values and rebuilding
  4. mutablePipelineState.State.BlendState = BlendStates.AlphaBlend
  5. mutablePipelineState.Update
  6. // Applying the state to the pipeline
  7. 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:

  1. pipelineStateDescription.RasterizerState = RasterizerStates.CullNone;
  2. pipelineStateDescription.RasterizerState = RasterizerStates.CullFront;
  3. 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

  1. var rasterizerStateDescription = new RasterizerStateDescription(CullMode.Front);
  2. rasterizerStateDescription.ScissorTestEnable = true; // enables the scissor test
  3. 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 writeCode: Setting the depth state
  1. pipelineStateDescription.DepthStencilState = DepthStencilStates.Default;
  2. pipelineStateDescription.DepthStencilState = DepthStencilStates.DefaultInverse;
  3. pipelineStateDescription.DepthStencilState = DepthStencilStates.DepthRead;
  4. 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

  1. // depth test is enabled but it doesn't write
  2. var depthStencilStateDescription = new DepthStencilStateDescription(true, false);
  3. pipelineStateDescription.DepthStencilState = depthStencilStateDescription;

The stencil reference isn't part of the PipelineState. It's set using SetStencilReference(Int32).

Code: Set the stencil reference

  1. 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 colorCode: Set the blend state
  1. // Set common blend states
  2. pipelineStateDescription.BlendState = BlendStates.Additive;
  3. pipelineStateDescription.BlendState = BlendStates.AlphaBlend;
  4. pipelineStateDescription.BlendState = BlendStates.NonPremultiplied;
  5. pipelineStateDescription.BlendState = BlendStates.Opaque;
  6. // Set the sample mask
  7. 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

  1. // create the object describing the blend state per target
  2. var blendStateRenderTargetDescription = new BlendStateRenderTargetDescription();
  3. blendStateRenderTargetDescription.BlendEnable = true;
  4. blendStateRenderTargetDescription.ColorSourceBlend = Blend.SourceColor;
  5. // etc.
  6. // create the blendStateDescription object
  7. var blendStateDescription = new BlendStateDescription(Blend.SourceColor, Blend.InverseSourceColor);
  8. blendStateDescription.AlphaToCoverageEnable = true; // enable alpha to coverage
  9. blendStateDescription.RenderTargets[0] = blendStateRenderTargetDescription;
  10. pipelineStateDescription.BlendState = blendStateDescription;

The blend factor isn't part of the PipelineState. It's set using SetBlendFactor(Color4).

Code: Set the blend factor

  1. 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 EffectBytecodeand 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

  1. var effectInstance = new EffectInstance(EffectSystem.LoadEffect("MyEffect").WaitForResult());
  2. pipelineStateDescription.EffectBytecode = effectInstance.Effect.Bytecode;
  3. 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

  1. VertexDeclaration vertexDeclaration = ...
  2. pipelineStateDescription.InputElements = vertexDeclaration.CreateInputElements();
  3. 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

  1. var renderOutputDescription = new RenderOutputDescription(GraphicsDevice.Presenter.BackBuffer.Format, GraphicsDevice.Presenter.DepthStencilBuffer.Format);
  2. 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

  1. mutablePipelineState.State.Output.CaptureState(CommandList);
  2. mutablePipelineState.Update();