Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
GraphicsOutput.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 
5 // Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 // THE SOFTWARE.
24 
25 using System;
26 using System.Collections.Generic;
27 using SharpDX.Direct3D;
28 using SharpDX.Direct3D11;
29 using SharpDX.DXGI;
30 
31 using SiliconStudio.Core;
32 using SiliconStudio.Core.Mathematics;
33 
34 using ResultCode = SharpDX.DXGI.ResultCode;
35 
36 namespace SiliconStudio.Paradox.Graphics
37 {
38  /// <summary>
39  /// Provides methods to retrieve and manipulate an graphics output (a monitor), it is equivalent to <see cref="Output"/>.
40  /// </summary>
41  /// <msdn-id>bb174546</msdn-id>
42  /// <unmanaged>IDXGIOutput</unmanaged>
43  /// <unmanaged-short>IDXGIOutput</unmanaged-short>
44  public partial class GraphicsOutput
45  {
46  private readonly int outputIndex;
47  private readonly Output output;
48  private readonly OutputDescription outputDescription;
49 
50  /// <summary>
51  /// Initializes a new instance of <see cref="GraphicsOutput" />.
52  /// </summary>
53  /// <param name="adapter">The adapter.</param>
54  /// <param name="outputIndex">Index of the output.</param>
55  /// <exception cref="System.ArgumentNullException">output</exception>
56  /// <exception cref="ArgumentOutOfRangeException">output</exception>
57  internal GraphicsOutput(GraphicsAdapter adapter, int outputIndex)
58  {
59  if (adapter == null) throw new ArgumentNullException("adapter");
60 
61  this.outputIndex = outputIndex;
62  this.adapter = adapter;
63  this.output = adapter.NativeAdapter.GetOutput(outputIndex).DisposeBy(this);
64  outputDescription = output.Description;
65 
66  unsafe
67  {
68  var rectangle = outputDescription.DesktopBounds;
69  desktopBounds = *(Rectangle*)&rectangle;
70  }
71  }
72 
73  /// <summary>
74  /// Find the display mode that most closely matches the requested display mode.
75  /// </summary>
76  /// <param name="targetProfiles">The target profile, as available formats are different depending on the feature level..</param>
77  /// <param name="mode">The mode.</param>
78  /// <returns>Returns the closes display mode.</returns>
79  /// <unmanaged>HRESULT IDXGIOutput::FindClosestMatchingMode([In] const DXGI_MODE_DESC* pModeToMatch,[Out] DXGI_MODE_DESC* pClosestMatch,[In, Optional] IUnknown* pConcernedDevice)</unmanaged>
80  /// <remarks>Direct3D devices require UNORM formats. This method finds the closest matching available display mode to the mode specified in pModeToMatch. Similarly ranked fields (i.e. all specified, or all unspecified, etc) are resolved in the following order. ScanlineOrdering Scaling Format Resolution RefreshRate When determining the closest value for a particular field, previously matched fields are used to filter the display mode list choices, and other fields are ignored. For example, when matching Resolution, the display mode list will have already been filtered by a certain ScanlineOrdering, Scaling, and Format, while RefreshRate is ignored. This ordering doesn't define the absolute ordering for every usage scenario of FindClosestMatchingMode, because the application can choose some values initially, effectively changing the order that fields are chosen. Fields of the display mode are matched one at a time, generally in a specified order. If a field is unspecified, FindClosestMatchingMode gravitates toward the values for the desktop related to this output. If this output is not part of the desktop, then the default desktop output is used to find values. If an application uses a fully unspecified display mode, FindClosestMatchingMode will typically return a display mode that matches the desktop settings for this output. Unspecified fields are lower priority than specified fields and will be resolved later than specified fields.</remarks>
81  public DisplayMode FindClosestMatchingDisplayMode(GraphicsProfile[] targetProfiles, DisplayMode mode)
82  {
83  if (targetProfiles == null) throw new ArgumentNullException("targetProfiles");
84 
85  ModeDescription closestDescription;
86  SharpDX.Direct3D11.Device deviceTemp = null;
87  try
88  {
89  var features = new SharpDX.Direct3D.FeatureLevel[targetProfiles.Length];
90  for (int i = 0; i < targetProfiles.Length; i++)
91  {
92  features[i] = (FeatureLevel)targetProfiles[i];
93  }
94 
95  deviceTemp = new SharpDX.Direct3D11.Device(adapter.NativeAdapter, SharpDX.Direct3D11.DeviceCreationFlags.None, features);
96  }
97  catch (Exception) { }
98 
99  var description = new SharpDX.DXGI.ModeDescription()
100  {
101  Width = mode.Width,
102  Height = mode.Height,
103  RefreshRate = mode.RefreshRate.ToSharpDX(),
104  Format = (SharpDX.DXGI.Format)mode.Format,
105  Scaling = DisplayModeScaling.Unspecified,
106  ScanlineOrdering = DisplayModeScanlineOrder.Unspecified
107  };
108  using (var device = deviceTemp)
109  output.GetClosestMatchingMode(device, description, out closestDescription);
110 
111  return DisplayMode.FromDescription(closestDescription);
112  }
113 
114  /// <summary>
115  /// Retrieves the handle of the monitor associated with this <see cref="GraphicsOutput"/>.
116  /// </summary>
117  /// <msdn-id>bb173068</msdn-id>
118  /// <unmanaged>HMONITOR Monitor</unmanaged>
119  /// <unmanaged-short>HMONITOR Monitor</unmanaged-short>
120  public IntPtr MonitorHandle { get { return outputDescription.MonitorHandle; } }
121 
122  /// <summary>
123  /// Gets the native output.
124  /// </summary>
125  /// <value>The native output.</value>
126  internal Output NativeOutput
127  {
128  get
129  {
130  return output;
131  }
132  }
133 
134  /// <summary>
135  /// Enumerates all available display modes for this output and stores them in <see cref="SupportedDisplayModes"/>.
136  /// </summary>
137  private void InitializeSupportedDisplayModes()
138  {
139  var modesAvailable = new List<DisplayMode>();
140  var modesMap = new Dictionary<string, DisplayMode>();
141 
142 #if DIRECTX11_1
143  var output1 = output.QueryInterface<Output1>();
144 #endif
145 
146  try
147  {
148  const DisplayModeEnumerationFlags displayModeEnumerationFlags = DisplayModeEnumerationFlags.Interlaced | DisplayModeEnumerationFlags.Scaling;
149 
150  foreach (var format in Enum.GetValues(typeof(SharpDX.DXGI.Format)))
151  {
152  var dxgiFormat = (Format)format;
153 #if DIRECTX11_1
154  var modes = output1.GetDisplayModeList1(dxgiFormat, displayModeEnumerationFlags);
155 #else
156  var modes = output.GetDisplayModeList(dxgiFormat, displayModeEnumerationFlags);
157 #endif
158 
159  foreach (var mode in modes)
160  {
161  if (mode.Scaling == DisplayModeScaling.Unspecified)
162  {
163  var key = format + ";" + mode.Width + ";" + mode.Height + ";" + mode.RefreshRate.Numerator + ";" + mode.RefreshRate.Denominator;
164 
165  DisplayMode oldMode;
166  if (!modesMap.TryGetValue(key, out oldMode))
167  {
168  var displayMode = DisplayMode.FromDescription(mode);
169 
170  modesMap.Add(key, displayMode);
171  modesAvailable.Add(displayMode);
172  }
173  }
174  }
175  }
176  }
177  catch (SharpDX.SharpDXException dxgiException)
178  {
179  if (dxgiException.ResultCode != ResultCode.NotCurrentlyAvailable)
180  throw;
181  }
182 
183 #if DIRECTX11_1
184  output1.Dispose();
185 #endif
186  supportedDisplayModes = modesAvailable.ToArray();
187  }
188 
189  /// <summary>
190  /// Initializes <see cref="CurrentDisplayMode"/> with the most appropiate mode from <see cref="SupportedDisplayModes"/>.
191  /// </summary>
192  /// <remarks>It checks first for a mode with <see cref="Format.R8G8B8A8_UNorm"/>,
193  /// if it is not found - it checks for <see cref="Format.B8G8R8A8_UNorm"/>.</remarks>
194  private void InitializeCurrentDisplayMode()
195  {
196  currentDisplayMode = TryFindMatchingDisplayMode(Format.R8G8B8A8_UNorm)
197  ?? TryFindMatchingDisplayMode(Format.B8G8R8A8_UNorm);
198  }
199 
200  /// <summary>
201  /// Tries to find a display mode that has the same size as the current <see cref="OutputDescription"/> associated with this instance
202  /// of the specified format.
203  /// </summary>
204  /// <param name="format">The format to match with.</param>
205  /// <returns>A matched <see cref="DisplayMode"/> or null if nothing is found.</returns>
206  private DisplayMode TryFindMatchingDisplayMode(Format format)
207  {
208  var desktopBounds = outputDescription.DesktopBounds;
209 
210  foreach (var supportedDisplayMode in SupportedDisplayModes)
211  {
212  if (supportedDisplayMode.Width == desktopBounds.Width
213  && supportedDisplayMode.Height == desktopBounds.Height
214  && (Format)supportedDisplayMode.Format == format)
215  {
216  // Stupid DXGI, there is no way to get the DXGI.Format, nor the refresh rate.
217  return new DisplayMode((PixelFormat)format, desktopBounds.Width, desktopBounds.Height, supportedDisplayMode.RefreshRate);
218  }
219  }
220 
221  return null;
222  }
223  }
224 }
225 #endif
System.Windows.Shapes.Rectangle Rectangle
Definition: ColorPicker.cs:16
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
GraphicsProfile
Identifies the set of supported devices for the demo based on device capabilities.
PixelFormat
Defines various types of pixel formats.
Definition: PixelFormat.cs:32