DeviceStateHelperD3D11 for issue https://github.com/aienabled/NoesisGUI.MonoGameWrapper/issues/5
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