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