Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
namespace NoesisGUI.MonoGameWrapper.Helpers.DeviceState
{
using System;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Mathematics.Interop;
using Buffer = SharpDX.Direct3D11.Buffer;
using Device = SharpDX.Direct3D11.Device;
/// <summary>
/// This helper provide methods for saving and restoring D3D11 graphics device state
/// with MonoGame. Provided by NoesisGUI team.
/// </summary>
internal class DeviceStateHelperD3D11 : DeviceStateHelper
{
private readonly Device device;
private readonly Buffer[] vb = new Buffer[1];
private readonly int[] vbOffset = new int[1];
private readonly int[] vbStride = new int[1];
private RawColor4 blendFactor;
private BlendState blendState;
private DepthStencilState depthState;
private DepthStencilView depthStencilView;
private Buffer ib;
private Format ibFormat;
private int ibOffset;
private InputLayout layout;
private PixelShader ps;
private Buffer[] psConstantBuffers;
private ShaderResourceView[] psResources;
private SamplerState[] psSamplers;
private RasterizerState rasterizerState;
private RenderTargetView[] renderTargetView;
private int sampleMaskRef;
private RawRectangle[] scissorRectangles;
private int stencilRefRef;
private PrimitiveTopology topology;
private RawViewportF[] viewports;
private VertexShader vs;
private Buffer[] vsConstantBuffers;
private ShaderResourceView[] vsResources;
private SamplerState[] vsSamplers;
public DeviceStateHelperD3D11(Device device)
{
this.device = device;
}
protected override void Restore()
{
var context = this.device.ImmediateContext;
context.InputAssembler.PrimitiveTopology = this.topology;
context.InputAssembler.InputLayout = this.layout;
this.layout?.Dispose();
context.Rasterizer.SetViewports(this.viewports);
//context.Rasterizer.SetScissorRectangles(this.scissorRectangles);
context.Rasterizer.State = this.rasterizerState;
this.rasterizerState?.Dispose();
context.OutputMerger.SetBlendState(this.blendState, this.blendFactor, this.sampleMaskRef);
this.blendState?.Dispose();
context.OutputMerger.SetDepthStencilState(this.depthState, this.stencilRefRef);
this.depthState?.Dispose();
context.OutputMerger.SetRenderTargets(this.depthStencilView, this.renderTargetView[0]);
this.depthStencilView?.Dispose();
this.renderTargetView[0]?.Dispose();
context.PixelShader.Set(this.ps);
context.PixelShader.SetConstantBuffers(0, this.psConstantBuffers);
context.PixelShader.SetSamplers(0, this.psSamplers);
context.PixelShader.SetShaderResources(0, this.psResources);
this.ps?.Dispose();
DisposeArray(this.psConstantBuffers);
DisposeArray(this.psSamplers);
DisposeArray(this.psResources);
context.VertexShader.Set(this.vs);
context.VertexShader.SetConstantBuffers(0, this.vsConstantBuffers);
context.VertexShader.SetSamplers(0, this.vsSamplers);
context.VertexShader.SetShaderResources(0, this.vsResources);
this.vs?.Dispose();
DisposeArray(this.vsConstantBuffers);
DisposeArray(this.vsSamplers);
DisposeArray(this.vsResources);
context.InputAssembler.SetIndexBuffer(this.ib, this.ibFormat, this.ibOffset);
this.ib?.Dispose();
context.InputAssembler.SetVertexBuffers(0, this.vb, this.vbStride, this.vbOffset);
DisposeArray(this.vb);
}
protected override void Save()
{
var context = this.device.ImmediateContext;
this.topology = context.InputAssembler.PrimitiveTopology;
this.layout = context.InputAssembler.InputLayout;
this.viewports = context.Rasterizer.GetViewports<RawViewportF>();
//this.scissorRectangles = context.Rasterizer.GetScissorRectangles<RawRectangle>();
this.rasterizerState = context.Rasterizer.State;
this.blendState = context.OutputMerger.GetBlendState(out this.blendFactor, out this.sampleMaskRef);
this.depthState = context.OutputMerger.GetDepthStencilState(out this.stencilRefRef);
this.renderTargetView = context.OutputMerger.GetRenderTargets(1, out this.depthStencilView);
this.ps = context.PixelShader.Get();
this.psConstantBuffers = context.PixelShader.GetConstantBuffers(0, 4);
this.psSamplers = context.PixelShader.GetSamplers(0, 4);
this.psResources = context.PixelShader.GetShaderResources(0, 4);
this.vs = context.VertexShader.Get();
this.vsConstantBuffers = context.VertexShader.GetConstantBuffers(0, 4);
this.vsSamplers = context.VertexShader.GetSamplers(0, 4);
this.vsResources = context.VertexShader.GetShaderResources(0, 4);
context.InputAssembler.GetIndexBuffer(out this.ib, out this.ibFormat, out this.ibOffset);
context.InputAssembler.GetVertexBuffers(0, 1, this.vb, this.vbStride, this.vbOffset);
}
private static void DisposeArray<T>(T[] array)
where T : IDisposable
{
foreach (var entry in array)
{
entry?.Dispose();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment