Konstantin Koch d9e752b3b1 Fix AssimpImporter and that Rendersystems can be loaded when creating content files, also allows Reference and Null Device for DX
If a model was imported with TargetRealTimeMaximumQuality and then
drawn, it causes a blue screen on my system (Nvidia Geforce GTC 650,
Driver version 353.62)
Also disabled Content recreation if a content project is launched with
the visual studio debugger.
2015-11-22 14:12:43 +01:00

295 lines
12 KiB
C#

#region Using Statements
using System;
using System.Linq;
using System.Collections.Generic;
using ANX.Framework;
using ANX.Framework.Graphics;
using ANX.Framework.NonXNA;
using SharpDX.D3DCompiler;
using SharpDX.DXGI;
using SharpDX.Direct3D10;
#endregion
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
// For details see: http://anxframework.codeplex.com/license
using Dx10 = SharpDX.Direct3D10;
namespace ANX.RenderSystem.Windows.DX10
{
public partial class GraphicsDeviceDX : INativeGraphicsDevice
{
#if DEBUG
static int graphicsDeviceCount = 0;
static int swapChainCount = 0;
#endif
//Restricted to 8 from DirectX side.
const int MAX_RENDER_TARGETS = 8;
#region Private
private Dx10.Device nativeDevice;
private Dx10.RenderTargetView[] renderTargetView = new RenderTargetView[MAX_RENDER_TARGETS];
private Dx10.DepthStencilView[] depthStencilView = new DepthStencilView[MAX_RENDER_TARGETS];
private RenderTarget2D_DX10 backBuffer;
internal EffectPass_DX10 currentPass;
#endregion
#region CreateDevice
protected void CreateDevice(PresentationParameters presentationParameters)
{
var desc = new SwapChainDescription()
{
BufferCount = 1,
ModeDescription = new ModeDescription(
presentationParameters.BackBufferWidth,
presentationParameters.BackBufferHeight,
new Rational(60, 1),
DxFormatConverter.Translate(presentationParameters.BackBufferFormat)
),
IsWindowed = true,
OutputHandle = presentationParameters.DeviceWindowHandle,
SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput | Usage.ShaderInput,
};
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205068(v=vs.85).aspx
#if DEBUG
var flags = Dx10.DeviceCreationFlags.Debug;
#else
var flags = Dx10.DeviceCreationFlags.None;
#endif
var driverType = Dx10.DriverType.Hardware;
if (GraphicsAdapter.UseReferenceDevice)
driverType = DriverType.Reference;
else if (GraphicsAdapter.UseNullDevice)
driverType = DriverType.Null;
Dx10.Device.CreateWithSwapChain(driverType, flags, desc, out nativeDevice, out swapChain);
#if DEBUG
nativeDevice.DebugName = "GraphicsDevice_" + graphicsDeviceCount++;
swapChain.DebugName = "SwapChain_" + swapChainCount++;
#endif
}
#endregion
#region CreateRenderView
protected void CreateRenderView(PresentationParameters presentationParameters)
{
backBuffer = new RenderTarget2D_DX10(this, Dx10.Texture2D.FromSwapChain<Dx10.Texture2D>(swapChain, 0), presentationParameters.DepthStencilFormat);
this.SetRenderTargets();
}
#endregion
#region Clear
public void Clear(ClearOptions options, Vector4 color, float depth, int stencil)
{
if ((options & ClearOptions.Target) == ClearOptions.Target)
{
// Clear a RenderTarget (or BackBuffer)
var clearColor = new SharpDX.Color4(color.X, color.Y, color.Z, color.W);
for (int i = 0; i < MAX_RENDER_TARGETS; i++)
{
if (this.renderTargetView[i] == null)
break;
nativeDevice.ClearRenderTargetView(this.renderTargetView[i], clearColor);
}
}
Dx10.DepthStencilClearFlags clearFlags;
if ((options | ClearOptions.Stencil | ClearOptions.DepthBuffer) == options)
{
clearFlags = Dx10.DepthStencilClearFlags.Depth | Dx10.DepthStencilClearFlags.Stencil;
}
else if ((options | ClearOptions.Stencil) == options)
{
clearFlags = Dx10.DepthStencilClearFlags.Stencil;
}
else
{
clearFlags = Dx10.DepthStencilClearFlags.Depth;
}
for (int i = 0; i < MAX_RENDER_TARGETS; i++)
{
if (this.depthStencilView[i] == null)
break;
nativeDevice.ClearDepthStencilView(this.depthStencilView[i], clearFlags, depth, (byte)stencil);
}
}
#endregion
#region Present
public void Present()
{
swapChain.Present(VSync ? 1 : 0, PresentFlags.None);
}
public void Present(Rectangle? sourceRectangle, Rectangle? destinationRectangle, WindowHandle overrideWindowHandle)
{
throw new NotImplementedException();
}
#endregion
private void SetupDraw(PrimitiveType primitiveType)
{
var inputLayout = this.inputLayoutManager.GetInputLayout(NativeDevice, currentPass.Signature, this.currentVertexBuffer);
nativeDevice.InputAssembler.PrimitiveTopology = DxFormatConverter.Translate(primitiveType);
if (currentInputLayout != inputLayout)
{
nativeDevice.InputAssembler.InputLayout = inputLayout;
currentInputLayout = inputLayout;
}
}
#region SetVertexBuffers
public void SetVertexBuffers(ANX.Framework.Graphics.VertexBufferBinding[] vertexBuffers)
{
if (vertexBuffers == null)
throw new ArgumentNullException("vertexBuffers");
if (this.currentVertexBuffer.SequenceEqual(vertexBuffers))
return;
this.currentVertexBufferCount = vertexBuffers.Length;
if (this.currentVertexBuffer == null || this.currentVertexBuffer.Length < currentVertexBufferCount)
{
this.currentVertexBuffer = new ANX.Framework.Graphics.VertexBufferBinding[currentVertexBufferCount];
}
for (int i = 0; i < this.currentVertexBufferCount; i++)
{
this.currentVertexBuffer[i] = vertexBuffers[i];
}
Dx10.VertexBufferBinding[] nativeVertexBufferBindings = new Dx10.VertexBufferBinding[vertexBuffers.Length];
for (int i = 0; i < vertexBuffers.Length; i++)
{
ANX.Framework.Graphics.VertexBufferBinding anxVertexBufferBinding = vertexBuffers[i];
var nativeVertexBuffer = anxVertexBufferBinding.VertexBuffer.NativeVertexBuffer as DxVertexBuffer;
if (nativeVertexBuffer != null)
{
int vertexStride = anxVertexBufferBinding.VertexBuffer.VertexDeclaration.VertexStride;
nativeVertexBufferBindings[i] = new Dx10.VertexBufferBinding(nativeVertexBuffer.NativeBuffer, vertexStride, anxVertexBufferBinding.VertexOffset * vertexStride);
}
else
{
throw new Exception("couldn't fetch native DirectX10 VertexBuffer");
}
}
nativeDevice.InputAssembler.SetVertexBuffers(0, nativeVertexBufferBindings);
}
#endregion
#region SetViewport
protected void SetViewport(int x, int y, int width, int height, float minDepth, float maxDepth)
{
nativeDevice.Rasterizer.SetViewports(new SharpDX.Viewport(x, y, width, height, minDepth, maxDepth));
}
protected void SetViewport(params SharpDX.Viewport[] viewports)
{
nativeDevice.Rasterizer.SetViewports(viewports);
}
#endregion
#region SetRenderTargets
public void SetRenderTargets(params RenderTargetBinding[] renderTargets)
{
if (renderTargets == null || renderTargets.Length == 0)
{
this.renderTargetView[0] = this.backBuffer.RenderTargetView;
this.depthStencilView[0] = this.backBuffer.DepthStencilView;
for (int i = 1; i < MAX_RENDER_TARGETS; i++)
{
this.renderTargetView[i] = null;
this.depthStencilView[i] = null;
}
//To correctly unset renderTargets, the amount of given rendertargetViews must be max(#previousRenderTargets, #newRenderTargets),
//otherwise the old ones at the slots stay bound. For us it means, we try to unbind every possible previous slot.
nativeDevice.OutputMerger.SetRenderTargets(MAX_RENDER_TARGETS, this.renderTargetView, this.backBuffer.DepthStencilView);
nativeDevice.Rasterizer.SetViewports(new SharpDX.Viewport(0, 0, this.backBuffer.Width, this.backBuffer.Height));
}
else
{
int renderTargetCount = renderTargets.Length;
if (renderTargetCount > MAX_RENDER_TARGETS)
throw new NotSupportedException(string.Format("{0} render targets are not supported. The maximum is {1}.", renderTargetCount, MAX_RENDER_TARGETS));
SharpDX.Viewport[] rtViewports = new SharpDX.Viewport[renderTargetCount];
var firstRenderTarget = renderTargets[0].RenderTarget as RenderTarget2D;
for (int i = 1; i < renderTargetCount; i++)
{
var renderTarget = renderTargets[i].RenderTarget as RenderTarget2D;
if (renderTarget.Width != firstRenderTarget.Width || renderTarget.Height != firstRenderTarget.Height || renderTarget.MultiSampleCount != firstRenderTarget.MultiSampleCount)
throw new ArgumentException("The render targets don't match");
}
for (int i = 0; i < renderTargetCount; i++)
{
RenderTarget2D renderTarget = renderTargets[i].RenderTarget as RenderTarget2D;
RenderTarget2D_DX10 nativeRenderTarget = renderTarget.NativeRenderTarget as RenderTarget2D_DX10;
renderTargetView[i] = nativeRenderTarget.RenderTargetView;
depthStencilView[i] = nativeRenderTarget.DepthStencilView;
rtViewports[i] = new SharpDX.Viewport(0, 0, renderTarget.Width, renderTarget.Height);
}
for (int i = renderTargetCount; i < MAX_RENDER_TARGETS; i++)
{
this.renderTargetView[i] = null;
this.depthStencilView[i] = null;
}
nativeDevice.OutputMerger.SetRenderTargets(MAX_RENDER_TARGETS, renderTargetView, this.depthStencilView[0]);
nativeDevice.Rasterizer.SetViewports(rtViewports);
}
}
#endregion
protected void DisposeBackBuffer()
{
if (backBuffer != null)
{
for (int i = 0; i < MAX_RENDER_TARGETS; i++)
{
this.renderTargetView[i] = null;
this.depthStencilView[i] = null;
}
nativeDevice.OutputMerger.SetRenderTargets(MAX_RENDER_TARGETS, this.renderTargetView, null);
backBuffer.Dispose();
backBuffer = null;
}
}
internal Dx10.Device NativeDevice
{
get
{
return this.nativeDevice;
}
}
public Rectangle ScissorRectangle
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
}