204 lines
7.7 KiB
C#
204 lines
7.7 KiB
C#
// MonoGame - Copyright (C) The MonoGame Team
|
|
// This file is subject to the terms and conditions defined in
|
|
// file 'LICENSE.txt', which is part of this source code package.
|
|
|
|
using SharpDX.Direct3D11;
|
|
using SharpDX.DXGI;
|
|
using Resource = SharpDX.Direct3D11.Resource;
|
|
|
|
namespace Microsoft.Xna.Framework.Graphics
|
|
{
|
|
public partial class RenderTarget2D
|
|
{
|
|
internal RenderTargetView[] _renderTargetViews;
|
|
internal DepthStencilView _depthStencilView;
|
|
private RenderTarget2D _resolvedTexture;
|
|
|
|
private void PlatformConstruct(GraphicsDevice graphicsDevice, int width, int height, bool mipMap,
|
|
DepthFormat preferredDepthFormat, int preferredMultiSampleCount, RenderTargetUsage usage, bool shared)
|
|
{
|
|
GenerateIfRequired();
|
|
}
|
|
|
|
private void GenerateIfRequired()
|
|
{
|
|
if (_renderTargetViews != null)
|
|
return;
|
|
|
|
// Create a view interface on the rendertarget to use on bind.
|
|
if (ArraySize > 1)
|
|
{
|
|
_renderTargetViews = new RenderTargetView[ArraySize];
|
|
for (var i = 0; i < ArraySize; i++)
|
|
{
|
|
var renderTargetViewDescription = new RenderTargetViewDescription();
|
|
if (GetTextureSampleDescription().Count > 1)
|
|
{
|
|
renderTargetViewDescription.Dimension = RenderTargetViewDimension.Texture2DMultisampledArray;
|
|
renderTargetViewDescription.Texture2DMSArray.ArraySize = 1;
|
|
renderTargetViewDescription.Texture2DMSArray.FirstArraySlice = i;
|
|
}
|
|
else
|
|
{
|
|
renderTargetViewDescription.Dimension = RenderTargetViewDimension.Texture2DArray;
|
|
renderTargetViewDescription.Texture2DArray.ArraySize = 1;
|
|
renderTargetViewDescription.Texture2DArray.FirstArraySlice = i;
|
|
renderTargetViewDescription.Texture2DArray.MipSlice = 0;
|
|
}
|
|
_renderTargetViews[i] = new RenderTargetView(
|
|
GraphicsDevice._d3dDevice, GetTexture(),
|
|
renderTargetViewDescription);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_renderTargetViews = new[] { new RenderTargetView(GraphicsDevice._d3dDevice, GetTexture()) };
|
|
}
|
|
|
|
// If we don't need a depth buffer then we're done.
|
|
if (DepthStencilFormat == DepthFormat.None)
|
|
return;
|
|
|
|
// The depth stencil view's multisampling configuration must strictly
|
|
// match the texture's multisampling configuration. Ignore whatever parameters
|
|
// were provided and use the texture's configuration so that things are
|
|
// guarenteed to work.
|
|
var multisampleDesc = GetTextureSampleDescription();
|
|
|
|
// Create a descriptor for the depth/stencil buffer.
|
|
// Allocate a 2-D surface as the depth/stencil buffer.
|
|
// Create a DepthStencil view on this surface to use on bind.
|
|
using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, new Texture2DDescription
|
|
{
|
|
Format = SharpDXHelper.ToFormat(DepthStencilFormat),
|
|
ArraySize = 1,
|
|
MipLevels = 1,
|
|
Width = width,
|
|
Height = height,
|
|
SampleDescription = multisampleDesc,
|
|
BindFlags = BindFlags.DepthStencil,
|
|
}))
|
|
{
|
|
// Create the view for binding to the device.
|
|
_depthStencilView = new DepthStencilView(GraphicsDevice._d3dDevice, depthBuffer,
|
|
new DepthStencilViewDescription()
|
|
{
|
|
Format = SharpDXHelper.ToFormat(DepthStencilFormat),
|
|
Dimension = GetTextureSampleDescription().Count > 1 ? DepthStencilViewDimension.Texture2DMultisampled : DepthStencilViewDimension.Texture2D
|
|
});
|
|
}
|
|
}
|
|
|
|
private void PlatformGraphicsDeviceResetting()
|
|
{
|
|
if (_renderTargetViews != null)
|
|
{
|
|
for (var i = 0; i < _renderTargetViews.Length; i++)
|
|
_renderTargetViews[i].Dispose();
|
|
_renderTargetViews = null;
|
|
}
|
|
SharpDX.Utilities.Dispose(ref _depthStencilView);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
if (_renderTargetViews != null)
|
|
{
|
|
for (var i = 0; i < _renderTargetViews.Length; i++)
|
|
_renderTargetViews[i].Dispose();
|
|
_renderTargetViews = null;
|
|
}
|
|
SharpDX.Utilities.Dispose(ref _depthStencilView);
|
|
if (_resolvedTexture != null)
|
|
SharpDX.Utilities.Dispose(ref _resolvedTexture);
|
|
}
|
|
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
RenderTargetView IRenderTarget.GetRenderTargetView(int arraySlice)
|
|
{
|
|
GenerateIfRequired();
|
|
return _renderTargetViews[arraySlice];
|
|
}
|
|
|
|
DepthStencilView IRenderTarget.GetDepthStencilView()
|
|
{
|
|
GenerateIfRequired();
|
|
return _depthStencilView;
|
|
}
|
|
|
|
protected internal override SampleDescription CreateSampleDescription()
|
|
{
|
|
return this.GraphicsDevice.GetSupportedSampleDescription
|
|
(SharpDXHelper.ToFormat(this._format), this.MultiSampleCount);
|
|
}
|
|
|
|
internal void ResolveSubresource()
|
|
{
|
|
lock (GraphicsDevice._d3dContext)
|
|
{
|
|
GraphicsDevice._d3dContext.ResolveSubresource(
|
|
this._texture,
|
|
0,
|
|
_resolvedTexture._texture,
|
|
0,
|
|
SharpDXHelper.ToFormat(_format));
|
|
}
|
|
}
|
|
|
|
internal override Resource CreateTexture()
|
|
{
|
|
var rt = base.CreateTexture();
|
|
|
|
// MSAA RT needs another non-MSAA texture where it is resolved
|
|
if (SampleDescription.Count > 1)
|
|
{
|
|
_resolvedTexture = new RenderTarget2D(
|
|
GraphicsDevice,
|
|
Width,
|
|
Height,
|
|
Mipmap,
|
|
Format,
|
|
DepthStencilFormat,
|
|
1,
|
|
RenderTargetUsage,
|
|
Shared,
|
|
ArraySize);
|
|
}
|
|
|
|
return rt;
|
|
}
|
|
|
|
protected override ShaderResourceView CreateShaderResourceView()
|
|
{
|
|
if (MultiSampleCount > 1)
|
|
return new SharpDX.Direct3D11.ShaderResourceView
|
|
(GraphicsDevice._d3dDevice, _resolvedTexture.GetTexture());
|
|
else
|
|
return base.CreateShaderResourceView();
|
|
}
|
|
|
|
protected internal override Texture2DDescription GetTexture2DDescription()
|
|
{
|
|
var desc = base.GetTexture2DDescription();
|
|
|
|
desc.BindFlags |= BindFlags.RenderTarget;
|
|
if (desc.SampleDescription.Count > 1)
|
|
desc.BindFlags &= ~BindFlags.ShaderResource;
|
|
|
|
if (Mipmap)
|
|
{
|
|
// Note: XNA 4 does not have a method Texture.GenerateMipMaps()
|
|
// because generation of mipmaps is not supported on the Xbox 360.
|
|
// TODO: New method Texture.GenerateMipMaps() required.
|
|
desc.OptionFlags |= ResourceOptionFlags.GenerateMipMaps;
|
|
}
|
|
|
|
return desc;
|
|
}
|
|
}
|
|
}
|