2017-09-21 18:33:05 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using SharpDX.DXGI;
|
|
|
|
|
using Device = SharpDX.Direct3D11.Device;
|
|
|
|
|
using Buffer = SharpDX.Direct3D11.Buffer;
|
|
|
|
|
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
|
|
|
|
using SharpDX.Direct3D11;
|
|
|
|
|
using SharpDX;
|
|
|
|
|
using SharpDX.Direct3D;
|
|
|
|
|
|
|
|
|
|
namespace CodeWalker.Rendering
|
|
|
|
|
{
|
|
|
|
|
public class GpuVarsBuffer<T> where T:struct //shader vars buffer helper!
|
|
|
|
|
{
|
|
|
|
|
public int Size;
|
|
|
|
|
public Buffer Buffer;
|
|
|
|
|
public T Vars;
|
|
|
|
|
public bool Flag;//for external use
|
|
|
|
|
public GpuVarsBuffer(Device device)
|
|
|
|
|
{
|
|
|
|
|
Size = System.Runtime.InteropServices.Marshal.SizeOf<T>();// (sizeof(T));
|
|
|
|
|
Buffer = new Buffer(device, Size, ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0);// //DXUtility::CreateShaderVarsBuffer(Size, name);
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (Buffer != null)
|
|
|
|
|
{
|
|
|
|
|
Buffer.Dispose();
|
|
|
|
|
Buffer = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Update(DeviceContext context)
|
|
|
|
|
{
|
2018-02-28 00:46:06 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var dataBox = context.MapSubresource(Buffer, 0, MapMode.WriteDiscard, MapFlags.None);
|
|
|
|
|
Utilities.Write(dataBox.DataPointer, ref Vars);
|
|
|
|
|
context.UnmapSubresource(Buffer, 0);
|
|
|
|
|
}
|
|
|
|
|
catch { } //not much we can do about this except ignore it..
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
public void SetVSCBuffer(DeviceContext context, int slot)
|
|
|
|
|
{
|
|
|
|
|
context.VertexShader.SetConstantBuffer(slot, Buffer);
|
|
|
|
|
}
|
|
|
|
|
public void SetPSCBuffer(DeviceContext context, int slot)
|
|
|
|
|
{
|
|
|
|
|
context.PixelShader.SetConstantBuffer(slot, Buffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-03 03:25:20 +08:00
|
|
|
|
|
|
|
|
|
public class GpuABuffer<T> where T : struct //Dynamic GPU buffer of items updated by CPU, for array of structs used as a constant buffer
|
|
|
|
|
{
|
|
|
|
|
public int StructSize;
|
|
|
|
|
public int StructCount;
|
|
|
|
|
public int BufferSize;
|
|
|
|
|
public Buffer Buffer;
|
|
|
|
|
|
|
|
|
|
public GpuABuffer(Device device, int count)
|
|
|
|
|
{
|
|
|
|
|
StructCount = count;
|
|
|
|
|
StructSize = System.Runtime.InteropServices.Marshal.SizeOf<T>();
|
|
|
|
|
BufferSize = StructCount * StructSize;
|
|
|
|
|
Buffer = new Buffer(device, BufferSize, ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0);
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (Buffer != null)
|
|
|
|
|
{
|
|
|
|
|
Buffer.Dispose();
|
|
|
|
|
Buffer = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Update(DeviceContext context, T[] data)
|
|
|
|
|
{
|
|
|
|
|
var dataBox = context.MapSubresource(Buffer, 0, MapMode.WriteDiscard, MapFlags.None);
|
2019-11-07 00:51:35 +08:00
|
|
|
|
Utilities.Write(dataBox.DataPointer, data, 0, Math.Min(data.Length, StructCount));
|
2019-11-03 03:25:20 +08:00
|
|
|
|
context.UnmapSubresource(Buffer, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetVSCBuffer(DeviceContext context, int slot)
|
|
|
|
|
{
|
|
|
|
|
context.VertexShader.SetConstantBuffer(slot, Buffer);
|
|
|
|
|
}
|
|
|
|
|
public void SetPSCBuffer(DeviceContext context, int slot)
|
|
|
|
|
{
|
|
|
|
|
context.PixelShader.SetConstantBuffer(slot, Buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-09-21 18:33:05 +08:00
|
|
|
|
public class GpuSBuffer<T> where T : struct //for static struct data as resource view
|
|
|
|
|
{
|
|
|
|
|
public int StructSize;
|
|
|
|
|
public int StructCount;
|
|
|
|
|
public int BufferSize;
|
|
|
|
|
public Buffer Buffer;
|
|
|
|
|
public ShaderResourceView SRV;
|
|
|
|
|
public GpuSBuffer(Device device, T[] data)
|
|
|
|
|
{
|
|
|
|
|
StructCount = data.Length;
|
|
|
|
|
StructSize = System.Runtime.InteropServices.Marshal.SizeOf<T>();// (sizeof(T));
|
|
|
|
|
BufferSize = StructCount * StructSize;
|
|
|
|
|
//var ds = new DataStream(new DataPointer()
|
|
|
|
|
Buffer = Buffer.Create<T>(device, BindFlags.ShaderResource, data, BufferSize, ResourceUsage.Default, CpuAccessFlags.None, ResourceOptionFlags.BufferStructured, StructSize);
|
|
|
|
|
//Buffer = new Buffer(device, BufferSize, ResourceUsage.Default, BindFlags.ShaderResource, CpuAccessFlags.None, ResourceOptionFlags.BufferStructured, StructSize);
|
|
|
|
|
SRV = DXUtility.CreateShaderResourceView(device, Buffer, SharpDX.DXGI.Format.Unknown, SharpDX.Direct3D.ShaderResourceViewDimension.Buffer, 0, 0, StructCount, 0);
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (SRV != null)
|
|
|
|
|
{
|
|
|
|
|
SRV.Dispose();
|
|
|
|
|
SRV = null;
|
|
|
|
|
}
|
|
|
|
|
if (Buffer != null)
|
|
|
|
|
{
|
|
|
|
|
Buffer.Dispose();
|
|
|
|
|
Buffer = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class GpuCBuffer<T> where T : struct //Dynamic GPU buffer of items updated by CPU
|
|
|
|
|
{
|
|
|
|
|
public int StructSize;
|
|
|
|
|
public int StructCount;
|
|
|
|
|
public int BufferSize;
|
|
|
|
|
public int CurrentCount;
|
|
|
|
|
public Buffer Buffer;
|
|
|
|
|
public ShaderResourceView SRV;
|
|
|
|
|
public List<T> Data;
|
|
|
|
|
public T[] DataArray;
|
|
|
|
|
|
|
|
|
|
public GpuCBuffer(Device device, int count)
|
|
|
|
|
{
|
|
|
|
|
StructCount = count;
|
|
|
|
|
StructSize = System.Runtime.InteropServices.Marshal.SizeOf<T>();// (sizeof(T));
|
|
|
|
|
BufferSize = StructCount * StructSize;
|
|
|
|
|
//Buffer = Buffer.Create<T>(device, BindFlags.ShaderResource, null, BufferSize, ResourceUsage.Dynamic, CpuAccessFlags.Write, ResourceOptionFlags.BufferStructured, StructSize);
|
|
|
|
|
Buffer = new Buffer(device, BufferSize, ResourceUsage.Dynamic, BindFlags.ShaderResource, CpuAccessFlags.Write, ResourceOptionFlags.BufferStructured, StructSize);
|
|
|
|
|
SRV = DXUtility.CreateShaderResourceView(device, Buffer, SharpDX.DXGI.Format.Unknown, SharpDX.Direct3D.ShaderResourceViewDimension.Buffer, 0, 0, StructCount, 0);
|
|
|
|
|
Data = new List<T>(count);
|
|
|
|
|
DataArray = new T[count];
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (SRV != null)
|
|
|
|
|
{
|
|
|
|
|
SRV.Dispose();
|
|
|
|
|
SRV = null;
|
|
|
|
|
}
|
|
|
|
|
if (Buffer != null)
|
|
|
|
|
{
|
|
|
|
|
Buffer.Dispose();
|
|
|
|
|
Buffer = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
|
|
|
|
Data.Clear();
|
|
|
|
|
CurrentCount = 0;
|
|
|
|
|
}
|
|
|
|
|
public bool Add(T item)
|
|
|
|
|
{
|
|
|
|
|
if (CurrentCount < StructCount)
|
|
|
|
|
{
|
|
|
|
|
Data.Add(item);
|
|
|
|
|
CurrentCount++;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Update(DeviceContext context)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < CurrentCount; i++)
|
|
|
|
|
{
|
|
|
|
|
DataArray[i] = Data[i];
|
|
|
|
|
}
|
|
|
|
|
var dataBox = context.MapSubresource(Buffer, 0, MapMode.WriteDiscard, MapFlags.None);
|
|
|
|
|
Utilities.Write(dataBox.DataPointer, DataArray, 0, CurrentCount);
|
|
|
|
|
context.UnmapSubresource(Buffer, 0);
|
|
|
|
|
}
|
2019-11-03 03:25:20 +08:00
|
|
|
|
public void Update(DeviceContext context, T[] data)
|
|
|
|
|
{
|
|
|
|
|
var dataBox = context.MapSubresource(Buffer, 0, MapMode.WriteDiscard, MapFlags.None);
|
|
|
|
|
Utilities.Write(dataBox.DataPointer, data, 0, data.Length);
|
|
|
|
|
context.UnmapSubresource(Buffer, 0);
|
|
|
|
|
}
|
2017-09-21 18:33:05 +08:00
|
|
|
|
|
|
|
|
|
public void SetVSResource(DeviceContext context, int slot)
|
|
|
|
|
{
|
|
|
|
|
context.VertexShader.SetShaderResource(slot, SRV);
|
|
|
|
|
}
|
|
|
|
|
public void SetPSResource(DeviceContext context, int slot)
|
|
|
|
|
{
|
|
|
|
|
context.PixelShader.SetShaderResource(slot, SRV);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class GpuBuffer<T> where T : struct //Dynamic GPU buffer of items updated by compute shader
|
|
|
|
|
{
|
|
|
|
|
public int StructSize;
|
|
|
|
|
public int StructCount;
|
|
|
|
|
public int ItemTotalSize;
|
|
|
|
|
public int ItemCount;
|
|
|
|
|
public int Size;
|
|
|
|
|
public Buffer Buffer;
|
|
|
|
|
public ShaderResourceView SRV;
|
|
|
|
|
public UnorderedAccessView UAV;
|
|
|
|
|
|
|
|
|
|
public GpuBuffer(Device device, int itemSize, int itemCount)
|
|
|
|
|
{
|
|
|
|
|
StructSize = System.Runtime.InteropServices.Marshal.SizeOf<T>();// sizeof(T)),
|
|
|
|
|
StructCount = itemCount * itemSize;
|
|
|
|
|
ItemTotalSize = itemSize * StructSize;
|
|
|
|
|
ItemCount = itemCount;
|
|
|
|
|
Size = StructSize * itemSize * itemCount;
|
|
|
|
|
Buffer = DXUtility.CreateBuffer(device, Size, ResourceUsage.Default, BindFlags.ShaderResource | BindFlags.UnorderedAccess, 0, ResourceOptionFlags.BufferStructured, StructSize);
|
|
|
|
|
SRV = DXUtility.CreateShaderResourceView(device, Buffer, Format.Unknown, ShaderResourceViewDimension.Buffer, 0, 0, StructCount, 0);
|
|
|
|
|
UAV = DXUtility.CreateUnorderedAccessView(device, Buffer, Format.Unknown, UnorderedAccessViewDimension.Buffer, 0, StructCount, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (UAV != null)
|
|
|
|
|
{
|
|
|
|
|
UAV.Dispose();
|
|
|
|
|
UAV = null;
|
|
|
|
|
}
|
|
|
|
|
if (SRV != null)
|
|
|
|
|
{
|
|
|
|
|
SRV.Dispose();
|
|
|
|
|
SRV = null;
|
|
|
|
|
}
|
|
|
|
|
if (Buffer != null)
|
|
|
|
|
{
|
|
|
|
|
Buffer.Dispose();
|
|
|
|
|
Buffer = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class GpuTexture //texture and render targets (depth, MS).
|
|
|
|
|
{
|
|
|
|
|
public Texture2D Texture;
|
|
|
|
|
public Texture2D TextureMS;
|
|
|
|
|
public Texture2D Depth;
|
|
|
|
|
public Texture2D DepthMS;
|
|
|
|
|
public RenderTargetView RTV;
|
|
|
|
|
public DepthStencilView DSV;
|
|
|
|
|
public RenderTargetView MSRTV;
|
|
|
|
|
public DepthStencilView MSDSV;
|
|
|
|
|
public ShaderResourceView SRV;
|
2019-12-14 16:52:04 +08:00
|
|
|
|
//public ShaderResourceView DepthSRV; //possibly causing crash on DX10 hardware when multisampled
|
2017-09-21 18:33:05 +08:00
|
|
|
|
public int VramUsage;
|
|
|
|
|
public bool Multisampled;
|
|
|
|
|
public bool UseDepth;
|
|
|
|
|
|
|
|
|
|
public void Init(Device device, int w, int h, Format f, int sc, int sq, bool depth, Format df)
|
|
|
|
|
{
|
|
|
|
|
VramUsage = 0;
|
|
|
|
|
Multisampled = (sc > 1);
|
|
|
|
|
UseDepth = depth;
|
|
|
|
|
ResourceUsage u = ResourceUsage.Default;
|
|
|
|
|
BindFlags b = BindFlags.RenderTarget | BindFlags.ShaderResource;
|
|
|
|
|
RenderTargetViewDimension rtvd = RenderTargetViewDimension.Texture2D;
|
|
|
|
|
ShaderResourceViewDimension srvd = ShaderResourceViewDimension.Texture2D;// D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
|
|
|
int fs = DXUtility.ElementSize(f);
|
|
|
|
|
int wh = w * h;
|
2019-12-14 16:52:04 +08:00
|
|
|
|
BindFlags db = BindFlags.DepthStencil;// | BindFlags.ShaderResource;// D3D11_BIND_DEPTH_STENCIL;
|
2017-09-21 18:33:05 +08:00
|
|
|
|
DepthStencilViewDimension dsvd = DepthStencilViewDimension.Texture2D;
|
2019-12-06 23:51:46 +08:00
|
|
|
|
Format dtexf = GetDepthTexFormat(df);
|
|
|
|
|
Format dsrvf = GetDepthSrvFormat(df);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
|
|
|
|
|
Texture = DXUtility.CreateTexture2D(device, w, h, 1, 1, f, 1, 0, u, b, 0, 0);
|
|
|
|
|
RTV = DXUtility.CreateRenderTargetView(device, Texture, f, rtvd, 0, 0, 0);
|
|
|
|
|
SRV = DXUtility.CreateShaderResourceView(device, Texture, f, srvd, 1, 0, 0, 0);
|
|
|
|
|
VramUsage += (wh * fs);
|
|
|
|
|
|
|
|
|
|
if (Multisampled)
|
|
|
|
|
{
|
|
|
|
|
b = BindFlags.RenderTarget;
|
|
|
|
|
rtvd = RenderTargetViewDimension.Texture2DMultisampled;
|
|
|
|
|
dsvd = DepthStencilViewDimension.Texture2DMultisampled;
|
2019-12-14 16:52:04 +08:00
|
|
|
|
//srvd = ShaderResourceViewDimension.Texture2DMultisampled;
|
2017-09-21 18:33:05 +08:00
|
|
|
|
|
|
|
|
|
TextureMS = DXUtility.CreateTexture2D(device, w, h, 1, 1, f, sc, sq, u, b, 0, 0);
|
|
|
|
|
MSRTV = DXUtility.CreateRenderTargetView(device, TextureMS, f, rtvd, 0, 0, 0);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
VramUsage += (wh * fs) * sc;
|
2017-09-21 18:33:05 +08:00
|
|
|
|
|
|
|
|
|
if (depth)
|
|
|
|
|
{
|
2019-12-06 23:51:46 +08:00
|
|
|
|
DepthMS = DXUtility.CreateTexture2D(device, w, h, 1, 1, dtexf, sc, sq, u, db, 0, 0);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
MSDSV = DXUtility.CreateDepthStencilView(device, DepthMS, df, dsvd);
|
2019-12-14 16:52:04 +08:00
|
|
|
|
//DepthSRV = DXUtility.CreateShaderResourceView(device, DepthMS, dsrvf, srvd, 1, 0, 0, 0);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
VramUsage += (wh * DXUtility.ElementSize(df)) * sc;
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (depth)
|
|
|
|
|
{
|
2019-12-06 23:51:46 +08:00
|
|
|
|
Depth = DXUtility.CreateTexture2D(device, w, h, 1, 1, dtexf, sc, sq, u, db, 0, 0);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
DSV = DXUtility.CreateDepthStencilView(device, Depth, df, dsvd);
|
2019-12-14 16:52:04 +08:00
|
|
|
|
//DepthSRV = DXUtility.CreateShaderResourceView(device, Depth, dsrvf, srvd, 1, 0, 0, 0);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
VramUsage += (wh * DXUtility.ElementSize(df));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (SRV != null)
|
|
|
|
|
{
|
|
|
|
|
SRV.Dispose();
|
|
|
|
|
SRV = null;
|
|
|
|
|
}
|
|
|
|
|
if (MSDSV != null)
|
|
|
|
|
{
|
|
|
|
|
MSDSV.Dispose();
|
|
|
|
|
MSDSV = null;
|
|
|
|
|
}
|
|
|
|
|
if (MSRTV != null)
|
|
|
|
|
{
|
|
|
|
|
MSRTV.Dispose();
|
|
|
|
|
MSRTV = null;
|
|
|
|
|
}
|
|
|
|
|
if (DSV != null)
|
|
|
|
|
{
|
|
|
|
|
DSV.Dispose();
|
|
|
|
|
DSV = null;
|
|
|
|
|
}
|
|
|
|
|
if (RTV != null)
|
|
|
|
|
{
|
|
|
|
|
RTV.Dispose();
|
|
|
|
|
RTV = null;
|
|
|
|
|
}
|
|
|
|
|
if (DepthMS != null)
|
|
|
|
|
{
|
|
|
|
|
DepthMS.Dispose();
|
|
|
|
|
DepthMS = null;
|
|
|
|
|
}
|
|
|
|
|
if (Depth != null)
|
|
|
|
|
{
|
|
|
|
|
Depth.Dispose();
|
|
|
|
|
Depth = null;
|
|
|
|
|
}
|
|
|
|
|
if (TextureMS != null)
|
|
|
|
|
{
|
|
|
|
|
TextureMS.Dispose();
|
|
|
|
|
TextureMS = null;
|
|
|
|
|
}
|
|
|
|
|
if (Texture != null)
|
|
|
|
|
{
|
|
|
|
|
Texture.Dispose();
|
|
|
|
|
Texture = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public GpuTexture(Device device, int w, int h, Format f, int sc, int sq, bool depth, Format df)
|
|
|
|
|
{
|
|
|
|
|
Init(device, w, h, f, sc, sq, depth, df);
|
|
|
|
|
}
|
|
|
|
|
public GpuTexture(Device device, int w, int h, Format f, int sc, int sq)
|
|
|
|
|
{
|
|
|
|
|
Init(device, w, h, f, sc, sq, false, Format.Unknown);
|
|
|
|
|
}
|
|
|
|
|
public GpuTexture(Device device, int w, int h, Format f)
|
|
|
|
|
{
|
|
|
|
|
Init(device, w, h, f, 1, 0, false, Format.Unknown);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear(DeviceContext context, Color4 colour)
|
|
|
|
|
{
|
|
|
|
|
if (Multisampled)
|
|
|
|
|
{
|
|
|
|
|
context.ClearRenderTargetView(MSRTV, colour);
|
|
|
|
|
if (UseDepth)
|
|
|
|
|
{
|
2019-12-01 17:17:14 +08:00
|
|
|
|
context.ClearDepthStencilView(MSDSV, DepthStencilClearFlags.Depth, 0.0f, 0);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
context.ClearRenderTargetView(RTV, colour);
|
|
|
|
|
if (UseDepth)
|
|
|
|
|
{
|
2019-12-01 17:17:14 +08:00
|
|
|
|
context.ClearDepthStencilView(DSV, DepthStencilClearFlags.Depth, 0.0f, 0);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearDepth(DeviceContext context)
|
|
|
|
|
{
|
|
|
|
|
if (!UseDepth) return;
|
|
|
|
|
if (Multisampled)
|
|
|
|
|
{
|
2019-12-01 17:17:14 +08:00
|
|
|
|
context.ClearDepthStencilView(MSDSV, DepthStencilClearFlags.Depth, 0.0f, 0);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-12-01 17:17:14 +08:00
|
|
|
|
context.ClearDepthStencilView(DSV, DepthStencilClearFlags.Depth, 0.0f, 0);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetRenderTarget(DeviceContext context)
|
|
|
|
|
{
|
|
|
|
|
if (Multisampled)
|
|
|
|
|
{
|
|
|
|
|
context.OutputMerger.SetRenderTargets(UseDepth ? MSDSV : null, MSRTV);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
context.OutputMerger.SetRenderTargets(UseDepth ? DSV : null, RTV);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-06 23:51:46 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Format GetDepthTexFormat(Format df)
|
|
|
|
|
{
|
|
|
|
|
Format dtexf = Format.R32_Typeless;
|
|
|
|
|
switch (df)
|
|
|
|
|
{
|
|
|
|
|
case Format.D16_UNorm:
|
|
|
|
|
dtexf = Format.R16_Typeless;
|
|
|
|
|
break;
|
|
|
|
|
case Format.D24_UNorm_S8_UInt:
|
|
|
|
|
dtexf = Format.R24G8_Typeless;
|
|
|
|
|
break;
|
|
|
|
|
case Format.D32_Float:
|
|
|
|
|
dtexf = Format.R32_Typeless;
|
|
|
|
|
break;
|
|
|
|
|
case Format.D32_Float_S8X24_UInt:
|
|
|
|
|
dtexf = Format.R32G8X24_Typeless;//is this right? who uses this anyway??
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return dtexf;
|
|
|
|
|
}
|
|
|
|
|
public static Format GetDepthSrvFormat(Format df)
|
|
|
|
|
{
|
|
|
|
|
Format dsrvf = Format.R32_Float;
|
|
|
|
|
switch (df)
|
|
|
|
|
{
|
|
|
|
|
case Format.D16_UNorm:
|
|
|
|
|
dsrvf = Format.R16_UNorm;
|
|
|
|
|
break;
|
|
|
|
|
case Format.D24_UNorm_S8_UInt:
|
|
|
|
|
dsrvf = Format.R24_UNorm_X8_Typeless;
|
|
|
|
|
break;
|
|
|
|
|
case Format.D32_Float:
|
|
|
|
|
dsrvf = Format.R32_Float;
|
|
|
|
|
break;
|
|
|
|
|
case Format.D32_Float_S8X24_UInt:
|
|
|
|
|
dsrvf = Format.R32_Float_X8X24_Typeless;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return dsrvf;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-12-03 21:52:22 +08:00
|
|
|
|
public class GpuMultiTexture //multiple texture and render targets (depth).
|
|
|
|
|
{
|
|
|
|
|
public Texture2D[] Textures;
|
|
|
|
|
public Texture2D Depth;
|
|
|
|
|
public RenderTargetView[] RTVs;
|
|
|
|
|
public DepthStencilView DSV;
|
|
|
|
|
public ShaderResourceView[] SRVs;
|
|
|
|
|
public ShaderResourceView DepthSRV;
|
|
|
|
|
public int VramUsage;
|
|
|
|
|
public bool UseDepth;
|
|
|
|
|
public int Count;
|
2019-12-04 17:14:11 +08:00
|
|
|
|
public bool Multisampled;
|
|
|
|
|
public int MultisampleCount;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
2019-12-04 17:14:11 +08:00
|
|
|
|
public void Init(Device device, int w, int h, int count, Format f, bool depth, Format df, int multisamplecount)
|
2019-12-03 21:52:22 +08:00
|
|
|
|
{
|
|
|
|
|
Count = count;
|
|
|
|
|
VramUsage = 0;
|
|
|
|
|
UseDepth = depth;
|
2019-12-04 17:14:11 +08:00
|
|
|
|
MultisampleCount = multisamplecount;
|
|
|
|
|
Multisampled = (multisamplecount > 1);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
ResourceUsage u = ResourceUsage.Default;
|
|
|
|
|
BindFlags b = BindFlags.RenderTarget | BindFlags.ShaderResource;
|
|
|
|
|
int fs = DXUtility.ElementSize(f);
|
|
|
|
|
int wh = w * h;
|
|
|
|
|
BindFlags db = BindFlags.DepthStencil | BindFlags.ShaderResource;// D3D11_BIND_DEPTH_STENCIL;
|
2019-12-04 17:14:11 +08:00
|
|
|
|
RenderTargetViewDimension rtvd = RenderTargetViewDimension.Texture2D;
|
|
|
|
|
ShaderResourceViewDimension srvd = ShaderResourceViewDimension.Texture2D;// D3D11_SRV_DIMENSION_TEXTURE2D;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
DepthStencilViewDimension dsvd = DepthStencilViewDimension.Texture2D;
|
|
|
|
|
|
2019-12-04 17:14:11 +08:00
|
|
|
|
if (Multisampled)
|
|
|
|
|
{
|
|
|
|
|
rtvd = RenderTargetViewDimension.Texture2DMultisampled;
|
|
|
|
|
srvd = ShaderResourceViewDimension.Texture2DMultisampled;
|
|
|
|
|
dsvd = DepthStencilViewDimension.Texture2DMultisampled;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-03 21:52:22 +08:00
|
|
|
|
Textures = new Texture2D[count];
|
|
|
|
|
RTVs = new RenderTargetView[count];
|
|
|
|
|
SRVs = new ShaderResourceView[count];
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
|
{
|
2019-12-04 17:14:11 +08:00
|
|
|
|
Textures[i] = DXUtility.CreateTexture2D(device, w, h, 1, 1, f, multisamplecount, 0, u, b, 0, 0);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
RTVs[i] = DXUtility.CreateRenderTargetView(device, Textures[i], f, rtvd, 0, 0, 0);
|
|
|
|
|
SRVs[i] = DXUtility.CreateShaderResourceView(device, Textures[i], f, srvd, 1, 0, 0, 0);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
VramUsage += (wh * fs) * multisamplecount;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
if (depth)
|
|
|
|
|
{
|
2019-12-06 23:51:46 +08:00
|
|
|
|
Format dtexf = GpuTexture.GetDepthTexFormat(df);
|
|
|
|
|
Format dsrvf = GpuTexture.GetDepthSrvFormat(df);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
Depth = DXUtility.CreateTexture2D(device, w, h, 1, 1, dtexf, multisamplecount, 0, u, db, 0, 0);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
DSV = DXUtility.CreateDepthStencilView(device, Depth, df, dsvd);
|
|
|
|
|
DepthSRV = DXUtility.CreateShaderResourceView(device, Depth, dsrvf, srvd, 1, 0, 0, 0);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
VramUsage += (wh * DXUtility.ElementSize(df)) * multisamplecount;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < Count; i++)
|
|
|
|
|
{
|
|
|
|
|
SRVs[i].Dispose();
|
|
|
|
|
RTVs[i].Dispose();
|
|
|
|
|
Textures[i].Dispose();
|
|
|
|
|
}
|
|
|
|
|
SRVs = null;
|
|
|
|
|
RTVs = null;
|
|
|
|
|
Textures = null;
|
|
|
|
|
|
|
|
|
|
if (DSV != null)
|
|
|
|
|
{
|
|
|
|
|
DSV.Dispose();
|
|
|
|
|
DSV = null;
|
|
|
|
|
}
|
|
|
|
|
if (DepthSRV != null)
|
|
|
|
|
{
|
|
|
|
|
DepthSRV.Dispose();
|
|
|
|
|
DepthSRV = null;
|
|
|
|
|
}
|
|
|
|
|
if (Depth != null)
|
|
|
|
|
{
|
|
|
|
|
Depth.Dispose();
|
|
|
|
|
Depth = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-04 17:14:11 +08:00
|
|
|
|
public GpuMultiTexture(Device device, int w, int h, int count, Format f, bool depth, Format df, int msc = 1)
|
2019-12-03 21:52:22 +08:00
|
|
|
|
{
|
2019-12-04 17:14:11 +08:00
|
|
|
|
Init(device, w, h, count, f, depth, df, msc);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
2019-12-04 17:14:11 +08:00
|
|
|
|
public GpuMultiTexture(Device device, int w, int h, int count, Format f, int msc = 1)
|
2019-12-03 21:52:22 +08:00
|
|
|
|
{
|
2019-12-04 17:14:11 +08:00
|
|
|
|
Init(device, w, h, count, f, false, Format.Unknown, msc);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear(DeviceContext context, Color4 colour)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < Count; i++)
|
|
|
|
|
{
|
|
|
|
|
context.ClearRenderTargetView(RTVs[i], colour);
|
|
|
|
|
}
|
|
|
|
|
if (UseDepth)
|
|
|
|
|
{
|
|
|
|
|
context.ClearDepthStencilView(DSV, DepthStencilClearFlags.Depth, 0.0f, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearDepth(DeviceContext context)
|
|
|
|
|
{
|
|
|
|
|
if (!UseDepth) return;
|
|
|
|
|
context.ClearDepthStencilView(DSV, DepthStencilClearFlags.Depth, 0.0f, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetRenderTargets(DeviceContext context)
|
|
|
|
|
{
|
|
|
|
|
context.OutputMerger.SetRenderTargets(UseDepth ? DSV : null, RTVs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|