2 * Copyright (c) 2007-2009 SlimDX Group
\r
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
\r
5 * of this software and associated documentation files (the "Software"), to deal
\r
6 * in the Software without restriction, including without limitation the rights
\r
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
8 * copies of the Software, and to permit persons to whom the Software is
\r
9 * furnished to do so, subject to the following conditions:
\r
11 * The above copyright notice and this permission notice shall be included in
\r
12 * all copies or substantial portions of the Software.
\r
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
23 using System.Collections.Generic;
\r
24 using SlimDX.Direct3D9;
\r
26 namespace SampleFramework
\r
28 class Direct3D9Settings : ICloneable
\r
30 public int AdapterOrdinal
\r
36 public DeviceType DeviceType
\r
42 public Format AdapterFormat
\r
48 public CreateFlags CreationFlags
\r
54 public PresentParameters PresentParameters
\r
60 public Direct3D9Settings()
\r
62 PresentParameters = new PresentParameters();
\r
63 DeviceType = DeviceType.Hardware;
\r
64 PresentParameters.Windowed = true;
\r
65 AdapterFormat = Format.Unknown;
\r
66 CreationFlags = CreateFlags.HardwareVertexProcessing;
\r
67 PresentParameters.BackBufferFormat = Format.Unknown;
\r
68 PresentParameters.BackBufferCount = 1;
\r
69 PresentParameters.Multisample = MultisampleType.None;
\r
70 PresentParameters.SwapEffect = SwapEffect.Discard;
\r
71 PresentParameters.EnableAutoDepthStencil = true;
\r
72 PresentParameters.AutoDepthStencilFormat = Format.Unknown;
\r
73 PresentParameters.PresentFlags = PresentFlags.DiscardDepthStencil;
\r
74 PresentParameters.PresentationInterval = PresentInterval.Default;
\r
77 public Direct3D9Settings Clone()
\r
79 Direct3D9Settings clone = new Direct3D9Settings();
\r
80 clone.AdapterFormat = AdapterFormat;
\r
81 clone.AdapterOrdinal = AdapterOrdinal;
\r
82 clone.CreationFlags = CreationFlags;
\r
83 clone.DeviceType = DeviceType;
\r
84 clone.PresentParameters = PresentParameters.Clone();
\r
89 object ICloneable.Clone()
\r
94 public static Direct3D9Settings BuildOptimalSettings(DeviceSettings settings)
\r
96 DisplayMode desktopMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(0);
\r
97 Direct3D9Settings optimal = new Direct3D9Settings();
\r
99 optimal.AdapterOrdinal = settings.AdapterOrdinal;
\r
100 optimal.DeviceType = settings.DeviceType;
\r
101 optimal.PresentParameters.Windowed = settings.Windowed;
\r
102 optimal.PresentParameters.BackBufferCount = settings.BackBufferCount;
\r
103 optimal.PresentParameters.Multisample = settings.MultisampleType;
\r
104 optimal.PresentParameters.MultisampleQuality = settings.MultisampleQuality;
\r
105 optimal.PresentParameters.FullScreenRefreshRateInHertz = settings.RefreshRate;
\r
107 if(settings.Multithreaded)
\r
108 optimal.CreationFlags |= CreateFlags.Multithreaded;
\r
110 if(optimal.PresentParameters.Windowed || ConversionMethods.GetColorBits(desktopMode.Format) >= 8)
\r
111 optimal.AdapterFormat = desktopMode.Format;
\r
113 optimal.AdapterFormat = Format.X8R8G8B8;
\r
115 if(settings.BackBufferWidth == 0 || settings.BackBufferHeight == 0)
\r
117 if(optimal.PresentParameters.Windowed)
\r
119 optimal.PresentParameters.BackBufferWidth = 640;
\r
120 optimal.PresentParameters.BackBufferHeight = 480;
\r
124 optimal.PresentParameters.BackBufferWidth = desktopMode.Width;
\r
125 optimal.PresentParameters.BackBufferHeight = desktopMode.Height;
\r
130 optimal.PresentParameters.BackBufferWidth = settings.BackBufferWidth;
\r
131 optimal.PresentParameters.BackBufferHeight = settings.BackBufferHeight;
\r
134 if(settings.BackBufferFormat == Format.Unknown)
\r
135 optimal.PresentParameters.BackBufferFormat = optimal.AdapterFormat;
\r
137 optimal.PresentParameters.BackBufferFormat = settings.BackBufferFormat;
\r
139 if(settings.DepthStencilFormat == Format.Unknown)
\r
141 if(ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat) >= 8)
\r
142 optimal.PresentParameters.AutoDepthStencilFormat = Format.D32;
\r
144 optimal.PresentParameters.AutoDepthStencilFormat = Format.D16;
\r
147 optimal.PresentParameters.AutoDepthStencilFormat = settings.DepthStencilFormat;
\r
149 if(!settings.EnableVSync)
\r
150 optimal.PresentParameters.PresentationInterval = PresentInterval.Immediate;
\r
155 public static float RankSettingsCombo(SettingsCombo9 combo, Direct3D9Settings optimal, DisplayMode desktopMode)
\r
157 float ranking = 0.0f;
\r
159 if(combo.AdapterOrdinal == optimal.AdapterOrdinal)
\r
160 ranking += 1000.0f;
\r
162 if(combo.DeviceType == optimal.DeviceType)
\r
165 if(combo.DeviceType == DeviceType.Hardware)
\r
168 if(combo.Windowed == optimal.PresentParameters.Windowed)
\r
171 if(combo.AdapterFormat == optimal.AdapterFormat)
\r
175 int bitDepthDelta = Math.Abs(ConversionMethods.GetColorBits(combo.AdapterFormat) -
\r
176 ConversionMethods.GetColorBits(optimal.AdapterFormat));
\r
177 float scale = Math.Max(0.9f - bitDepthDelta * 0.2f, 0.0f);
\r
181 if(!combo.Windowed)
\r
184 if(ConversionMethods.GetColorBits(desktopMode.Format) >= 8)
\r
185 match = (combo.AdapterFormat == desktopMode.Format);
\r
187 match = (combo.AdapterFormat == Format.X8R8G8B8);
\r
193 if((optimal.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 &&
\r
194 (optimal.CreationFlags & CreateFlags.MixedVertexProcessing) != 0)
\r
196 if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
\r
200 if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
\r
203 foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
\r
205 if(displayMode.Format == combo.AdapterFormat &&
\r
206 displayMode.Width == optimal.PresentParameters.BackBufferWidth &&
\r
207 displayMode.Height == optimal.PresentParameters.BackBufferHeight)
\r
214 if(combo.BackBufferFormat == optimal.PresentParameters.BackBufferFormat)
\r
218 int bitDepthDelta = Math.Abs(ConversionMethods.GetColorBits(combo.BackBufferFormat) -
\r
219 ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat));
\r
220 float scale = Math.Max(0.9f - bitDepthDelta * 0.2f, 0.0f);
\r
224 if(combo.BackBufferFormat == combo.AdapterFormat)
\r
227 for(int i = 0; i < combo.MultisampleTypes.Count; i++)
\r
229 MultisampleType type = combo.MultisampleTypes[i];
\r
230 int quality = combo.MultisampleQualities[i];
\r
232 if(type == optimal.PresentParameters.Multisample && quality == optimal.PresentParameters.MultisampleQuality)
\r
239 if(combo.DepthStencilFormats.Contains(optimal.PresentParameters.AutoDepthStencilFormat))
\r
242 foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
\r
244 if(displayMode.Format == combo.AdapterFormat &&
\r
245 displayMode.RefreshRate == optimal.PresentParameters.FullScreenRefreshRateInHertz)
\r
252 if(combo.PresentIntervals.Contains(optimal.PresentParameters.PresentationInterval))
\r
258 public static Direct3D9Settings BuildValidSettings(SettingsCombo9 combo, Direct3D9Settings input)
\r
260 Direct3D9Settings settings = new Direct3D9Settings();
\r
262 settings.AdapterOrdinal = combo.AdapterOrdinal;
\r
263 settings.DeviceType = combo.DeviceType;
\r
264 settings.PresentParameters.Windowed = combo.Windowed;
\r
265 settings.AdapterFormat = combo.AdapterFormat;
\r
266 settings.PresentParameters.BackBufferFormat = combo.BackBufferFormat;
\r
267 settings.PresentParameters.SwapEffect = input.PresentParameters.SwapEffect;
\r
268 settings.PresentParameters.PresentFlags = input.PresentParameters.PresentFlags | PresentFlags.DiscardDepthStencil;
\r
270 settings.CreationFlags = input.CreationFlags;
\r
271 if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) == 0 &&
\r
272 ((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 ||
\r
273 (settings.CreationFlags & CreateFlags.MixedVertexProcessing) != 0))
\r
275 settings.CreationFlags &= ~CreateFlags.HardwareVertexProcessing;
\r
276 settings.CreationFlags &= ~CreateFlags.MixedVertexProcessing;
\r
277 settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;
\r
280 if((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) == 0 &&
\r
281 (settings.CreationFlags & CreateFlags.MixedVertexProcessing) == 0 &&
\r
282 (settings.CreationFlags & CreateFlags.SoftwareVertexProcessing) == 0)
\r
284 if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
\r
285 settings.CreationFlags |= CreateFlags.HardwareVertexProcessing;
\r
287 settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;
\r
290 DisplayMode bestDisplayMode = FindValidResolution(combo, input);
\r
291 settings.PresentParameters.BackBufferWidth = bestDisplayMode.Width;
\r
292 settings.PresentParameters.BackBufferHeight = bestDisplayMode.Height;
\r
294 settings.PresentParameters.BackBufferCount = input.PresentParameters.BackBufferCount;
\r
295 if(settings.PresentParameters.BackBufferCount > 3)
\r
296 settings.PresentParameters.BackBufferCount = 3;
\r
297 if(settings.PresentParameters.BackBufferCount < 1)
\r
298 settings.PresentParameters.BackBufferCount = 1;
\r
300 if(input.PresentParameters.SwapEffect != SwapEffect.Discard)
\r
302 settings.PresentParameters.Multisample = MultisampleType.None;
\r
303 settings.PresentParameters.MultisampleQuality = 0;
\r
307 MultisampleType bestType = MultisampleType.None;
\r
308 int bestQuality = 0;
\r
310 for(int i = 0; i < combo.MultisampleTypes.Count; i++)
\r
312 MultisampleType type = combo.MultisampleTypes[i];
\r
313 int quality = combo.MultisampleQualities[0];
\r
315 if(Math.Abs(type - input.PresentParameters.Multisample) < Math.Abs(bestType -
\r
316 input.PresentParameters.Multisample))
\r
319 bestQuality = Math.Min(quality - 1, input.PresentParameters.MultisampleQuality);
\r
323 settings.PresentParameters.Multisample = bestType;
\r
324 settings.PresentParameters.MultisampleQuality = bestQuality;
\r
327 List<int> rankings = new List<int>();
\r
328 int inputDepthBitDepth = ConversionMethods.GetDepthBits(input.PresentParameters.AutoDepthStencilFormat);
\r
329 int inputStencilBitDepth = ConversionMethods.GetStencilBits(input.PresentParameters.AutoDepthStencilFormat);
\r
331 foreach(Format format in combo.DepthStencilFormats)
\r
333 int currentBitDepth = ConversionMethods.GetDepthBits(format);
\r
334 int currentStencilDepth = ConversionMethods.GetStencilBits(format);
\r
336 int ranking = Math.Abs(currentBitDepth - inputDepthBitDepth);
\r
337 ranking += Math.Abs(currentStencilDepth - inputStencilBitDepth);
\r
338 rankings.Add(ranking);
\r
341 int bestRanking = int.MaxValue;
\r
342 foreach(int ranking in rankings)
\r
344 if(ranking < bestRanking)
\r
345 bestRanking = ranking;
\r
347 int bestIndex = rankings.IndexOf(bestRanking);
\r
351 settings.PresentParameters.AutoDepthStencilFormat = combo.DepthStencilFormats[bestIndex];
\r
352 settings.PresentParameters.EnableAutoDepthStencil = true;
\r
356 settings.PresentParameters.AutoDepthStencilFormat = Format.Unknown;
\r
357 settings.PresentParameters.EnableAutoDepthStencil = false;
\r
361 settings.PresentParameters.FullScreenRefreshRateInHertz = 0;
\r
364 int match = input.PresentParameters.FullScreenRefreshRateInHertz;
\r
365 bestDisplayMode.RefreshRate = 0;
\r
368 bestRanking = 100000;
\r
369 foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
\r
371 if(displayMode.Format != combo.AdapterFormat ||
\r
372 displayMode.Width != bestDisplayMode.Width ||
\r
373 displayMode.Height != bestDisplayMode.Height)
\r
376 int ranking = Math.Abs(displayMode.RefreshRate - match);
\r
378 if(ranking < bestRanking)
\r
380 bestDisplayMode.RefreshRate = displayMode.RefreshRate;
\r
381 bestRanking = ranking;
\r
383 if(bestRanking == 0)
\r
389 settings.PresentParameters.FullScreenRefreshRateInHertz = bestDisplayMode.RefreshRate;
\r
392 if(combo.PresentIntervals.Contains(input.PresentParameters.PresentationInterval))
\r
393 settings.PresentParameters.PresentationInterval = input.PresentParameters.PresentationInterval;
\r
395 settings.PresentParameters.PresentationInterval = PresentInterval.Default;
\r
400 static DisplayMode FindValidResolution(SettingsCombo9 combo, Direct3D9Settings input)
\r
402 DisplayMode bestMode = new DisplayMode();
\r
406 bestMode.Width = input.PresentParameters.BackBufferWidth;
\r
407 bestMode.Height = input.PresentParameters.BackBufferHeight;
\r
411 int bestRanking = 100000;
\r
413 foreach(DisplayMode mode in combo.AdapterInfo.DisplayModes)
\r
415 if(mode.Format != combo.AdapterFormat)
\r
418 ranking = Math.Abs(mode.Width - input.PresentParameters.BackBufferWidth) +
\r
419 Math.Abs(mode.Height - input.PresentParameters.BackBufferHeight);
\r
421 if(ranking < bestRanking)
\r
424 bestRanking = ranking;
\r
426 if(bestRanking == 0)
\r
431 if(bestMode.Width == 0)
\r
433 bestMode.Width = input.PresentParameters.BackBufferWidth;
\r
434 bestMode.Height = input.PresentParameters.BackBufferHeight;
\r