OSDN Git Service

#32713 初コミット。SVNrev567時点での、ファイルはbranch/140707(ReBuild XGVersion)から移行したもの。
[dtxmaniaxg-verk/dtxmaniaxg-verk-git.git] / FDK17プロジェクト / コード / 01.フレームワーク / DeviceSettings / Direct3D9Settings.cs
1 /*
2 * Copyright (c) 2007-2009 SlimDX Group
3
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:
10
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13
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
20 * THE SOFTWARE.
21 */
22 using System;
23 using System.Collections.Generic;
24 using SlimDX.Direct3D9;
25
26 namespace SampleFramework
27 {
28         class Direct3D9Settings : ICloneable
29         {
30                 public int AdapterOrdinal
31                 {
32                         get;
33                         set;
34                 }
35
36                 public DeviceType DeviceType
37                 {
38                         get;
39                         set;
40                 }
41
42                 public Format AdapterFormat
43                 {
44                         get;
45                         set;
46                 }
47
48                 public CreateFlags CreationFlags
49                 {
50                         get;
51                         set;
52                 }
53
54                 public PresentParameters PresentParameters
55                 {
56                         get;
57                         private set;
58                 }
59
60                 public Direct3D9Settings()
61                 {
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;
75                 }
76
77                 public Direct3D9Settings Clone()
78                 {
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();
85
86                         return clone;
87                 }
88
89                 object ICloneable.Clone()
90                 {
91                         return Clone();
92                 }
93
94                 public static Direct3D9Settings BuildOptimalSettings(DeviceSettings settings)
95                 {
96                         DisplayMode desktopMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(0);
97                         Direct3D9Settings optimal = new Direct3D9Settings();
98
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;
106
107                         if(settings.Multithreaded)
108                                 optimal.CreationFlags |= CreateFlags.Multithreaded;
109
110                         if(optimal.PresentParameters.Windowed || ConversionMethods.GetColorBits(desktopMode.Format) >= 8)
111                                 optimal.AdapterFormat = desktopMode.Format;
112                         else
113                                 optimal.AdapterFormat = Format.X8R8G8B8;
114
115                         if(settings.BackBufferWidth == 0 || settings.BackBufferHeight == 0)
116                         {
117                                 if(optimal.PresentParameters.Windowed)
118                                 {
119                                         optimal.PresentParameters.BackBufferWidth = 640;
120                                         optimal.PresentParameters.BackBufferHeight = 480;
121                                 }
122                                 else
123                                 {
124                                         optimal.PresentParameters.BackBufferWidth = desktopMode.Width;
125                                         optimal.PresentParameters.BackBufferHeight = desktopMode.Height;
126                                 }
127                         }
128                         else
129                         {
130                                 optimal.PresentParameters.BackBufferWidth = settings.BackBufferWidth;
131                                 optimal.PresentParameters.BackBufferHeight = settings.BackBufferHeight;
132                         }
133
134                         if(settings.BackBufferFormat == Format.Unknown)
135                                 optimal.PresentParameters.BackBufferFormat = optimal.AdapterFormat;
136                         else
137                                 optimal.PresentParameters.BackBufferFormat = settings.BackBufferFormat;
138
139                         if(settings.DepthStencilFormat == Format.Unknown)
140                         {
141                                 if(ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat) >= 8)
142                                         optimal.PresentParameters.AutoDepthStencilFormat = Format.D32;
143                                 else
144                                         optimal.PresentParameters.AutoDepthStencilFormat = Format.D16;
145                         }
146                         else
147                                 optimal.PresentParameters.AutoDepthStencilFormat = settings.DepthStencilFormat;
148
149                         if(!settings.EnableVSync)
150                                 optimal.PresentParameters.PresentationInterval = PresentInterval.Immediate;
151
152                         return optimal;
153                 }
154
155                 public static float RankSettingsCombo(SettingsCombo9 combo, Direct3D9Settings optimal, DisplayMode desktopMode)
156                 {
157                         float ranking = 0.0f;
158
159                         if(combo.AdapterOrdinal == optimal.AdapterOrdinal)
160                                 ranking += 1000.0f;
161
162                         if(combo.DeviceType == optimal.DeviceType)
163                                 ranking += 100.0f;
164
165                         if(combo.DeviceType == DeviceType.Hardware)
166                                 ranking += 0.1f;
167
168                         if(combo.Windowed == optimal.PresentParameters.Windowed)
169                                 ranking += 10.0f;
170
171                         if(combo.AdapterFormat == optimal.AdapterFormat)
172                                 ranking += 1.0f;
173                         else
174                         {
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);
178                                 ranking += scale;
179                         }
180
181                         if(!combo.Windowed)
182                         {
183                                 bool match;
184                                 if(ConversionMethods.GetColorBits(desktopMode.Format) >= 8)
185                                         match = (combo.AdapterFormat == desktopMode.Format);
186                                 else
187                                         match = (combo.AdapterFormat == Format.X8R8G8B8);
188
189                                 if(match)
190                                         ranking += 0.1f;
191                         }
192
193                         if((optimal.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 &&
194                                 (optimal.CreationFlags & CreateFlags.MixedVertexProcessing) != 0)
195                         {
196                                 if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
197                                         ranking += 1.0f;
198                         }
199
200                         if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
201                                 ranking += 0.1f;
202
203                         foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
204                         {
205                                 if(displayMode.Format == combo.AdapterFormat &&
206                                         displayMode.Width == optimal.PresentParameters.BackBufferWidth &&
207                                         displayMode.Height == optimal.PresentParameters.BackBufferHeight)
208                                 {
209                                         ranking += 1.0f;
210                                         break;
211                                 }
212                         }
213
214                         if(combo.BackBufferFormat == optimal.PresentParameters.BackBufferFormat)
215                                 ranking += 1.0f;
216                         else
217                         {
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);
221                                 ranking += scale;
222                         }
223
224                         if(combo.BackBufferFormat == combo.AdapterFormat)
225                                 ranking += 0.1f;
226
227                         for(int i = 0; i < combo.MultisampleTypes.Count; i++)
228                         {
229                                 MultisampleType type = combo.MultisampleTypes[i];
230                                 int quality = combo.MultisampleQualities[i];
231
232                                 if(type == optimal.PresentParameters.Multisample && quality == optimal.PresentParameters.MultisampleQuality)
233                                 {
234                                         ranking += 1.0f;
235                                         break;
236                                 }
237                         }
238
239                         if(combo.DepthStencilFormats.Contains(optimal.PresentParameters.AutoDepthStencilFormat))
240                                 ranking += 1.0f;
241
242                         foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
243                         {
244                                 if(displayMode.Format == combo.AdapterFormat &&
245                                         displayMode.RefreshRate == optimal.PresentParameters.FullScreenRefreshRateInHertz)
246                                 {
247                                         ranking += 1.0f;
248                                         break;
249                                 }
250                         }
251
252                         if(combo.PresentIntervals.Contains(optimal.PresentParameters.PresentationInterval))
253                                 ranking += 1.0f;
254
255                         return ranking;
256                 }
257
258                 public static Direct3D9Settings BuildValidSettings(SettingsCombo9 combo, Direct3D9Settings input)
259                 {
260                         Direct3D9Settings settings = new Direct3D9Settings();
261
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;
269
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))
274                         {
275                                 settings.CreationFlags &= ~CreateFlags.HardwareVertexProcessing;
276                                 settings.CreationFlags &= ~CreateFlags.MixedVertexProcessing;
277                                 settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;
278                         }
279
280                         if((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) == 0 &&
281                                 (settings.CreationFlags & CreateFlags.MixedVertexProcessing) == 0 &&
282                                 (settings.CreationFlags & CreateFlags.SoftwareVertexProcessing) == 0)
283                         {
284                                 if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
285                                         settings.CreationFlags |= CreateFlags.HardwareVertexProcessing;
286                                 else
287                                         settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;
288                         }
289
290                         DisplayMode bestDisplayMode = FindValidResolution(combo, input);
291                         settings.PresentParameters.BackBufferWidth = bestDisplayMode.Width;
292                         settings.PresentParameters.BackBufferHeight = bestDisplayMode.Height;
293
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;
299
300                         if(input.PresentParameters.SwapEffect != SwapEffect.Discard)
301                         {
302                                 settings.PresentParameters.Multisample = MultisampleType.None;
303                                 settings.PresentParameters.MultisampleQuality = 0;
304                         }
305                         else
306                         {
307                                 MultisampleType bestType = MultisampleType.None;
308                                 int bestQuality = 0;
309
310                                 for(int i = 0; i < combo.MultisampleTypes.Count; i++)
311                                 {
312                                         MultisampleType type = combo.MultisampleTypes[i];
313                                         int quality = combo.MultisampleQualities[0];
314
315                                         if(Math.Abs(type - input.PresentParameters.Multisample) < Math.Abs(bestType -
316                                                 input.PresentParameters.Multisample))
317                                         {
318                                                 bestType = type;
319                                                 bestQuality = Math.Min(quality - 1, input.PresentParameters.MultisampleQuality);
320                                         }
321                                 }
322
323                                 settings.PresentParameters.Multisample = bestType;
324                                 settings.PresentParameters.MultisampleQuality = bestQuality;
325                         }
326
327                         List<int> rankings = new List<int>();
328                         int inputDepthBitDepth = ConversionMethods.GetDepthBits(input.PresentParameters.AutoDepthStencilFormat);
329                         int inputStencilBitDepth = ConversionMethods.GetStencilBits(input.PresentParameters.AutoDepthStencilFormat);
330
331                         foreach(Format format in combo.DepthStencilFormats)
332                         {
333                                 int currentBitDepth = ConversionMethods.GetDepthBits(format);
334                                 int currentStencilDepth = ConversionMethods.GetStencilBits(format);
335
336                                 int ranking = Math.Abs(currentBitDepth - inputDepthBitDepth);
337                                 ranking += Math.Abs(currentStencilDepth - inputStencilBitDepth);
338                                 rankings.Add(ranking);
339                         }
340
341                         int bestRanking = int.MaxValue;
342                         foreach(int ranking in rankings)
343                         {
344                                 if(ranking < bestRanking)
345                                         bestRanking = ranking;
346                         }
347                         int bestIndex = rankings.IndexOf(bestRanking);
348
349                         if(bestIndex >= 0)
350                         {
351                                 settings.PresentParameters.AutoDepthStencilFormat = combo.DepthStencilFormats[bestIndex];
352                                 settings.PresentParameters.EnableAutoDepthStencil = true;
353                         }
354                         else
355                         {
356                                 settings.PresentParameters.AutoDepthStencilFormat = Format.Unknown;
357                                 settings.PresentParameters.EnableAutoDepthStencil = false;
358                         }
359
360                         if(combo.Windowed)
361                                 settings.PresentParameters.FullScreenRefreshRateInHertz = 0;
362                         else
363                         {
364                                 int match = input.PresentParameters.FullScreenRefreshRateInHertz;
365                                 bestDisplayMode.RefreshRate = 0;
366                                 if(match != 0)
367                                 {
368                                         bestRanking = 100000;
369                                         foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
370                                         {
371                                                 if(displayMode.Format != combo.AdapterFormat ||
372                                                         displayMode.Width != bestDisplayMode.Width ||
373                                                         displayMode.Height != bestDisplayMode.Height)
374                                                         continue;
375
376                                                 int ranking = Math.Abs(displayMode.RefreshRate - match);
377
378                                                 if(ranking < bestRanking)
379                                                 {
380                                                         bestDisplayMode.RefreshRate = displayMode.RefreshRate;
381                                                         bestRanking = ranking;
382
383                                                         if(bestRanking == 0)
384                                                                 break;
385                                                 }
386                                         }
387                                 }
388
389                                 settings.PresentParameters.FullScreenRefreshRateInHertz = bestDisplayMode.RefreshRate;
390                         }
391
392                         if(combo.PresentIntervals.Contains(input.PresentParameters.PresentationInterval))
393                                 settings.PresentParameters.PresentationInterval = input.PresentParameters.PresentationInterval;
394                         else
395                                 settings.PresentParameters.PresentationInterval = PresentInterval.Default;
396
397                         return settings;
398                 }
399
400                 static DisplayMode FindValidResolution(SettingsCombo9 combo, Direct3D9Settings input)
401                 {
402                         DisplayMode bestMode = new DisplayMode();
403
404                         if(combo.Windowed)
405                         {
406                                 bestMode.Width = input.PresentParameters.BackBufferWidth;
407                                 bestMode.Height = input.PresentParameters.BackBufferHeight;
408                                 return bestMode;
409                         }
410
411                         int bestRanking = 100000;
412                         int ranking;
413                         foreach(DisplayMode mode in combo.AdapterInfo.DisplayModes)
414                         {
415                                 if(mode.Format != combo.AdapterFormat)
416                                         continue;
417
418                                 ranking = Math.Abs(mode.Width - input.PresentParameters.BackBufferWidth) +
419                                         Math.Abs(mode.Height - input.PresentParameters.BackBufferHeight);
420
421                                 if(ranking < bestRanking)
422                                 {
423                                         bestMode = mode;
424                                         bestRanking = ranking;
425
426                                         if(bestRanking == 0)
427                                                 break;
428                                 }
429                         }
430
431                         if(bestMode.Width == 0)
432                         {
433                                 bestMode.Width = input.PresentParameters.BackBufferWidth;
434                                 bestMode.Height = input.PresentParameters.BackBufferHeight;
435                         }
436
437                         return bestMode;
438                 }
439         }
440 }