Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
Buffer.Direct3D.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_DIRECT3D
4 using System;
5 using System.Collections.Generic;
6 
7 using SharpDX;
8 using SharpDX.DXGI;
9 using SharpDX.Direct3D11;
10 
11 namespace SiliconStudio.Paradox.Graphics
12 {
13  public partial class Buffer
14  {
15  private readonly SharpDX.Direct3D11.BufferDescription nativeDescription;
16 
17  internal SharpDX.Direct3D11.Buffer NativeBuffer
18  {
19  get
20  {
21  return (SharpDX.Direct3D11.Buffer)NativeDeviceChild;
22  }
23  }
24 
25  /// <summary>
26  /// Initializes a new instance of the <see cref="Buffer" /> class.
27  /// </summary>
28  /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
29  /// <param name="description">The description.</param>
30  /// <param name="bufferFlags">Type of the buffer.</param>
31  /// <param name="viewFormat">The view format.</param>
32  /// <param name="dataPointer">The data pointer.</param>
33  protected Buffer(GraphicsDevice device, BufferDescription description, BufferFlags bufferFlags, PixelFormat viewFormat, IntPtr dataPointer) : base(device)
34  {
35  Description = description;
36  nativeDescription = ConvertToNativeDescription(Description);
37  BufferFlags = bufferFlags;
38  ViewFormat = viewFormat;
39  InitCountAndViewFormat(out this.elementCount, ref ViewFormat);
40  NativeDeviceChild = new SharpDX.Direct3D11.Buffer(device.RootDevice.NativeDevice, dataPointer, nativeDescription);
41 
42  // Staging resource don't have any views
43  if (nativeDescription.Usage != ResourceUsage.Staging)
44  this.InitializeViews();
45  }
46 
47  /// <inheritdoc/>
48  protected internal override void OnDestroyed()
49  {
50  base.OnDestroyed();
51  DestroyImpl();
52  }
53 
54  /// <inheritdoc/>
55  protected internal override bool OnRecreate()
56  {
57  base.OnRecreate();
58 
59  if (Description.Usage == GraphicsResourceUsage.Immutable
60  || Description.Usage == GraphicsResourceUsage.Default)
61  return false;
62 
63  NativeDeviceChild = new SharpDX.Direct3D11.Buffer(GraphicsDevice.RootDevice.NativeDevice, IntPtr.Zero, nativeDescription);
64 
65  // Staging resource don't have any views
66  if (nativeDescription.Usage != ResourceUsage.Staging)
67  this.InitializeViews();
68 
69  return true;
70  }
71 
72  /// <summary>
73  /// Explicitly recreate buffer with given data. Usually called after a <see cref="GraphicsDevice"/> reset.
74  /// </summary>
75  /// <typeparam name="T"></typeparam>
76  /// <param name="dataPointer"></param>
77  public void Recreate(IntPtr dataPointer)
78  {
79  NativeDeviceChild = new SharpDX.Direct3D11.Buffer(GraphicsDevice.RootDevice.NativeDevice, dataPointer, nativeDescription);
80 
81  // Staging resource don't have any views
82  if (nativeDescription.Usage != ResourceUsage.Staging)
83  this.InitializeViews();
84  }
85 
86  /// <summary>
87  /// Gets a <see cref="ShaderResourceView"/> for a particular <see cref="PixelFormat"/>.
88  /// </summary>
89  /// <param name="viewFormat">The view format.</param>
90  /// <returns>A <see cref="ShaderResourceView"/> for the particular view format.</returns>
91  /// <remarks>
92  /// The buffer must have been declared with <see cref="Graphics.BufferFlags.ShaderResource"/>.
93  /// The ShaderResourceView instance is kept by this buffer and will be disposed when this buffer is disposed.
94  /// </remarks>
95  internal ShaderResourceView GetShaderResourceView(PixelFormat viewFormat)
96  {
97  ShaderResourceView srv = null;
98  if ((nativeDescription.BindFlags & BindFlags.ShaderResource) != 0)
99  {
100  var description = new ShaderResourceViewDescription
101  {
102  Format = (SharpDX.DXGI.Format)viewFormat,
103  Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.ExtendedBuffer,
104  BufferEx =
105  {
106  ElementCount = this.ElementCount,
107  FirstElement = 0,
108  Flags = ShaderResourceViewExtendedBufferFlags.None
109  }
110  };
111 
112  if (((BufferFlags & BufferFlags.RawBuffer) == BufferFlags.RawBuffer))
113  description.BufferEx.Flags |= ShaderResourceViewExtendedBufferFlags.Raw;
114 
115  srv = new ShaderResourceView(this.GraphicsDevice.NativeDevice, NativeResource, description);
116  }
117  return srv;
118  }
119 
120  /// <summary>
121  /// Gets a <see cref="RenderTargetView" /> for a particular <see cref="PixelFormat" />.
122  /// </summary>
123  /// <param name="pixelFormat">The view format.</param>
124  /// <param name="width">The width in pixels of the render target.</param>
125  /// <returns>A <see cref="RenderTargetView" /> for the particular view format.</returns>
126  /// <remarks>The buffer must have been declared with <see cref="Graphics.BufferFlags.RenderTarget" />.
127  /// The RenderTargetView instance is kept by this buffer and will be disposed when this buffer is disposed.</remarks>
128  internal RenderTargetView GetRenderTargetView(PixelFormat pixelFormat, int width)
129  {
130  RenderTargetView srv = null;
131  if ((nativeDescription.BindFlags & BindFlags.RenderTarget) != 0)
132  {
133  var description = new RenderTargetViewDescription()
134  {
135  Format = (SharpDX.DXGI.Format)pixelFormat,
136  Dimension = RenderTargetViewDimension.Buffer,
137  Buffer =
138  {
139  ElementWidth = pixelFormat.SizeInBytes() * width,
140  ElementOffset = 0
141  }
142  };
143 
144  srv = new RenderTargetView(this.GraphicsDevice.NativeDevice, NativeBuffer, description);
145  }
146  return srv;
147  }
148 
149  protected override void OnNameChanged()
150  {
151  base.OnNameChanged();
152  if (GraphicsDevice != null && GraphicsDevice.IsDebugMode)
153  {
154  if (NativeShaderResourceView != null)
155  NativeShaderResourceView.DebugName = Name == null ? null : string.Format("{0} SRV", Name);
156 
157  if (NativeUnorderedAccessView != null)
158  NativeUnorderedAccessView.DebugName = Name == null ? null : string.Format("{0} UAV", Name);
159  }
160  }
161 
162  private void InitCountAndViewFormat(out int count, ref PixelFormat viewFormat)
163  {
164  if (Description.StructureByteStride == 0)
165  {
166  if ((BufferFlags & BufferFlags.RawBuffer) != 0)
167  count = Description.SizeInBytes / sizeof(int);
168  else if ((BufferFlags & BufferFlags.IndexBuffer) != 0)
169  {
170  count = (BufferFlags & BufferFlags.ShaderResource) != 0 ? Description.SizeInBytes / ViewFormat.SizeInBytes() : 0;
171  }
172  else
173  count = 1;
174  }
175  else
176  {
177  // For structured buffer
178  count = Description.SizeInBytes / Description.StructureByteStride;
179  viewFormat = PixelFormat.None;
180  }
181  }
182 
183  private static SharpDX.Direct3D11.BufferDescription ConvertToNativeDescription(BufferDescription bufferDescription)
184  {
185  var desc = new SharpDX.Direct3D11.BufferDescription()
186  {
187  SizeInBytes = bufferDescription.SizeInBytes,
188  StructureByteStride = bufferDescription.StructureByteStride,
189  CpuAccessFlags = GetCpuAccessFlagsFromUsage(bufferDescription.Usage),
190  BindFlags = BindFlags.None,
191  OptionFlags = ResourceOptionFlags.None,
192  Usage = (SharpDX.Direct3D11.ResourceUsage)bufferDescription.Usage,
193  };
194 
195  var bufferFlags = bufferDescription.BufferFlags;
196 
197  if ((bufferFlags & BufferFlags.ConstantBuffer) != 0)
198  desc.BindFlags |= BindFlags.ConstantBuffer;
199 
200  if ((bufferFlags & BufferFlags.IndexBuffer) != 0)
201  desc.BindFlags |= BindFlags.IndexBuffer;
202 
203  if ((bufferFlags & BufferFlags.VertexBuffer) != 0)
204  desc.BindFlags |= BindFlags.VertexBuffer;
205 
206  if ((bufferFlags & BufferFlags.RenderTarget) != 0)
207  desc.BindFlags |= BindFlags.RenderTarget;
208 
209  if ((bufferFlags & BufferFlags.ShaderResource) != 0)
210  desc.BindFlags |= BindFlags.ShaderResource;
211 
212  if ((bufferFlags & BufferFlags.UnorderedAccess) != 0)
213  desc.BindFlags |= BindFlags.UnorderedAccess;
214 
215  if ((bufferFlags & BufferFlags.StructuredBuffer) != 0)
216  {
217  desc.OptionFlags |= ResourceOptionFlags.BufferStructured;
218  if (bufferDescription.StructureByteStride == 0)
219  throw new ArgumentException("Element size cannot be set to 0 for structured buffer");
220  }
221 
222  if ((bufferFlags & BufferFlags.RawBuffer) == BufferFlags.RawBuffer)
223  desc.OptionFlags |= ResourceOptionFlags.BufferAllowRawViews;
224 
225  if ((bufferFlags & BufferFlags.ArgumentBuffer) == BufferFlags.ArgumentBuffer)
226  desc.OptionFlags |= ResourceOptionFlags.DrawIndirectArguments;
227 
228  return desc;
229  }
230 
231  /// <summary>
232  /// Initializes the views.
233  /// </summary>
234  private void InitializeViews()
235  {
236  var bindFlags = nativeDescription.BindFlags;
237 
238  var srvFormat = ViewFormat;
239  var uavFormat = ViewFormat;
240 
241  if (((BufferFlags & BufferFlags.RawBuffer) != 0))
242  {
243  srvFormat = PixelFormat.R32_Typeless;
244  uavFormat = PixelFormat.R32_Typeless;
245  }
246 
247  if ((bindFlags & BindFlags.ShaderResource) != 0)
248  {
249  this.NativeShaderResourceView = GetShaderResourceView(srvFormat);
250  }
251 
252  if ((bindFlags & BindFlags.UnorderedAccess) != 0)
253  {
254  var description = new UnorderedAccessViewDescription()
255  {
256  Format = (SharpDX.DXGI.Format)uavFormat,
257  Dimension = UnorderedAccessViewDimension.Buffer,
258  Buffer =
259  {
260  ElementCount = this.ElementCount,
261  FirstElement = 0,
262  Flags = UnorderedAccessViewBufferFlags.None
263  },
264  };
265 
266  if (((BufferFlags & BufferFlags.RawBuffer) == BufferFlags.RawBuffer))
267  description.Buffer.Flags |= UnorderedAccessViewBufferFlags.Raw;
268 
269  if (((BufferFlags & BufferFlags.StructuredAppendBuffer) == BufferFlags.StructuredAppendBuffer))
270  description.Buffer.Flags |= UnorderedAccessViewBufferFlags.Append;
271 
272  if (((BufferFlags & BufferFlags.StructuredCounterBuffer) == BufferFlags.StructuredCounterBuffer))
273  description.Buffer.Flags |= UnorderedAccessViewBufferFlags.Counter;
274 
275  this.NativeUnorderedAccessView = new UnorderedAccessView(this.GraphicsDevice.NativeDevice, NativeBuffer, description);
276  }
277  }
278  }
279 }
280 #endif
GraphicsResourceUsage
Identifies expected resource use during rendering. The usage directly reflects whether a resource is ...
SiliconStudio.Paradox.Graphics.Buffer Buffer
Definition: BasicEffect.cs:15
Flags
Enumeration of the new Assimp's flags.
_In_ size_t count
Definition: DirectXTexP.h:174
PixelFormat
Defines various types of pixel formats.
Definition: PixelFormat.cs:32