Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
GraphicsDevice.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 
6 using SharpDX.Direct3D11;
7 
8 using SiliconStudio.Core;
9 using SiliconStudio.Core.Mathematics;
10 using SiliconStudio.Paradox.Shaders;
11 
12 namespace SiliconStudio.Paradox.Graphics
13 {
14  public partial class GraphicsDevice
15  {
16  private bool simulateReset = false;
17  private const int ConstantBufferCount = SharpDX.Direct3D11.CommonShaderStage.ConstantBufferApiSlotCount; // 14 actually
18  private const int SamplerStateCount = SharpDX.Direct3D11.CommonShaderStage.SamplerSlotCount;
19  private const int ShaderResourceViewCount = SharpDX.Direct3D11.CommonShaderStage.InputResourceSlotCount;
20  private const int SimultaneousRenderTargetCount = SharpDX.Direct3D11.OutputMergerStage.SimultaneousRenderTargetCount;
21  private const int StageCount = 6;
22  private const int UnorderedAcccesViewCount = SharpDX.Direct3D11.ComputeShaderStage.UnorderedAccessViewSlotCount;
23 
24  private readonly Buffer[] constantBuffers = new Buffer[StageCount*ConstantBufferCount];
25  private readonly SharpDX.Direct3D11.RenderTargetView[] currentRenderTargetViews = new SharpDX.Direct3D11.RenderTargetView[SimultaneousRenderTargetCount];
26  private readonly SamplerState[] samplerStates = new SamplerState[StageCount*SamplerStateCount];
27  private readonly SharpDX.Direct3D11.CommonShaderStage[] shaderStages = new SharpDX.Direct3D11.CommonShaderStage[StageCount];
28  private readonly GraphicsResourceBase[] unorderedAccessViews = new GraphicsResourceBase[UnorderedAcccesViewCount]; // Only CS
29 
30  private SharpDX.Direct3D11.Device nativeDevice;
31  private SharpDX.Direct3D11.DeviceContext nativeDeviceContext;
32  private SharpDX.Direct3D11.InputAssemblerStage inputAssembler;
33  private SharpDX.Direct3D11.OutputMergerStage outputMerger;
34 
35  private int actualRenderTargetViewCount;
36  private SharpDX.Direct3D11.DeviceCreationFlags creationFlags;
37  private EffectInputSignature currentEffectInputSignature;
38  private SharpDX.Direct3D11.InputLayout currentInputLayout;
39  private SharpDX.Direct3D11.RenderTargetView currentRenderTargetView;
40  private VertexArrayLayout currentVertexArrayLayout;
41  private SharpDX.ViewportF[] currentNativeViewports = new SharpDX.ViewportF[16];
42  private Viewport[] currentViewports;
43 
44  /// <summary>
45  /// Initializes a new instance of the <see cref="GraphicsDevice" /> class using the default GraphicsAdapter
46  /// and the Level10 <see cref="GraphicsProfile" />.
47  /// </summary>
48  /// <param name="device">The device.</param>
49  private GraphicsDevice(GraphicsDevice device)
50  {
51  RootDevice = device;
52  Adapter = device.Adapter;
53  creationFlags = device.creationFlags;
54  Features = device.Features;
55  sharedDataPerDevice = device.sharedDataPerDevice;
56  InputLayoutManager = device.InputLayoutManager;
57  nativeDevice = device.NativeDevice;
58  nativeDeviceContext = new SharpDX.Direct3D11.DeviceContext(NativeDevice).DisposeBy(this);
59  isDeferred = true;
60  IsDebugMode = device.IsDebugMode;
61  if (IsDebugMode)
62  {
63  GraphicsResourceBase.SetDebugName(device, nativeDeviceContext, "DeferredContext");
64  }
65  NeedWorkAroundForUpdateSubResource = !Features.HasDriverCommandLists;
66 
67  primitiveQuad = new PrimitiveQuad(this).DisposeBy(this);
68 
69  InitializeStages();
70  }
71 
72  private void SetDefaultStates()
73  {
74  }
75 
76  // Used by Texture.SetData
77 
78  /// <summary>
79  /// Gets the status of this device.
80  /// </summary>
81  /// <value>The graphics device status.</value>
83  {
84  get
85  {
86  if (simulateReset)
87  {
88  simulateReset = false;
89  return GraphicsDeviceStatus.Reset;
90  }
91 
92  var result = NativeDevice.DeviceRemovedReason;
93  if (result == SharpDX.DXGI.ResultCode.DeviceRemoved)
94  {
95  return GraphicsDeviceStatus.Removed;
96  }
97 
98  if (result == SharpDX.DXGI.ResultCode.DeviceReset)
99  {
100  return GraphicsDeviceStatus.Reset;
101  }
102 
103  if (result == SharpDX.DXGI.ResultCode.DeviceHung)
104  {
105  return GraphicsDeviceStatus.Hung;
106  }
107 
108  if (result == SharpDX.DXGI.ResultCode.DriverInternalError)
109  {
110  return GraphicsDeviceStatus.InternalError;
111  }
112 
113  if (result == SharpDX.DXGI.ResultCode.InvalidCall)
114  {
115  return GraphicsDeviceStatus.InvalidCall;
116  }
117 
118  if (result.Code < 0)
119  {
120  return GraphicsDeviceStatus.Reset;
121  }
122 
123  return GraphicsDeviceStatus.Normal;
124  }
125  }
126 
127  /// <summary>
128  /// Gets the first viewport.
129  /// </summary>
130  /// <value>The first viewport.</value>
131  public Viewport Viewport
132  {
133  get
134  {
135  return currentViewports[0];
136  }
137  }
138 
139  /// <summary>
140  /// Gets the input layout manager.
141  /// </summary>
142  /// <value>The input layout manager.</value>
143  internal InputLayoutManager InputLayoutManager { get; private set; }
144 
145  /// <summary>
146  /// Gets the native device.
147  /// </summary>
148  /// <value>The native device.</value>
149  internal SharpDX.Direct3D11.Device NativeDevice
150  {
151  get
152  {
153  return nativeDevice;
154  }
155  }
156 
157  /// <summary>
158  /// Gets the native device context.
159  /// </summary>
160  /// <value>The native device context.</value>
161  internal SharpDX.Direct3D11.DeviceContext NativeDeviceContext
162  {
163  get
164  {
165  return nativeDeviceContext;
166  }
167  }
168 
169  /// <summary>
170  /// Sets the type of the primitive.
171  /// </summary>
172  /// <value>The type of the primitive.</value>
174  {
175  set
176  {
177  inputAssembler.PrimitiveTopology = (SharpDX.Direct3D.PrimitiveTopology)value;
178  }
179  }
180 
181  public void ApplyPlatformSpecificParams(Effect effect)
182  {
183  }
184 
185  /// <summary>
186  /// Marks context as active on the current thread.
187  /// </summary>
188  public void Begin()
189  {
190  }
191 
192  /// <summary>
193  /// Begins profiling.
194  /// </summary>
195  /// <param name="profileColor">Color of the profile.</param>
196  /// <param name="name">The name.</param>
197  public void BeginProfile(Color4 profileColor, string name)
198  {
199 #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
200  SharpDX.Direct3D.PixHelper.BeginEvent(new SharpDX.ColorBGRA(profileColor.ToBgra()), name);
201 #endif
202  }
203 
204  /// <summary>
205  /// Clears the specified depth stencil buffer. See <see cref="Textures+and+render+targets"/> to learn how to use it.
206  /// </summary>
207  /// <param name="depthStencilBuffer">The depth stencil buffer.</param>
208  /// <param name="options">The options.</param>
209  /// <param name="depth">The depth.</param>
210  /// <param name="stencil">The stencil.</param>
211  /// <exception cref="System.InvalidOperationException"></exception>
212  public void Clear(DepthStencilBuffer depthStencilBuffer, DepthStencilClearOptions options, float depth = 1, byte stencil = 0)
213  {
214  if (depthStencilBuffer == null) throw new ArgumentNullException("depthStencilBuffer");
215 
216  var flags = ((options & DepthStencilClearOptions.DepthBuffer) != 0) ? SharpDX.Direct3D11.DepthStencilClearFlags.Depth : 0;
217 
218  // Check that the DepthStencilBuffer has a Stencil if Clear Stencil is requested
219  if ((options & DepthStencilClearOptions.Stencil) != 0)
220  {
221  if (!depthStencilBuffer.HasStencil)
222  throw new InvalidOperationException(string.Format(FrameworkResources.NoStencilBufferForDepthFormat, depthStencilBuffer.Description.Format));
223  flags |= SharpDX.Direct3D11.DepthStencilClearFlags.Stencil;
224  }
225 
226  NativeDeviceContext.ClearDepthStencilView(depthStencilBuffer.NativeDepthStencilView, flags, depth, stencil);
227  }
228 
229  /// <summary>
230  /// Clears the specified render target. See <see cref="Textures+and+render+targets"/> to learn how to use it.
231  /// </summary>
232  /// <param name="renderTarget">The render target.</param>
233  /// <param name="color">The color.</param>
234  /// <exception cref="System.ArgumentNullException">renderTarget</exception>
235  public unsafe void Clear(RenderTarget renderTarget, Color4 color)
236  {
237  if (renderTarget == null) throw new ArgumentNullException("renderTarget");
238 
239  NativeDeviceContext.ClearRenderTargetView(renderTarget.NativeRenderTargetView, *(SharpDX.Color4*)&color);
240  }
241 
242  /// <summary>
243  /// Clears a read-write Buffer. This buffer must have been created with read-write/unordered access.
244  /// </summary>
245  /// <param name="buffer">The buffer.</param>
246  /// <param name="value">The value.</param>
247  /// <exception cref="System.ArgumentNullException">buffer</exception>
248  /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;buffer</exception>
249  public unsafe void ClearReadWrite(Buffer buffer, Vector4 value)
250  {
251  if (buffer == null) throw new ArgumentNullException("buffer");
252  if (buffer.NativeUnorderedAccessView == null) throw new ArgumentException("Expecting buffer supporting UAV", "buffer");
253 
254  NativeDeviceContext.ClearUnorderedAccessView(buffer.NativeUnorderedAccessView, *(SharpDX.Vector4*)&value);
255  }
256 
257  /// <summary>
258  /// Clears a read-write Buffer. This buffer must have been created with read-write/unordered access.
259  /// </summary>
260  /// <param name="buffer">The buffer.</param>
261  /// <param name="value">The value.</param>
262  /// <exception cref="System.ArgumentNullException">buffer</exception>
263  /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;buffer</exception>
264  public unsafe void ClearReadWrite(Buffer buffer, Int4 value)
265  {
266  if (buffer == null) throw new ArgumentNullException("buffer");
267  if (buffer.NativeUnorderedAccessView == null) throw new ArgumentException("Expecting buffer supporting UAV", "buffer");
268 
269  NativeDeviceContext.ClearUnorderedAccessView(buffer.NativeUnorderedAccessView, *(SharpDX.Int4*)&value);
270  }
271 
272  /// <summary>
273  /// Clears a read-write Buffer. This buffer must have been created with read-write/unordered access.
274  /// </summary>
275  /// <param name="buffer">The buffer.</param>
276  /// <param name="value">The value.</param>
277  /// <exception cref="System.ArgumentNullException">buffer</exception>
278  /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;buffer</exception>
279  public unsafe void ClearReadWrite(Buffer buffer, UInt4 value)
280  {
281  if (buffer == null) throw new ArgumentNullException("buffer");
282  if (buffer.NativeUnorderedAccessView == null) throw new ArgumentException("Expecting buffer supporting UAV", "buffer");
283 
284  NativeDeviceContext.ClearUnorderedAccessView(buffer.NativeUnorderedAccessView, *(SharpDX.Int4*)&value);
285  }
286 
287  /// <summary>
288  /// Clears a read-write Texture. This texture must have been created with read-write/unordered access.
289  /// </summary>
290  /// <param name="texture">The texture.</param>
291  /// <param name="value">The value.</param>
292  /// <exception cref="System.ArgumentNullException">texture</exception>
293  /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;texture</exception>
294  public unsafe void ClearReadWrite(Texture texture, Vector4 value)
295  {
296  if (texture == null) throw new ArgumentNullException("texture");
297  if (texture.NativeUnorderedAccessView == null) throw new ArgumentException("Expecting buffer supporting UAV", "texture");
298 
299  NativeDeviceContext.ClearUnorderedAccessView(texture.NativeUnorderedAccessView, *(SharpDX.Vector4*)&value);
300  }
301 
302  /// <summary>
303  /// Clears a read-write Texture. This texture must have been created with read-write/unordered access.
304  /// </summary>
305  /// <param name="texture">The texture.</param>
306  /// <param name="value">The value.</param>
307  /// <exception cref="System.ArgumentNullException">texture</exception>
308  /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;texture</exception>
309  public unsafe void ClearReadWrite(Texture texture, Int4 value)
310  {
311  if (texture == null) throw new ArgumentNullException("texture");
312  if (texture.NativeUnorderedAccessView == null) throw new ArgumentException("Expecting buffer supporting UAV", "texture");
313 
314  NativeDeviceContext.ClearUnorderedAccessView(texture.NativeUnorderedAccessView, *(SharpDX.Int4*)&value);
315  }
316 
317  /// <summary>
318  /// Clears a read-write Texture. This texture must have been created with read-write/unordered access.
319  /// </summary>
320  /// <param name="texture">The texture.</param>
321  /// <param name="value">The value.</param>
322  /// <exception cref="System.ArgumentNullException">texture</exception>
323  /// <exception cref="System.ArgumentException">Expecting buffer supporting UAV;texture</exception>
324  public unsafe void ClearReadWrite(Texture texture, UInt4 value)
325  {
326  if (texture == null) throw new ArgumentNullException("texture");
327  if (texture.NativeUnorderedAccessView == null) throw new ArgumentException("Expecting buffer supporting UAV", "texture");
328 
329  NativeDeviceContext.ClearUnorderedAccessView(texture.NativeUnorderedAccessView, *(SharpDX.Int4*)&value);
330  }
331 
332  public void ClearState()
333  {
334  NativeDeviceContext.ClearState();
335  for (int i = 0; i < currentViewports.Length; i++)
336  currentViewports[i] = new Viewport();
337 
338  for (int i = 0; i < samplerStates.Length; ++i)
339  samplerStates[i] = null;
340  for (int i = 0; i < constantBuffers.Length; ++i)
341  constantBuffers[i] = null;
342  for (int i = 0; i < unorderedAccessViews.Length; ++i)
343  unorderedAccessViews[i] = null;
344  for (int i = 0; i < currentRenderTargetViews.Length; i++)
345  currentRenderTargetViews[i] = null;
346 
347  currentEffectInputSignature = null;
348  currentVertexArrayLayout = null;
349  currentInputLayout = null;
350  CurrentEffect = null;
351 
352  SetRenderTarget(DepthStencilBuffer, BackBuffer);
353  }
354 
355  public void Copy(GraphicsResource source, GraphicsResource destination)
356  {
357  if (source == null) throw new ArgumentNullException("source");
358  if (destination == null) throw new ArgumentNullException("destination");
359  NativeDeviceContext.CopyResource(source.NativeResource, destination.NativeResource);
360  }
361 
362  public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion? sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0)
363  {
364  if (source == null) throw new ArgumentNullException("source");
365  if (destination == null) throw new ArgumentNullException("destination");
366 
367  var nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion?();
368 
369  if (sourecRegion.HasValue)
370  {
371  var value = sourecRegion.Value;
372  nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion(value.Left, value.Top, value.Front, value.Right, value.Bottom, value.Back);
373  }
374 
375  NativeDeviceContext.CopySubresourceRegion(source.NativeResource, sourceSubresource, nullableSharpDxRegion, destination.NativeResource, destinationSubResource, dstX, dstY, dstZ);
376  }
377 
378  /// <inheritdoc />
379  public void CopyCount(Buffer sourceBuffer, Buffer destBuffer, int offsetInBytes)
380  {
381  if (sourceBuffer == null) throw new ArgumentNullException("sourceBuffer");
382  if (destBuffer == null) throw new ArgumentNullException("destBuffer");
383  NativeDeviceContext.CopyStructureCount(destBuffer.NativeBuffer, offsetInBytes, sourceBuffer.NativeUnorderedAccessView);
384  }
385 
386  /// <inheritdoc />
387  public void Dispatch(int threadCountX, int threadCountY, int threadCountZ)
388  {
389  NativeDeviceContext.Dispatch(threadCountX, threadCountY, threadCountZ);
390  }
391 
392  /// <summary>
393  /// Dispatches the specified indirect buffer.
394  /// </summary>
395  /// <param name="indirectBuffer">The indirect buffer.</param>
396  /// <param name="offsetInBytes">The offset information bytes.</param>
397  public void Dispatch(Buffer indirectBuffer, int offsetInBytes)
398  {
399  if (indirectBuffer == null) throw new ArgumentNullException("indirectBuffer");
400  NativeDeviceContext.DispatchIndirect(indirectBuffer.NativeBuffer, offsetInBytes);
401  }
402 
403  /// <summary>
404  /// Draw non-indexed, non-instanced primitives.
405  /// </summary>
406  /// <param name="primitiveType">Type of the primitive to draw.</param>
407  /// <param name="vertexCount">Number of vertices to draw.</param>
408  /// <param name="startVertexLocation">Index of the first vertex, which is usually an offset in a vertex buffer; it could also be used as the first vertex id generated for a shader parameter marked with the <strong>SV_TargetId</strong> system-value semantic.</param>
409  public void Draw(PrimitiveType primitiveType, int vertexCount, int startVertexLocation = 0)
410  {
411  PrepareDraw(primitiveType);
412 
413  NativeDeviceContext.Draw(vertexCount, startVertexLocation);
414  }
415 
416  /// <summary>
417  /// Draw geometry of an unknown size.
418  /// </summary>
419  /// <param name="primitiveType">Type of the primitive to draw.</param>
420  public void DrawAuto(PrimitiveType primitiveType)
421  {
422  PrepareDraw(primitiveType);
423 
424  NativeDeviceContext.DrawAuto();
425  }
426 
427  /// <summary>
428  /// Draw indexed, non-instanced primitives.
429  /// </summary>
430  /// <param name="primitiveType">Type of the primitive to draw.</param>
431  /// <param name="indexCount">Number of indices to draw.</param>
432  /// <param name="startIndexLocation">The location of the first index read by the GPU from the index buffer.</param>
433  /// <param name="baseVertexLocation">A value added to each index before reading a vertex from the vertex buffer.</param>
434  public void DrawIndexed(PrimitiveType primitiveType, int indexCount, int startIndexLocation = 0, int baseVertexLocation = 0)
435  {
436  PrepareDraw(primitiveType);
437 
438  NativeDeviceContext.DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
439  }
440 
441  /// <summary>
442  /// Draw indexed, instanced primitives.
443  /// </summary>
444  /// <param name="primitiveType">Type of the primitive to draw.</param>
445  /// <param name="indexCountPerInstance">Number of indices read from the index buffer for each instance.</param>
446  /// <param name="instanceCount">Number of instances to draw.</param>
447  /// <param name="startIndexLocation">The location of the first index read by the GPU from the index buffer.</param>
448  /// <param name="baseVertexLocation">A value added to each index before reading a vertex from the vertex buffer.</param>
449  /// <param name="startInstanceLocation">A value added to each index before reading per-instance data from a vertex buffer.</param>
450  public void DrawIndexedInstanced(PrimitiveType primitiveType, int indexCountPerInstance, int instanceCount, int startIndexLocation = 0, int baseVertexLocation = 0, int startInstanceLocation = 0)
451  {
452  PrepareDraw(primitiveType);
453 
454  NativeDeviceContext.DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
455  }
456 
457  /// <summary>
458  /// Draw indexed, instanced, GPU-generated primitives.
459  /// </summary>
460  /// <param name="primitiveType">Type of the primitive to draw.</param>
461  /// <param name="argumentsBuffer">A buffer containing the GPU generated primitives.</param>
462  /// <param name="alignedByteOffsetForArgs">Offset in <em>pBufferForArgs</em> to the start of the GPU generated primitives.</param>
463  public void DrawIndexedInstanced(PrimitiveType primitiveType, Buffer argumentsBuffer, int alignedByteOffsetForArgs = 0)
464  {
465  if (argumentsBuffer == null) throw new ArgumentNullException("argumentsBuffer");
466 
467  PrepareDraw(primitiveType);
468 
469  NativeDeviceContext.DrawIndexedInstancedIndirect(argumentsBuffer.NativeBuffer, alignedByteOffsetForArgs);
470  }
471 
472  /// <summary>
473  /// Draw non-indexed, instanced primitives.
474  /// </summary>
475  /// <param name="primitiveType">Type of the primitive to draw.</param>
476  /// <param name="vertexCountPerInstance">Number of vertices to draw.</param>
477  /// <param name="instanceCount">Number of instances to draw.</param>
478  /// <param name="startVertexLocation">Index of the first vertex.</param>
479  /// <param name="startInstanceLocation">A value added to each index before reading per-instance data from a vertex buffer.</param>
480  public void DrawInstanced(PrimitiveType primitiveType, int vertexCountPerInstance, int instanceCount, int startVertexLocation = 0, int startInstanceLocation = 0)
481  {
482  PrepareDraw(primitiveType);
483 
484  NativeDeviceContext.DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
485  }
486 
487  /// <summary>
488  /// Draw instanced, GPU-generated primitives.
489  /// </summary>
490  /// <param name="primitiveType">Type of the primitive to draw.</param>
491  /// <param name="argumentsBuffer">An arguments buffer</param>
492  /// <param name="alignedByteOffsetForArgs">Offset in <em>pBufferForArgs</em> to the start of the GPU generated primitives.</param>
493  public void DrawInstanced(PrimitiveType primitiveType, Buffer argumentsBuffer, int alignedByteOffsetForArgs = 0)
494  {
495  if (argumentsBuffer == null) throw new ArgumentNullException("argumentsBuffer");
496 
497  PrepareDraw(primitiveType);
498 
499  NativeDeviceContext.DrawIndexedInstancedIndirect(argumentsBuffer.NativeBuffer, alignedByteOffsetForArgs);
500  }
501 
502  /// <summary>
503  /// Enables profiling.
504  /// </summary>
505  /// <param name="enabledFlag">if set to <c>true</c> [enabled flag].</param>
506  public void EnableProfile(bool enabledFlag)
507  {
508 #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
509  SharpDX.Direct3D.PixHelper.AllowProfiling(enabledFlag);
510 #endif
511  }
512 
513  /// <summary>
514  /// Unmarks context as active on the current thread.
515  /// </summary>
516  public void End()
517  {
518  }
519 
520  /// <summary>
521  /// Ends profiling.
522  /// </summary>
523  public void EndProfile()
524  {
525 #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
526  SharpDX.Direct3D.PixHelper.EndEvent();
527 #endif
528  }
529 
530  /// <summary>
531  /// Executes a deferred command list.
532  /// </summary>
533  /// <param name="commandList">The deferred command list.</param>
534  public void ExecuteCommandList(ICommandList commandList)
535  {
536  if (commandList == null) throw new ArgumentNullException("commandList");
537 
538  NativeDeviceContext.ExecuteCommandList(((CommandList)commandList).NativeCommandList, false);
539  commandList.Release();
540  }
541 
542  /// <summary>
543  /// Finishes a deffered command list.
544  /// </summary>
545  /// <returns>A deferred command list.</returns>
546  public ICommandList FinishCommandList()
547  {
548  return new CommandList(NativeDeviceContext.FinishCommandList(false));
549  }
550 
551  /// <summary>
552  /// Maps a subresource.
553  /// </summary>
554  /// <param name="resource">The resource.</param>
555  /// <param name="subResourceIndex">Index of the sub resource.</param>
556  /// <param name="mapMode">The map mode.</param>
557  /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param>
558  /// <param name="offsetInBytes">The offset information in bytes.</param>
559  /// <param name="lengthInBytes">The length information in bytes.</param>
560  /// <returns>Pointer to the sub resource to map.</returns>
561  public unsafe MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0)
562  {
563  if (resource == null) throw new ArgumentNullException("resource");
564  SharpDX.DataBox dataBox = NativeDeviceContext.MapSubresource(resource.NativeResource, subResourceIndex, (SharpDX.Direct3D11.MapMode)mapMode, doNotWait ? SharpDX.Direct3D11.MapFlags.DoNotWait : SharpDX.Direct3D11.MapFlags.None);
565  var databox = *(DataBox*)Interop.Cast(ref dataBox);
566  if (!dataBox.IsEmpty)
567  {
568  databox.DataPointer = (IntPtr)((byte*)databox.DataPointer + offsetInBytes);
569  }
570  return new MappedResource(resource, subResourceIndex, databox);
571  }
572 
573  /// <summary>
574  /// Creates a new deferred device used for multithread deferred rendering.
575  /// </summary>
576  /// <returns>GraphicsDevice.</returns>
577  public GraphicsDevice NewDeferred()
578  {
579  return new GraphicsDevice(RootDevice);
580  }
581 
582  /// <summary>
583  /// Unbinds all depth-stencil buffer and render targets from the output-merger stage.
584  /// </summary>
585  public void ResetTargets()
586  {
587  for (int i = 0; i < currentRenderTargetViews.Length; i++)
588  currentRenderTargetViews[i] = null;
589  actualRenderTargetViewCount = 0;
590  currentRenderTargetView = null;
591  outputMerger.ResetTargets();
592  }
593 
594  /// <summary>
595  /// Set the blend state of the output-merger stage with a white default blend color and sample mask set to 0xffffffff. See <see cref="Render+states"/> to learn how to use it.
596  /// </summary>
597  /// <param name="blendState">a blend-state</param>
598  public void SetBlendState(BlendState blendState)
599  {
600  if (blendState == null)
601  {
602  NativeDeviceContext.OutputMerger.SetBlendState(null, SharpDX.Color.White, -1);
603  }
604  else
605  {
606  NativeDeviceContext.OutputMerger.SetBlendState((SharpDX.Direct3D11.BlendState)blendState.NativeDeviceChild, ColorHelper.Convert(blendState.BlendFactor), blendState.MultiSampleMask);
607  }
608  }
609 
610  /// <summary>
611  /// Set the blend state of the output-merger stage. See <see cref="Render+states"/> to learn how to use it.
612  /// </summary>
613  /// <param name="blendState">a blend-state</param>
614  /// <param name="blendFactor">Blend factors, one for each RGBA component. This requires a blend state object that specifies the <see cref="Blend.BlendFactor" /></param>
615  /// <param name="multiSampleMask">32-bit sample coverage. The default value is 0xffffffff.</param>
616  public void SetBlendState(BlendState blendState, Color4 blendFactor, int multiSampleMask = -1)
617  {
618  if (blendState == null)
619  {
620  NativeDeviceContext.OutputMerger.SetBlendState(null, ColorHelper.Convert(blendFactor), multiSampleMask);
621  }
622  else
623  {
624  NativeDeviceContext.OutputMerger.SetBlendState((SharpDX.Direct3D11.BlendState)blendState.NativeDeviceChild, ColorHelper.Convert(blendFactor), multiSampleMask);
625  }
626  }
627 
628  /// <summary>
629  /// Set the blend state of the output-merger stage. See <see cref="Render+states"/> to learn how to use it.
630  /// </summary>
631  /// <param name="blendState">a blend-state</param>
632  /// <param name="blendFactor">Blend factors, one for each RGBA component. This requires a blend state object that specifies the <see cref="Blend.BlendFactor" /></param>
633  /// <param name="multiSampleMask">32-bit sample coverage. The default value is 0xffffffff.</param>
634  public void SetBlendState(BlendState blendState, Color4 blendFactor, uint multiSampleMask = 0xFFFFFFFF)
635  {
636  SetBlendState(blendState, blendFactor, unchecked((int)multiSampleMask));
637  }
638 
639  /// <summary>
640  /// Sets the depth-stencil state of the output-merger stage. See <see cref="Render+states"/> to learn how to use it.
641  /// </summary>
642  /// <param name="depthStencilState">a depth-stencil state</param>
643  /// <param name="stencilReference">Reference value to perform against when doing a depth-stencil test.</param>
644  public void SetDepthStencilState(DepthStencilState depthStencilState, int stencilReference = 0)
645  {
646  NativeDeviceContext.OutputMerger.SetDepthStencilState(depthStencilState != null ? (SharpDX.Direct3D11.DepthStencilState)depthStencilState.NativeDeviceChild : null, stencilReference);
647  }
648 
649  /// <summary>
650  /// Set the <strong>rasterizer state</strong> for the rasterizer stage of the pipeline. See <see cref="Render+states"/> to learn how to use it.
651  /// </summary>
652  /// <param name="rasterizerState">The rasterizser state to set on this device.</param>
653  public void SetRasterizerState(RasterizerState rasterizerState)
654  {
655  NativeDeviceContext.Rasterizer.State = rasterizerState != null ? (SharpDX.Direct3D11.RasterizerState)rasterizerState.NativeDeviceChild : null;
656  }
657 
658  /// <summary>
659  /// Binds a depth-stencil buffer and a single render target to the output-merger stage. See <see cref="Textures+and+render+targets"/> to learn how to use it.
660  /// </summary>
661  /// <param name="depthStencilView">A view of the depth-stencil buffer to bind.</param>
662  /// <param name="renderTargetView">A view of the render target to bind.</param>
663  public void SetRenderTarget(DepthStencilBuffer depthStencilView, RenderTarget renderTargetView)
664  {
665  CommonSetRenderTargets(depthStencilView, renderTargetView);
666  outputMerger.SetTargets(depthStencilView != null ? depthStencilView.NativeDepthStencilView : null, currentRenderTargetView);
667  }
668 
669  /// <summary>
670  /// Binds a depth-stencil buffer and a set of render targets to the output-merger stage. See <see cref="Textures+and+render+targets"/> to learn how to use it.
671  /// </summary>
672  /// <param name="depthStencilView">A view of the depth-stencil buffer to bind.</param>
673  /// <param name="renderTargetViews">A set of render target views to bind.</param>
674  /// <exception cref="System.ArgumentNullException">renderTargetViews</exception>
675  public void SetRenderTargets(DepthStencilBuffer depthStencilView, params RenderTarget[] renderTargetViews)
676  {
677  if (renderTargetViews == null) throw new ArgumentNullException("renderTargetViews");
678  CommonSetRenderTargets(depthStencilView, renderTargetViews);
679  outputMerger.SetTargets(depthStencilView != null ? depthStencilView.NativeDepthStencilView : null, actualRenderTargetViewCount, currentRenderTargetViews);
680  }
681 
682  /// <summary>
683  /// Binds a single scissor rectangle to the rasterizer stage. See <see cref="Render+states"/> to learn how to use it.
684  /// </summary>
685  /// <param name="left">The left.</param>
686  /// <param name="top">The top.</param>
687  /// <param name="right">The right.</param>
688  /// <param name="bottom">The bottom.</param>
689  public void SetScissorRectangles(int left, int top, int right, int bottom)
690  {
691  NativeDeviceContext.Rasterizer.SetScissorRectangle(left, top, right, bottom);
692  }
693 
694  /// <summary>
695  /// Binds a set of scissor rectangles to the rasterizer stage. See <see cref="Render+states"/> to learn how to use it.
696  /// </summary>
697  /// <param name="scissorRectangles">The set of scissor rectangles to bind.</param>
698  public unsafe void SetScissorRectangles(params Rectangle[] scissorRectangles)
699  {
700  if (scissorRectangles == null) throw new ArgumentNullException("scissorRectangles");
701  var localScissorRectangles = new SharpDX.Rectangle[scissorRectangles.Length];
702  Utilities.Write((IntPtr)Interop.Fixed(localScissorRectangles), scissorRectangles, 0, scissorRectangles.Length);
703  NativeDeviceContext.Rasterizer.SetScissorRectangles(localScissorRectangles);
704  }
705 
706  /// <summary>
707  /// Sets the stream targets.
708  /// </summary>
709  /// <param name="buffers">The buffers.</param>
710  public void SetStreamTargets(params Buffer[] buffers)
711  {
712  SharpDX.Direct3D11.StreamOutputBufferBinding[] streamOutputBufferBindings;
713 
714  if (buffers != null)
715  {
716  streamOutputBufferBindings = new SharpDX.Direct3D11.StreamOutputBufferBinding[buffers.Length];
717  for (int i = 0; i < buffers.Length; ++i)
718  streamOutputBufferBindings[i].Buffer = buffers[i].NativeBuffer;
719  }
720  else
721  {
722  streamOutputBufferBindings = null;
723  }
724 
725  NativeDeviceContext.StreamOutput.SetTargets(streamOutputBufferBindings);
726  }
727 
728  /// <summary>
729  /// Sets the vertex array object.
730  /// </summary>
731  /// <param name="vertexArrayObject">The vertex array object.</param>
732  public void SetVertexArrayObject(VertexArrayObject vertexArrayObject)
733  {
734  if (vertexArrayObject == null)
735  {
736  inputAssembler.InputLayout = null;
737  IntPtr vertexBufferPtr = IntPtr.Zero;
738  unsafe
739  {
740  var ptrToNull = new IntPtr(&vertexBufferPtr);
741  // TODO RESET MORE Vertex Buffers
742  inputAssembler.SetVertexBuffers(0, 1, ptrToNull, ptrToNull, ptrToNull);
743  }
744  }
745 
746  newVertexArrayObject = vertexArrayObject;
747  }
748 
749  /// <summary>
750  /// Gets or sets the 1st viewport. See <see cref="Render+states"/> to learn how to use it.
751  /// </summary>
752  /// <value>The viewport.</value>
753  public void SetViewport(Viewport value)
754  {
755  SetViewport(0, value);
756  }
757 
758  /// <summary>
759  /// Gets or sets the 1st viewport. See <see cref="Render+states"/> to learn how to use it.
760  /// </summary>
761  /// <value>The viewport.</value>
762  public void SetViewport(int index, Viewport value)
763  {
764  currentViewports[index] = value;
765  unsafe
766  {
767  Utilities.ReadOut(new IntPtr(&value), out currentNativeViewports[index]);
768  }
769  nativeDeviceContext.Rasterizer.SetViewports(currentNativeViewports);
770  }
771 
772  public void UnmapSubresource(MappedResource unmapped)
773  {
774  NativeDeviceContext.UnmapSubresource(unmapped.Resource.NativeResource, unmapped.SubResourceIndex);
775  }
776 
777  /// <summary>
778  /// Unsets the read/write buffers.
779  /// </summary>
780  public void UnsetReadWriteBuffers()
781  {
782  // TODO optimize it using SetUnorderedAccessViews
783  for (int i = 0; i < UnorderedAcccesViewCount; i++)
784  {
785  SetUnorderedAccessView(ShaderStage.Compute, i, null);
786  }
787  }
788 
789  /// <summary>
790  /// Unsets the render targets.
791  /// </summary>
792  public void UnsetRenderTargets()
793  {
794  NativeDeviceContext.OutputMerger.ResetTargets();
795  }
796 
797  public void SimulateReset()
798  {
799  simulateReset = true;
800  }
801 
802  /// <summary>
803  /// Sets a constant buffer to the shader pipeline.
804  /// </summary>
805  /// <param name="stage">The shader stage.</param>
806  /// <param name="slot">The binding slot.</param>
807  /// <param name="buffer">The constant buffer to set.</param>
808  internal void SetConstantBuffer(ShaderStage stage, int slot, Buffer buffer)
809  {
810  if (stage == ShaderStage.None)
811  throw new ArgumentException("Cannot use Stage.None", "stage");
812 
813  int stageIndex = (int)stage - 1;
814 
815  int slotIndex = stageIndex*ConstantBufferCount + slot;
816  if (constantBuffers[slotIndex] != buffer)
817  {
818  constantBuffers[slotIndex] = buffer;
819  shaderStages[stageIndex].SetConstantBuffer(slot, buffer != null ? buffer.NativeBuffer : null);
820  }
821  }
822 
823  /// <summary>
824  /// Sets a sampler state to the shader pipeline.
825  /// </summary>
826  /// <param name="stage">The shader stage.</param>
827  /// <param name="slot">The binding slot.</param>
828  /// <param name="samplerState">The sampler state to set.</param>
829  internal void SetSamplerState(ShaderStage stage, int slot, SamplerState samplerState)
830  {
831  if (stage == ShaderStage.None)
832  throw new ArgumentException("Cannot use Stage.None", "stage");
833  int stageIndex = (int)stage - 1;
834 
835  int slotIndex = stageIndex*SamplerStateCount + slot;
836  if (samplerStates[slotIndex] != samplerState)
837  {
838  samplerStates[slotIndex] = samplerState;
839  shaderStages[stageIndex].SetSampler(slot, samplerState != null ? (SharpDX.Direct3D11.SamplerState)samplerState.NativeDeviceChild : null);
840  }
841  }
842 
843  /// <summary>
844  /// Sets a shader resource view to the shader pipeline.
845  /// </summary>
846  /// <param name="stage">The shader stage.</param>
847  /// <param name="slot">The binding slot.</param>
848  /// <param name="shaderResourceView">The shader resource view.</param>
849  internal void SetShaderResourceView(ShaderStage stage, int slot, GraphicsResource shaderResourceView)
850  {
851  shaderStages[(int)stage - 1].SetShaderResource(slot, shaderResourceView != null ? shaderResourceView.NativeShaderResourceView : null);
852  }
853 
854  /// <summary>
855  /// Sets an unordered access view to the shader pipeline.
856  /// </summary>
857  /// <param name="stage">The stage.</param>
858  /// <param name="slot">The slot.</param>
859  /// <param name="unorderedAccessView">The unordered access view.</param>
860  /// <exception cref="System.ArgumentException">Invalid stage.;stage</exception>
861  internal void SetUnorderedAccessView(ShaderStage stage, int slot, GraphicsResource unorderedAccessView)
862  {
863  if (stage != ShaderStage.Compute)
864  throw new ArgumentException("Invalid stage.", "stage");
865 
866  NativeDeviceContext.ComputeShader.SetUnorderedAccessView(slot, unorderedAccessView != null ? unorderedAccessView.NativeUnorderedAccessView : null);
867  }
868 
869  internal unsafe void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox)
870  {
871  if (resource == null) throw new ArgumentNullException("resource");
872  NativeDeviceContext.UpdateSubresource(*(SharpDX.DataBox*)Interop.Cast(ref databox), resource.NativeResource, subResourceIndex);
873  }
874 
875  internal unsafe void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
876  {
877  if (resource == null) throw new ArgumentNullException("resource");
878  NativeDeviceContext.UpdateSubresource(*(SharpDX.DataBox*)Interop.Cast(ref databox), resource.NativeResource, subResourceIndex, *(SharpDX.Direct3D11.ResourceRegion*)Interop.Cast(ref region));
879  }
880 
881  private void CommonSetRenderTargets(DepthStencilBuffer depthStencilBuffer, RenderTarget rtv)
882  {
883  currentRenderTargetView = rtv != null ? rtv.NativeRenderTargetView : null;
884  // Setup the viewport from the rendertarget view
885  if (rtv != null)
886  {
887  SetViewport(new Viewport(0, 0, rtv.Width, rtv.Height));
888  }
889  else if (depthStencilBuffer != null)
890  {
891  SetViewport(new Viewport(0, 0, depthStencilBuffer.Description.Width, depthStencilBuffer.Description.Height));
892  }
893  }
894 
895  private void CommonSetRenderTargets(DepthStencilBuffer depthStencilBuffer, RenderTarget[] renderTargets)
896  {
897  if (renderTargets.Length > currentRenderTargetViews.Length)
898  {
899  throw new ArgumentOutOfRangeException(string.Format("RenderTargets count is exceeding maximum range [{0}]", renderTargets.Length), "renderTargets");
900  }
901 
902  RenderTarget rtv = renderTargets.Length > 0 ? renderTargets[0] : null;
903 
904  for (int i = 0; i < renderTargets.Length; i++)
905  currentRenderTargetViews[i] = renderTargets[i] != null ? renderTargets[i].NativeRenderTargetView : null;
906  actualRenderTargetViewCount = renderTargets.Length;
907 
908  // Setup the viewport from the rendertarget view
909  if (rtv != null)
910  {
911  SetViewport(new Viewport(0, 0, rtv.Width, rtv.Height));
912  }
913  else if (depthStencilBuffer != null)
914  {
915  SetViewport(new Viewport(0, 0, depthStencilBuffer.Description.Width, depthStencilBuffer.Description.Height));
916  }
917  }
918 
919  private void InitializeStages()
920  {
921  inputAssembler = nativeDeviceContext.InputAssembler;
922  outputMerger = nativeDeviceContext.OutputMerger;
923  shaderStages[(int)ShaderStage.Vertex - 1] = nativeDeviceContext.VertexShader;
924  shaderStages[(int)ShaderStage.Hull - 1] = nativeDeviceContext.HullShader;
925  shaderStages[(int)ShaderStage.Domain - 1] = nativeDeviceContext.DomainShader;
926  shaderStages[(int)ShaderStage.Geometry - 1] = nativeDeviceContext.GeometryShader;
927  shaderStages[(int)ShaderStage.Pixel - 1] = nativeDeviceContext.PixelShader;
928  shaderStages[(int)ShaderStage.Compute - 1] = nativeDeviceContext.ComputeShader;
929  }
930 
931  private void InitializeFactories()
932  {
933  switch (Features.Profile)
934  {
935  case GraphicsProfile.Level_9_1:
936  case GraphicsProfile.Level_9_2:
937  case GraphicsProfile.Level_9_3:
938  currentViewports = new Viewport[1];
939  break;
940  default:
941  currentViewports = new Viewport[8];
942  break;
943  }
944  currentNativeViewports = new SharpDX.ViewportF[currentViewports.Length];
945  }
946 
947  /// <summary>
948  /// Initializes the specified device.
949  /// </summary>
950  /// <param name="graphicsProfiles">The graphics profiles.</param>
951  /// <param name="deviceCreationFlags">The device creation flags.</param>
952  /// <param name="windowHandle">The window handle.</param>
953  private void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle)
954  {
955  if (nativeDevice != null)
956  {
957  // Destroy previous device
958  ReleaseDevice();
959  }
960 
961  // Profiling is supported through pix markers
962  IsProfilingSupported = true;
963 
964  // Map GraphicsProfile to D3D11 FeatureLevel
965  SharpDX.Direct3D.FeatureLevel[] levels = graphicsProfiles.ToFeatureLevel();
966  creationFlags = (SharpDX.Direct3D11.DeviceCreationFlags)deviceCreationFlags;
967 
968  // Create Device D3D11 with feature Level based on profile
969  nativeDevice = new SharpDX.Direct3D11.Device(Adapter.NativeAdapter, creationFlags, levels);
970  nativeDeviceContext = nativeDevice.ImmediateContext;
971  if (IsDebugMode)
972  {
973  GraphicsResourceBase.SetDebugName(this, nativeDeviceContext, "ImmediateContext");
974  }
975 
976  InitializeStages();
977 
978  // Create the input layout manager
979  if (InputLayoutManager == null)
980  InputLayoutManager = new InputLayoutManager(this).DisposeBy(this);
981  }
982 
983  protected void DestroyPlatformDevice()
984  {
985  ReleaseDevice();
986  }
987 
988  private void ReleaseDevice()
989  {
990  // Display D3D11 ref counting info
991  ClearState();
992  NativeDevice.ImmediateContext.Flush();
993  NativeDevice.ImmediateContext.Dispose();
994 
995  if (IsDebugMode)
996  {
997  var deviceDebug = new DeviceDebug(NativeDevice);
998  deviceDebug.ReportLiveDeviceObjects(ReportingLevel.Detail);
999  }
1000 
1001  currentInputLayout = null;
1002  currentEffectInputSignature = null;
1003  currentRenderTargetView = null;
1004  currentVertexArrayLayout = null;
1005  nativeDevice.Dispose();
1006  }
1007 
1008  internal void OnDestroyed()
1009  {
1010  // Clear input layouts cache
1011  InputLayoutManager.OnDestroyed();
1012  }
1013 
1014  /// <summary>
1015  /// Prepares a draw call. This method is called before each Draw() method to setup the correct Primitive, InputLayout and VertexBuffers.
1016  /// </summary>
1017  /// <param name="primitiveType">Type of the primitive.</param>
1018  /// <exception cref="System.InvalidOperationException">Cannot GraphicsDevice.Draw*() without an effect being previously applied with Effect.Apply() method</exception>
1019  private void PrepareDraw(PrimitiveType primitiveType)
1020  {
1021  if (CurrentEffect == null)
1022  {
1023  throw new InvalidOperationException("Cannot GraphicsDevice.Draw*() without an effect being previously applied with Effect.Apply() method");
1024  }
1025 
1026  // Setup the primitive type
1027  PrimitiveType = primitiveType;
1028 
1029  // If the vertex array object is null, simply set the InputLayout to null
1030  if (newVertexArrayObject == null)
1031  {
1032  currentVertexArrayLayout = null;
1033  currentEffectInputSignature = null;
1034  currentInputLayout = null;
1035  }
1036  else
1037  {
1038  VertexArrayLayout newVertexArrayLayout = newVertexArrayObject.Layout;
1039  EffectInputSignature newEffectInputSignature = CurrentEffect.InputSignature;
1040 
1041  // If the input layout of the effect or the vertex buffer has changed, get the associated new input layout
1042  if (!ReferenceEquals(newVertexArrayLayout, currentVertexArrayLayout) || !ReferenceEquals(newEffectInputSignature, currentEffectInputSignature))
1043  {
1044  currentVertexArrayLayout = newVertexArrayLayout;
1045  currentEffectInputSignature = newEffectInputSignature;
1046  currentInputLayout = newVertexArrayObject.InputLayout;
1047 
1048  // Slow path if the current VertexArrayObject is not optimized for the particular input
1049  if (currentInputLayout == null || !ReferenceEquals(newEffectInputSignature, newVertexArrayObject.EffectInputSignature))
1050  {
1051  currentInputLayout = InputLayoutManager.GetInputLayout(newEffectInputSignature, currentVertexArrayLayout);
1052  }
1053  }
1054 
1055  // Apply the VertexArrayObject
1056  newVertexArrayObject.Apply(inputAssembler);
1057  }
1058 
1059  // Setup the input layout
1060  inputAssembler.InputLayout = currentInputLayout;
1061  }
1062  }
1063 }
1064 #endif
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ DXGI_FORMAT _In_ DWORD flags
Definition: DirectXTexP.h:170
GraphicsDeviceStatus
Describes the current status of a GraphicsDevice.
SiliconStudio.Paradox.Graphics.Buffer Buffer
Definition: BasicEffect.cs:15
System.Windows.Shapes.Rectangle Rectangle
Definition: ColorPicker.cs:16
ShaderStage
Enum to specify shader stage.
Definition: ShaderStage.cs:12
SiliconStudio.Paradox.Graphics.PrimitiveType PrimitiveType
Creates a render target buffer.
MapMode
Describes how the cpu is accessing a GraphicsResource with the GraphicsDeviceContext.Map method.
Definition: MapMode.cs:8
GraphicsProfile
Identifies the set of supported devices for the demo based on device capabilities.
DepthStencilClearOptions
Specifies the buffer to use when calling Clear.