Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
GraphicsDevice.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 using System;
4 using System.Collections.Generic;
5 using SiliconStudio.Core;
6 using SiliconStudio.Core.Mathematics;
7 using SiliconStudio.Paradox.Effects;
8 using SiliconStudio.Paradox.Graphics.Internals;
9 
10 namespace SiliconStudio.Paradox.Graphics
11 {
12  /// <summary>
13  /// Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See <see cref="The+GraphicsDevice+class"/> to learn more about the class.
14  /// </summary>
15  public partial class GraphicsDevice : ComponentBase
16  {
17  public static readonly int ThreadCount = 1; //AppConfig.GetConfiguration<Config>("RenderSystem").ThreadCount;
18 
19  internal readonly Dictionary<SamplerStateDescription, SamplerState> CachedSamplerStates = new Dictionary<SamplerStateDescription, SamplerState>();
20  internal readonly Dictionary<BlendStateDescription, BlendState> CachedBlendStates = new Dictionary<BlendStateDescription, BlendState>();
21  internal readonly Dictionary<RasterizerStateDescription, RasterizerState> CachedRasterizerStates = new Dictionary<RasterizerStateDescription, RasterizerState>();
22  internal readonly Dictionary<VertexArrayObject.Description, VertexArrayObject> CachedVertexArrayObjects = new Dictionary<VertexArrayObject.Description, VertexArrayObject>();
23 
24  /// <summary>
25  /// Gets the features supported by this graphics device.
26  /// </summary>
28 
29  internal HashSet<GraphicsResourceBase> Resources = new HashSet<GraphicsResourceBase>();
30 
31  internal readonly bool NeedWorkAroundForUpdateSubResource;
32  internal readonly ShaderStageSetup StageStatus = new ShaderStageSetup();
33  internal Effect CurrentEffect;
34  private readonly bool isDeferred;
35  private readonly ParameterCollection parameters = new ParameterCollection();
36 
37  private readonly Dictionary<object, IDisposable> sharedDataPerDevice;
38  private readonly Dictionary<object, IDisposable> sharedDataPerDeviceContext = new Dictionary<object, IDisposable>();
39  private VertexArrayObject newVertexArrayObject;
40  private GraphicsPresenter presenter;
41 
42  private PrimitiveQuad primitiveQuad;
43 
44  /// <summary>
45  /// Initializes a new instance of the <see cref="GraphicsDevice" /> class.
46  /// </summary>
47  /// <param name="adapter">The graphics adapter.</param>
48  /// <param name="profile">The graphics profile.</param>
49  /// <param name="deviceCreationFlags">The device creation flags.</param>
50  /// <param name="windowHandle">The window handle.</param>
51  protected GraphicsDevice(GraphicsAdapter adapter, GraphicsProfile[] profile, DeviceCreationFlags deviceCreationFlags, WindowHandle windowHandle)
52  {
53  RootDevice = this;
54 
55  // Setup IsDeferred to false for the main device
56  isDeferred = false;
57 
58  // Create shared data
59  sharedDataPerDevice = new Dictionary<object, IDisposable>();
60 
61  Recreate(adapter, profile, deviceCreationFlags, windowHandle);
62 
63  // Helpers
64  primitiveQuad = new PrimitiveQuad(this);
65  }
66 
67  public void Recreate(GraphicsAdapter adapter, GraphicsProfile[] profile, DeviceCreationFlags deviceCreationFlags, WindowHandle windowHandle)
68  {
69  if (adapter == null) throw new ArgumentNullException("adapter");
70  if (profile == null) throw new ArgumentNullException("profile");
71 
72  Adapter = adapter;
73  IsDebugMode = (deviceCreationFlags & DeviceCreationFlags.Debug) != 0;
74 
75  // Initialize this instance
76  InitializePlatformDevice(profile, deviceCreationFlags, windowHandle);
77 
78  // Create a new graphics device
79  Features = new GraphicsDeviceFeatures(this);
80 
81  InitializeFactories();
82 
83  if (SamplerStates == null)
84  {
85  SamplerStates = new SamplerStateFactory(this);
86  BlendStates = new BlendStateFactory(this);
87  RasterizerStates = new RasterizerStateFactory(this);
88  DepthStencilStates = new DepthStencilStateFactory(this);
89  }
90 
91  SetDefaultStates();
92  }
93 
94  protected override void Destroy()
95  {
96  DestroyPlatformDevice();
97 
98  // Notify listeners
99  if (Disposing != null)
100  Disposing(this, EventArgs.Empty);
101 
102  SamplerStates.Dispose();
103  BlendStates.Dispose();
104  RasterizerStates.Dispose();
105  if (DepthStencilBuffer != null)
106  DepthStencilBuffer.Dispose();
107  primitiveQuad.Dispose();
108 
109  base.Destroy();
110  }
111 
112  /// <summary>
113  /// Occurs while this component is disposing and before it is disposed.
114  /// </summary>
115  public event EventHandler<EventArgs> Disposing;
116 
117  /// <summary>
118  /// A delegate called to create shareable data. See remarks.
119  /// </summary>
120  /// <typeparam name="T">Type of the data to create.</typeparam>
121  /// <returns>A new instance of the data to share.</returns>
122  /// <remarks>
123  /// Because this method is being called from a lock region, this method should not be time consuming.
124  /// </remarks>
125  internal delegate T CreateSharedData<out T>() where T : class, IDisposable;
126 
127  /// <summary>
128  /// Gets the adapter this instance is attached to.
129  /// </summary>
130  public GraphicsAdapter Adapter { get; private set; }
131 
132  /// <summary>
133  /// Gets the back buffer sets by the current <see cref="Presenter" /> setup on this device.
134  /// </summary>
135  /// <value>
136  /// The back buffer. The returned value may be null if no <see cref="GraphicsPresenter" /> are setup on this device.
137  /// </value>
138  public RenderTarget BackBuffer
139  {
140  get
141  {
142  return Presenter != null ? Presenter.BackBuffer : null;
143  }
144  }
145 
146  /// <summary>
147  /// Gets the <see cref="BlendStates" /> factory.
148  /// </summary>
149  /// <value>
150  /// The <see cref="BlendStates" /> factory.
151  /// </value>
152  public BlendStateFactory BlendStates { get; private set; }
153 
154  /// <summary>
155  /// Gets the depth stencil buffer sets by the current <see cref="Presenter" /> setup on this device.
156  /// </summary>
157  /// <value>
158  /// The depth stencil buffer. The returned value may be null if no <see cref="GraphicsPresenter" /> are setup on this device or no depth buffer was allocated.
159  /// </value>
161  {
162  get
163  {
164  return Presenter != null ? Presenter.DepthStencilBuffer : null;
165  }
166  }
167 
168  /// <summary>
169  /// Gets the <see cref="DepthStencilStateFactory" /> factory.
170  /// </summary>
171  /// <value>
172  /// The <see cref="DepthStencilStateFactory" /> factory.
173  /// </value>
174  public DepthStencilStateFactory DepthStencilStates { get; private set; }
175 
176  /// <summary>
177  /// Gets a value indicating whether this instance is in debug mode.
178  /// </summary>
179  /// <value>
180  /// <c>true</c> if this instance is debug; otherwise, <c>false</c>.
181  /// </value>
182  public bool IsDebugMode { get; private set; }
183 
184  /// <summary>
185  /// Gets a value indicating whether this instance is a deferred graphics device context.
186  /// </summary>
187  /// <value>
188  /// <c>true</c> if this instance is deferred; otherwise, <c>false</c>.
189  /// </value>
190  public bool IsDeferred
191  {
192  get
193  {
194  return isDeferred;
195  }
196  }
197 
198  /// <summary>
199  /// Gets a value indicating whether this instance supports GPU markers and profiling.
200  /// </summary>
201  public bool IsProfilingSupported { get; private set; }
202 
203  /// <summary>
204  /// Gets the parameters attached to this particular device. This Parameters are used to override <see cref="Effect" /> parameters.
205  /// </summary>
206  /// <value>The parameters used to override all effects.</value>
207  public ParameterCollection Parameters
208  {
209  get
210  {
211  return parameters;
212  }
213  }
214 
215  /// <summary>
216  /// Gets or sets the current presenter use by the <see cref="Present" /> method.
217  /// </summary>
218  /// <value>The current presenter.</value>
219  public virtual GraphicsPresenter Presenter
220  {
221  get
222  {
223  return presenter;
224  }
225  set
226  {
227  presenter = value;
228  if (presenter != null)
229  {
230  Begin();
231  SetRenderTargets(presenter.DepthStencilBuffer, presenter.BackBuffer);
232  SetViewport(presenter.DefaultViewport);
233  End();
234  }
235  }
236  }
237 
238  /// <summary>
239  /// Gets the <see cref="RasterizerStates" /> factory.
240  /// </summary>
241  /// <value>
242  /// The <see cref="RasterizerStates" /> factory.
243  /// </value>
244  public RasterizerStateFactory RasterizerStates { get; private set; }
245 
246  /// <summary>
247  /// Gets the root device.
248  /// </summary>
249  /// <value>The root device.</value>
250  public GraphicsDevice RootDevice { get; private set; }
251 
252  /// <summary>
253  /// Gets the <see cref="SamplerStateFactory" /> factory.
254  /// </summary>
255  /// <value>
256  /// The <see cref="SamplerStateFactory" /> factory.
257  /// </value>
258  public SamplerStateFactory SamplerStates { get; private set; }
259 
260  /// <summary>
261  /// Gets or sets the index of the thread.
262  /// </summary>
263  /// <value>The index of the thread.</value>
264  public int ThreadIndex { get; internal set; }
265 
266  /// <summary>
267  /// Gets the shader profile.
268  /// </summary>
269  /// <value>The shader profile.</value>
270  internal GraphicsProfile? ShaderProfile { get; set; }
271 
272  /// <summary>
273  /// Initializes a new instance of the <see cref="GraphicsDevice" /> class.
274  /// </summary>
275  /// <param name="creationFlags">The creation flags.</param>
276  /// <param name="graphicsProfiles">The graphics profiles.</param>
277  /// <returns>
278  /// An instance of <see cref="GraphicsDevice" />
279  /// </returns>
280  public static GraphicsDevice New(DeviceCreationFlags creationFlags = DeviceCreationFlags.None, params GraphicsProfile[] graphicsProfiles)
281  {
282  return New(GraphicsAdapterFactory.Default, creationFlags, graphicsProfiles);
283  }
284 
285  /// <summary>
286  /// Initializes a new instance of the <see cref="GraphicsDevice" /> class.
287  /// </summary>
288  /// <param name="adapter">The adapter.</param>
289  /// <param name="creationFlags">The creation flags.</param>
290  /// <param name="graphicsProfiles">The graphics profiles.</param>
291  /// <returns>An instance of <see cref="GraphicsDevice" /></returns>
292  public static GraphicsDevice New(GraphicsAdapter adapter, DeviceCreationFlags creationFlags = DeviceCreationFlags.None, params GraphicsProfile[] graphicsProfiles)
293  {
294  return new GraphicsDevice(adapter ?? GraphicsAdapterFactory.Default, graphicsProfiles, creationFlags, null);
295  }
296 
297  /// <summary>
298  /// Initializes a new instance of the <see cref="GraphicsDevice" /> class.
299  /// </summary>
300  /// <param name="adapter">The adapter.</param>
301  /// <param name="creationFlags">The creation flags.</param>
302  /// <param name="windowHandle">The window handle.</param>
303  /// <param name="graphicsProfiles">The graphics profiles.</param>
304  /// <returns>An instance of <see cref="GraphicsDevice" /></returns>
305  public static GraphicsDevice New(GraphicsAdapter adapter, DeviceCreationFlags creationFlags = DeviceCreationFlags.None, WindowHandle windowHandle = null, params GraphicsProfile[] graphicsProfiles)
306  {
307  return new GraphicsDevice(adapter ?? GraphicsAdapterFactory.Default, graphicsProfiles, creationFlags, windowHandle);
308  }
309 
310  /// <summary>
311  /// Draws a full screen quad. An <see cref="Effect"/> must be applied before calling this method.
312  /// </summary>
313  public void DrawQuad()
314  {
315  primitiveQuad.Draw();
316  }
317 
318  /// <summary>
319  /// Draws a fullscreen texture using a <see cref="SamplerStateFactory.LinearClamp"/> sampler. See <see cref="Draw+a+texture"/> to learn how to use it.
320  /// </summary>
321  /// <param name="texture">The texture. Expecting an instance of <see cref="Texture2D"/>.</param>
322  public void DrawTexture(Texture texture)
323  {
324  DrawTexture(texture, null, Color4.White);
325  }
326 
327  /// <summary>
328  /// Draws a fullscreen texture using the specified sampler. See <see cref="Draw+a+texture"/> to learn how to use it.
329  /// </summary>
330  /// <param name="texture">The texture. Expecting an instance of <see cref="Texture2D"/>.</param>
331  /// <param name="sampler">The sampler.</param>
332  public void DrawTexture(Texture texture, SamplerState sampler)
333  {
334  DrawTexture(texture, sampler, Color4.White);
335  }
336 
337  /// <summary>
338  /// Draws a fullscreen texture using a <see cref="SamplerStateFactory.LinearClamp"/> sampler
339  /// and the texture color multiplied by a custom color. See <see cref="Draw+a+texture"/> to learn how to use it.
340  /// </summary>
341  /// <param name="texture">The texture. Expecting an instance of <see cref="Texture2D"/>.</param>
342  /// <param name="color">The color.</param>
343  public void DrawTexture(Texture texture, Color4 color)
344  {
345  DrawTexture(texture, null, color);
346  }
347 
348  /// <summary>
349  /// Draws a fullscreen texture using the specified sampler
350  /// and the texture color multiplied by a custom color. See <see cref="Draw+a+texture"/> to learn how to use it.
351  /// </summary>
352  /// <param name="texture">The texture. Expecting an instance of <see cref="Texture2D"/>.</param>
353  /// <param name="sampler">The sampler.</param>
354  /// <param name="color">The color.</param>
355  public void DrawTexture(Texture texture, SamplerState sampler, Color4 color)
356  {
357  primitiveQuad.Draw(texture, sampler, color);
358  }
359 
360  /// <summary>
361  /// Presents the current Presenter.
362  /// </summary>
363  public void Present()
364  {
365  if (Presenter != null)
366  {
367  Presenter.Present();
368  }
369  }
370 
371  /// <summary>
372  /// Sets a new depthStencilBuffer to this GraphicsDevice. If there is any RenderTarget already bound, it will be unbinded. See <see cref="Textures+and+render+targets"/> to learn how to use it.
373  /// </summary>
374  /// <param name="depthStencilBuffer">The depth stencil.</param>
375  public void SetRenderTarget(DepthStencilBuffer depthStencilBuffer)
376  {
377  SetRenderTarget(depthStencilBuffer, null);
378  }
379 
380  /// <summary>
381  /// Binds a single render target to the output-merger stage. See <see cref="Textures+and+render+targets"/> to learn how to use it.
382  /// </summary>
383  /// <param name="renderTargetView">A view of the render target to bind.</param>
384  public void SetRenderTarget(RenderTarget renderTargetView)
385  {
386  SetRenderTarget(null, renderTargetView);
387  }
388 
389  /// <summary>
390  /// <p>Bind one or more render targets atomically and the depth-stencil buffer to the output-merger stage. See <see cref="Textures+and+render+targets"/> to learn how to use it.</p>
391  /// </summary>
392  /// <param name="renderTargetViews">A set of render target views to bind.</param>
393  public void SetRenderTargets(params RenderTarget[] renderTargetViews)
394  {
395  SetRenderTargets(null, renderTargetViews);
396  }
397 
398  /// <summary>
399  /// Gets a shared data for this device context with a delegate to create the shared data if it is not present.
400  /// </summary>
401  /// <typeparam name="T">Type of the shared data to get/create.</typeparam>
402  /// <param name="type">Type of the data to share.</param>
403  /// <param name="key">The key of the shared data.</param>
404  /// <param name="sharedDataCreator">The shared data creator.</param>
405  /// <returns>
406  /// An instance of the shared data. The shared data will be disposed by this <see cref="GraphicsDevice" /> instance.
407  /// </returns>
408  internal T GetOrCreateSharedData<T>(GraphicsDeviceSharedDataType type, object key, CreateSharedData<T> sharedDataCreator) where T : class, IDisposable
409  {
410  Dictionary<object, IDisposable> dictionary = (type == GraphicsDeviceSharedDataType.PerDevice) ? sharedDataPerDevice : sharedDataPerDeviceContext;
411 
412  lock (dictionary)
413  {
414  IDisposable localValue;
415  if (!dictionary.TryGetValue(key, out localValue))
416  {
417  localValue = sharedDataCreator();
418  if (localValue == null)
419  {
420  return null;
421  }
422 
423  localValue = localValue.DisposeBy(this);
424  dictionary.Add(key, localValue);
425  }
426  return (T)localValue;
427  }
428  }
429  }
430 }
EventHandler< EventArgs > Disposing
Occurs while this component is disposing and before it is disposed.
static GraphicsAdapter Default
Gets the default adapter. This property can be null.
Primitive quad use to draw an effect on a quad (fullscreen by default). This is directly accessible f...
void Present()
Presents the current Presenter.
void SetRenderTarget(DepthStencilBuffer depthStencilBuffer)
Sets a new depthStencilBuffer to this GraphicsDevice. If there is any RenderTarget already bound...
void Recreate(GraphicsAdapter adapter, GraphicsProfile[] profile, DeviceCreationFlags deviceCreationFlags, WindowHandle windowHandle)
void DrawTexture(Texture texture, SamplerState sampler, Color4 color)
Draws a fullscreen texture using the specified sampler and the texture color multiplied by a custom c...
A platform specific window handle.
void DrawQuad()
Draws a full screen quad. An Effect must be applied before calling this method.
static readonly Color4 White
The White color (1, 1, 1, 1).
Definition: Color4.cs:54
Base class for a framework component.
static GraphicsDevice New(GraphicsAdapter adapter, DeviceCreationFlags creationFlags=DeviceCreationFlags.None, params GraphicsProfile[] graphicsProfiles)
Initializes a new instance of the GraphicsDevice class.
Represents a color in the form of rgba.
Definition: Color4.cs:42
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
This class is a frontend to SwapChain and SwapChain1.
void DrawTexture(Texture texture, Color4 color)
Draws a fullscreen texture using a SamplerStateFactory.LinearClamp sampler and the texture color mult...
void SetRenderTarget(RenderTarget renderTargetView)
Binds a single render target to the output-merger stage. See Textures+and+render+targets to learn how...
GraphicsDevice(GraphicsAdapter adapter, GraphicsProfile[] profile, DeviceCreationFlags deviceCreationFlags, WindowHandle windowHandle)
Initializes a new instance of the GraphicsDevice class.
static GraphicsDevice New(GraphicsAdapter adapter, DeviceCreationFlags creationFlags=DeviceCreationFlags.None, WindowHandle windowHandle=null, params GraphicsProfile[] graphicsProfiles)
Initializes a new instance of the GraphicsDevice class.
This class represents a graphics adapter.
static GraphicsDevice New(DeviceCreationFlags creationFlags=DeviceCreationFlags.None, params GraphicsProfile[] graphicsProfiles)
Initializes a new instance of the GraphicsDevice class.
GraphicsDeviceFeatures Features
Gets the features supported by this graphics device.
void DrawTexture(Texture texture)
Draws a fullscreen texture using a SamplerStateFactory.LinearClamp sampler. See Draw+a+texture to lea...
void DrawTexture(Texture texture, SamplerState sampler)
Draws a fullscreen texture using the specified sampler. See Draw+a+texture to learn how to use it...
void SetRenderTargets(params RenderTarget[] renderTargetViews)
GraphicsProfile
Identifies the set of supported devices for the demo based on device capabilities.
override void Destroy()
Disposes of object resources.
A container to handle a hierarchical collection of effect variables.
Base class for texture resources.
Definition: Texture.cs:38