1 //--------------------------------------------------------------------------------------
2 // File: DXUTEnum.cpp
3 //
4 // Enumerates D3D adapters, devices, modes, etc.
5 //
6 // Copyright (c) Microsoft Corporation. All rights reserved.
7 //--------------------------------------------------------------------------------------
8 #include "dxstdafx.h"
9 #undef min // use __min instead
10 #undef max // use __max instead
11
12
13 //--------------------------------------------------------------------------------------
14 // Forward declarations
15 //--------------------------------------------------------------------------------------
16 static int __cdecl SortModesCallback( const void* arg1, const void* arg2 );
17 UINT DXUTStencilBits( D3DFORMAT fmt );
18 UINT DXUTDepthBits( D3DFORMAT fmt );
19 UINT DXUTAlphaChannelBits( D3DFORMAT fmt );
20 UINT DXUTColorChannelBits( D3DFORMAT fmt );
DXUTGetEnumeration()21 CD3DEnumeration* DXUTGetEnumeration()
22 {
23 // Using an accessor function gives control of the construction order
24 static CD3DEnumeration d3denum;
25 return &d3denum;
26 }
27
28
29 //--------------------------------------------------------------------------------------
CD3DEnumeration()30 CD3DEnumeration::CD3DEnumeration()
31 {
32 m_pD3D = NULL;
33 m_IsDeviceAcceptableFunc = NULL;
34 m_pIsDeviceAcceptableFuncUserContext = NULL;
35 m_bRequirePostPixelShaderBlending = true;
36
37 m_nMinWidth = 640;
38 m_nMinHeight = 480;
39 m_nMaxWidth = UINT_MAX;
40 m_nMaxHeight = UINT_MAX;
41
42 m_nRefreshMin = 0;
43 m_nRefreshMax = UINT_MAX;
44
45 m_nMultisampleQualityMax = 0xFFFF;
46
47 ResetPossibleDepthStencilFormats();
48 ResetPossibleMultisampleTypeList();
49 ResetPossiblePresentIntervalList();
50 SetPossibleVertexProcessingList( true, true, true, false );
51 }
52
53
54 //--------------------------------------------------------------------------------------
~CD3DEnumeration()55 CD3DEnumeration::~CD3DEnumeration()
56 {
57 ClearAdapterInfoList();
58 }
59
60
61
62 //--------------------------------------------------------------------------------------
63 // Enumerates available D3D adapters, devices, modes, etc.
64 //--------------------------------------------------------------------------------------
Enumerate(IDirect3D9 * pD3D,LPDXUTCALLBACKISDEVICEACCEPTABLE IsDeviceAcceptableFunc,void * pIsDeviceAcceptableFuncUserContext)65 HRESULT CD3DEnumeration::Enumerate( IDirect3D9* pD3D,
66 LPDXUTCALLBACKISDEVICEACCEPTABLE IsDeviceAcceptableFunc,
67 void* pIsDeviceAcceptableFuncUserContext )
68 {
69 if( pD3D == NULL )
70 {
71 pD3D = DXUTGetD3DObject();
72 if( pD3D == NULL )
73 return DXUTERR_NODIRECT3D;
74 }
75
76 m_pD3D = pD3D;
77 m_IsDeviceAcceptableFunc = IsDeviceAcceptableFunc;
78 m_pIsDeviceAcceptableFuncUserContext = pIsDeviceAcceptableFuncUserContext;
79
80 HRESULT hr;
81 ClearAdapterInfoList();
82 CGrowableArray<D3DFORMAT> adapterFormatList;
83
84 const D3DFORMAT allowedAdapterFormatArray[] =
85 {
86 D3DFMT_X8R8G8B8,
87 D3DFMT_X1R5G5B5,
88 D3DFMT_R5G6B5,
89 D3DFMT_A2R10G10B10
90 };
91 const UINT allowedAdapterFormatArrayCount = sizeof(allowedAdapterFormatArray) / sizeof(allowedAdapterFormatArray[0]);
92
93 UINT numAdapters = pD3D->GetAdapterCount();
94 for (UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++)
95 {
96 CD3DEnumAdapterInfo* pAdapterInfo = new CD3DEnumAdapterInfo;
97 if( pAdapterInfo == NULL )
98 return E_OUTOFMEMORY;
99
100 pAdapterInfo->AdapterOrdinal = adapterOrdinal;
101 pD3D->GetAdapterIdentifier(adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier);
102
103 // Get list of all display modes on this adapter.
104 // Also build a temporary list of all display adapter formats.
105 adapterFormatList.RemoveAll();
106
107 for( UINT iFormatList = 0; iFormatList < allowedAdapterFormatArrayCount; iFormatList++ )
108 {
109 D3DFORMAT allowedAdapterFormat = allowedAdapterFormatArray[iFormatList];
110 UINT numAdapterModes = pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat );
111 for (UINT mode = 0; mode < numAdapterModes; mode++)
112 {
113 D3DDISPLAYMODE displayMode;
114 pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode );
115
116 if( displayMode.Width < m_nMinWidth ||
117 displayMode.Height < m_nMinHeight ||
118 displayMode.Width > m_nMaxWidth ||
119 displayMode.Height > m_nMaxHeight ||
120 displayMode.RefreshRate < m_nRefreshMin ||
121 displayMode.RefreshRate > m_nRefreshMax )
122 {
123 continue;
124 }
125
126 pAdapterInfo->displayModeList.Add( displayMode );
127
128 if( !adapterFormatList.Contains(displayMode.Format) )
129 adapterFormatList.Add( displayMode.Format );
130 }
131
132 }
133
134 D3DDISPLAYMODE displayMode;
135 pD3D->GetAdapterDisplayMode( adapterOrdinal, &displayMode );
136 if( !adapterFormatList.Contains(displayMode.Format) )
137 adapterFormatList.Add( displayMode.Format );
138
139 // Sort displaymode list
140 ::qsort( pAdapterInfo->displayModeList.GetData(),
141 pAdapterInfo->displayModeList.GetSize(), sizeof( D3DDISPLAYMODE ),
142 SortModesCallback );
143
144 // Get info for each device on this adapter
145 if( FAILED( EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) )
146 {
147 delete pAdapterInfo;
148 continue;
149 }
150
151 // If at least one device on this adapter is available and compatible
152 // with the app, add the adapterInfo to the list
153 if( pAdapterInfo->deviceInfoList.GetSize() > 0 )
154 {
155 hr = m_AdapterInfoList.Add( pAdapterInfo );
156 if( FAILED(hr) )
157 return hr;
158 } else
159 delete pAdapterInfo;
160 }
161
162 bool bUniqueDesc = true;
163 CD3DEnumAdapterInfo* pAdapterInfo;
164 for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
165 {
166 CD3DEnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt(i);
167
168 for( int j=i+1; j<m_AdapterInfoList.GetSize(); j++ )
169 {
170 CD3DEnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt(j);
171 if( _stricmp( pAdapterInfo1->AdapterIdentifier.Description,
172 pAdapterInfo2->AdapterIdentifier.Description ) == 0 )
173 {
174 bUniqueDesc = false;
175 break;
176 }
177 }
178
179 if( !bUniqueDesc )
180 break;
181 }
182
183 for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
184 {
185 pAdapterInfo = m_AdapterInfoList.GetAt(i);
186
187 MultiByteToWideChar( CP_ACP, 0,
188 pAdapterInfo->AdapterIdentifier.Description, -1,
189 pAdapterInfo->szUniqueDescription, 100 );
190 pAdapterInfo->szUniqueDescription[100] = 0;
191
192 if( !bUniqueDesc )
193 {
194 WCHAR sz[100];
195 StringCchPrintf( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal );
196 StringCchCat( pAdapterInfo->szUniqueDescription, 256, sz );
197
198 }
199 }
200
201 return S_OK;
202 }
203
204
205
206 //--------------------------------------------------------------------------------------
207 // Enumerates D3D devices for a particular adapter.
208 //--------------------------------------------------------------------------------------
EnumerateDevices(CD3DEnumAdapterInfo * pAdapterInfo,CGrowableArray<D3DFORMAT> * pAdapterFormatList)209 HRESULT CD3DEnumeration::EnumerateDevices( CD3DEnumAdapterInfo* pAdapterInfo, CGrowableArray<D3DFORMAT>* pAdapterFormatList )
210 {
211 HRESULT hr;
212
213 const D3DDEVTYPE devTypeArray[] =
214 {
215 D3DDEVTYPE_HAL,
216 D3DDEVTYPE_SW,
217 D3DDEVTYPE_REF
218 };
219 const UINT devTypeArrayCount = sizeof(devTypeArray) / sizeof(devTypeArray[0]);
220
221 // Enumerate each Direct3D device type
222 for( UINT iDeviceType = 0; iDeviceType < devTypeArrayCount; iDeviceType++ )
223 {
224 CD3DEnumDeviceInfo* pDeviceInfo = new CD3DEnumDeviceInfo;
225 if( pDeviceInfo == NULL )
226 return E_OUTOFMEMORY;
227
228 // Fill struct w/ AdapterOrdinal and D3DDEVTYPE
229 pDeviceInfo->DeviceType = devTypeArray[iDeviceType];
230
231 // Store device caps
232 if( FAILED( hr = m_pD3D->GetDeviceCaps( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType,
233 &pDeviceInfo->Caps ) ) )
234 {
235 delete pDeviceInfo;
236 continue;
237 }
238
239 // Create a temp device to verify that it is really possible to create a REF device
240 // [the developer DirectX redist has to be installed]
241 D3DDISPLAYMODE Mode;
242 m_pD3D->GetAdapterDisplayMode(0, &Mode);
243 D3DPRESENT_PARAMETERS pp;
244 ZeroMemory( &pp, sizeof(D3DPRESENT_PARAMETERS) );
245 pp.BackBufferWidth = 1;
246 pp.BackBufferHeight = 1;
247 pp.BackBufferFormat = Mode.Format;
248 pp.BackBufferCount = 1;
249 pp.SwapEffect = D3DSWAPEFFECT_COPY;
250 pp.Windowed = TRUE;
251 pp.hDeviceWindow = DXUTGetHWNDFocus();
252 IDirect3DDevice9 *pDevice = NULL;
253 if( FAILED( hr = m_pD3D->CreateDevice( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, DXUTGetHWNDFocus(),
254 D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &pDevice ) ) )
255 {
256 if( hr == D3DERR_NOTAVAILABLE )
257 {
258 delete pDeviceInfo;
259 continue;
260 }
261 }
262 SAFE_RELEASE( pDevice );
263
264 // Get info for each devicecombo on this device
265 if( FAILED( hr = EnumerateDeviceCombos( pAdapterInfo, pDeviceInfo, pAdapterFormatList ) ) )
266 {
267 delete pDeviceInfo;
268 continue;
269 }
270
271 // If at least one devicecombo for this device is found,
272 // add the deviceInfo to the list
273 if (pDeviceInfo->deviceSettingsComboList.GetSize() > 0 )
274 pAdapterInfo->deviceInfoList.Add( pDeviceInfo );
275 else
276 delete pDeviceInfo;
277 }
278
279 return S_OK;
280 }
281
282
283
284 //--------------------------------------------------------------------------------------
285 // Enumerates DeviceCombos for a particular device.
286 //--------------------------------------------------------------------------------------
EnumerateDeviceCombos(CD3DEnumAdapterInfo * pAdapterInfo,CD3DEnumDeviceInfo * pDeviceInfo,CGrowableArray<D3DFORMAT> * pAdapterFormatList)287 HRESULT CD3DEnumeration::EnumerateDeviceCombos( CD3DEnumAdapterInfo* pAdapterInfo, CD3DEnumDeviceInfo* pDeviceInfo, CGrowableArray<D3DFORMAT>* pAdapterFormatList )
288 {
289 const D3DFORMAT backBufferFormatArray[] =
290 {
291 D3DFMT_A8R8G8B8,
292 D3DFMT_X8R8G8B8,
293 D3DFMT_A2R10G10B10,
294 D3DFMT_R5G6B5,
295 D3DFMT_A1R5G5B5,
296 D3DFMT_X1R5G5B5
297 };
298 const UINT backBufferFormatArrayCount = sizeof(backBufferFormatArray) / sizeof(backBufferFormatArray[0]);
299
300 // See which adapter formats are supported by this device
301 for( int iFormat=0; iFormat<pAdapterFormatList->GetSize(); iFormat++ )
302 {
303 D3DFORMAT adapterFormat = pAdapterFormatList->GetAt(iFormat);
304
305 for( UINT iBackBufferFormat = 0; iBackBufferFormat < backBufferFormatArrayCount; iBackBufferFormat++ )
306 {
307 D3DFORMAT backBufferFormat = backBufferFormatArray[iBackBufferFormat];
308
309 for( int nWindowed = 0; nWindowed < 2; nWindowed++)
310 {
311 if( !nWindowed && pAdapterInfo->displayModeList.GetSize() == 0 )
312 continue;
313
314 if (FAILED( m_pD3D->CheckDeviceType( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType,
315 adapterFormat, backBufferFormat, nWindowed )))
316 {
317 continue;
318 }
319
320 if( m_bRequirePostPixelShaderBlending )
321 {
322 // If the backbuffer format doesn't support D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
323 // then alpha test, pixel fog, render-target blending, color write enable, and dithering.
324 // are not supported.
325 if( FAILED( m_pD3D->CheckDeviceFormat( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType,
326 adapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
327 D3DRTYPE_TEXTURE, backBufferFormat ) ) )
328 {
329 continue;
330 }
331 }
332
333 // If an application callback function has been provided, make sure this device
334 // is acceptable to the app.
335 if( m_IsDeviceAcceptableFunc != NULL )
336 {
337 if( !m_IsDeviceAcceptableFunc( &pDeviceInfo->Caps, adapterFormat, backBufferFormat, FALSE != nWindowed, m_pIsDeviceAcceptableFuncUserContext ) )
338 continue;
339 }
340
341 // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed
342 // DeviceCombo that is supported by the system and acceptable to the app. We still
343 // need to find one or more suitable depth/stencil buffer format,
344 // multisample type, and present interval.
345 CD3DEnumDeviceSettingsCombo* pDeviceCombo = new CD3DEnumDeviceSettingsCombo;
346 if( pDeviceCombo == NULL )
347 return E_OUTOFMEMORY;
348
349 pDeviceCombo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal;
350 pDeviceCombo->DeviceType = pDeviceInfo->DeviceType;
351 pDeviceCombo->AdapterFormat = adapterFormat;
352 pDeviceCombo->BackBufferFormat = backBufferFormat;
353 pDeviceCombo->Windowed = (nWindowed != 0);
354
355 BuildDepthStencilFormatList( pDeviceCombo );
356 BuildMultiSampleTypeList( pDeviceCombo );
357 if (pDeviceCombo->multiSampleTypeList.GetSize() == 0)
358 {
359 delete pDeviceCombo;
360 continue;
361 }
362 BuildDSMSConflictList( pDeviceCombo );
363 BuildPresentIntervalList(pDeviceInfo, pDeviceCombo );
364 pDeviceCombo->pAdapterInfo = pAdapterInfo;
365 pDeviceCombo->pDeviceInfo = pDeviceInfo;
366
367 pDeviceInfo->deviceSettingsComboList.Add( pDeviceCombo );
368
369 }
370 }
371 }
372
373 return S_OK;
374 }
375
376
377
378 //--------------------------------------------------------------------------------------
379 // Adds all depth/stencil formats that are compatible with the device
380 // and app to the given D3DDeviceCombo.
381 //--------------------------------------------------------------------------------------
BuildDepthStencilFormatList(CD3DEnumDeviceSettingsCombo * pDeviceCombo)382 void CD3DEnumeration::BuildDepthStencilFormatList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
383 {
384 D3DFORMAT depthStencilFmt;
385 for( int idsf = 0; idsf < m_DepthStecilPossibleList.GetSize(); idsf++ )
386 {
387 depthStencilFmt = m_DepthStecilPossibleList.GetAt(idsf);
388 if (SUCCEEDED(m_pD3D->CheckDeviceFormat(pDeviceCombo->AdapterOrdinal,
389 pDeviceCombo->DeviceType, pDeviceCombo->AdapterFormat,
390 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFmt)))
391 {
392 if (SUCCEEDED(m_pD3D->CheckDepthStencilMatch(pDeviceCombo->AdapterOrdinal,
393 pDeviceCombo->DeviceType, pDeviceCombo->AdapterFormat,
394 pDeviceCombo->BackBufferFormat, depthStencilFmt)))
395 {
396 pDeviceCombo->depthStencilFormatList.Add( depthStencilFmt );
397 }
398 }
399 }
400 }
401
402
403
404
405 //--------------------------------------------------------------------------------------
406 // Adds all multisample types that are compatible with the device and app to
407 // the given D3DDeviceCombo.
408 //--------------------------------------------------------------------------------------
BuildMultiSampleTypeList(CD3DEnumDeviceSettingsCombo * pDeviceCombo)409 void CD3DEnumeration::BuildMultiSampleTypeList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
410 {
411 D3DMULTISAMPLE_TYPE msType;
412 DWORD msQuality;
413 for( int imst = 0; imst < m_MultiSampleTypeList.GetSize(); imst++ )
414 {
415 msType = m_MultiSampleTypeList.GetAt(imst);
416 if( SUCCEEDED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal,
417 pDeviceCombo->DeviceType, pDeviceCombo->BackBufferFormat,
418 pDeviceCombo->Windowed, msType, &msQuality ) ) )
419 {
420 pDeviceCombo->multiSampleTypeList.Add( msType );
421 if( msQuality > m_nMultisampleQualityMax+1 )
422 msQuality = m_nMultisampleQualityMax+1;
423 pDeviceCombo->multiSampleQualityList.Add( msQuality );
424 }
425 }
426 }
427
428
429
430
431 //--------------------------------------------------------------------------------------
432 // Find any conflicts between the available depth/stencil formats and
433 // multisample types.
434 //--------------------------------------------------------------------------------------
BuildDSMSConflictList(CD3DEnumDeviceSettingsCombo * pDeviceCombo)435 void CD3DEnumeration::BuildDSMSConflictList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
436 {
437 CD3DEnumDSMSConflict DSMSConflict;
438
439 for( int iDS=0; iDS<pDeviceCombo->depthStencilFormatList.GetSize(); iDS++ )
440 {
441 D3DFORMAT dsFmt = pDeviceCombo->depthStencilFormatList.GetAt(iDS);
442
443 for( int iMS=0; iMS<pDeviceCombo->multiSampleTypeList.GetSize(); iMS++ )
444 {
445 D3DMULTISAMPLE_TYPE msType = pDeviceCombo->multiSampleTypeList.GetAt(iMS);
446
447 if( FAILED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, pDeviceCombo->DeviceType,
448 dsFmt, pDeviceCombo->Windowed, msType, NULL ) ) )
449 {
450 DSMSConflict.DSFormat = dsFmt;
451 DSMSConflict.MSType = msType;
452 pDeviceCombo->DSMSConflictList.Add( DSMSConflict );
453 }
454 }
455 }
456 }
457
458
459
460 //--------------------------------------------------------------------------------------
461 // Adds all present intervals that are compatible with the device and app
462 // to the given D3DDeviceCombo.
463 //--------------------------------------------------------------------------------------
BuildPresentIntervalList(CD3DEnumDeviceInfo * pDeviceInfo,CD3DEnumDeviceSettingsCombo * pDeviceCombo)464 void CD3DEnumeration::BuildPresentIntervalList( CD3DEnumDeviceInfo* pDeviceInfo,
465 CD3DEnumDeviceSettingsCombo* pDeviceCombo )
466 {
467 UINT pi;
468 for( int ipi = 0; ipi < m_PresentIntervalList.GetSize(); ipi++ )
469 {
470 pi = m_PresentIntervalList.GetAt(ipi);
471 if( pDeviceCombo->Windowed )
472 {
473 if( pi == D3DPRESENT_INTERVAL_TWO ||
474 pi == D3DPRESENT_INTERVAL_THREE ||
475 pi == D3DPRESENT_INTERVAL_FOUR )
476 {
477 // These intervals are not supported in windowed mode.
478 continue;
479 }
480 }
481 // Note that D3DPRESENT_INTERVAL_DEFAULT is zero, so you
482 // can't do a caps check for it -- it is always available.
483 if( pi == D3DPRESENT_INTERVAL_DEFAULT ||
484 (pDeviceInfo->Caps.PresentationIntervals & pi) )
485 {
486 pDeviceCombo->presentIntervalList.Add( pi );
487 }
488 }
489 }
490
491
492
493 //--------------------------------------------------------------------------------------
494 // Release all the allocated CD3DEnumAdapterInfo objects and empty the list
495 //--------------------------------------------------------------------------------------
ClearAdapterInfoList()496 void CD3DEnumeration::ClearAdapterInfoList()
497 {
498 CD3DEnumAdapterInfo* pAdapterInfo;
499 for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
500 {
501 pAdapterInfo = m_AdapterInfoList.GetAt(i);
502 delete pAdapterInfo;
503 }
504
505 m_AdapterInfoList.RemoveAll();
506 }
507
508
509
510 //--------------------------------------------------------------------------------------
511 // Call GetAdapterInfoList() after Enumerate() to get a STL vector of
512 // CD3DEnumAdapterInfo*
513 //--------------------------------------------------------------------------------------
GetAdapterInfoList()514 CGrowableArray<CD3DEnumAdapterInfo*>* CD3DEnumeration::GetAdapterInfoList()
515 {
516 return &m_AdapterInfoList;
517 }
518
519
520
521 //--------------------------------------------------------------------------------------
GetAdapterInfo(UINT AdapterOrdinal)522 CD3DEnumAdapterInfo* CD3DEnumeration::GetAdapterInfo( UINT AdapterOrdinal )
523 {
524 for( int iAdapter=0; iAdapter<m_AdapterInfoList.GetSize(); iAdapter++ )
525 {
526 CD3DEnumAdapterInfo* pAdapterInfo = m_AdapterInfoList.GetAt(iAdapter);
527 if( pAdapterInfo->AdapterOrdinal == AdapterOrdinal )
528 return pAdapterInfo;
529 }
530
531 return NULL;
532 }
533
534
535 //--------------------------------------------------------------------------------------
GetDeviceInfo(UINT AdapterOrdinal,D3DDEVTYPE DeviceType)536 CD3DEnumDeviceInfo* CD3DEnumeration::GetDeviceInfo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType )
537 {
538 CD3DEnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );
539 if( pAdapterInfo )
540 {
541 for( int iDeviceInfo=0; iDeviceInfo<pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ )
542 {
543 CD3DEnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt(iDeviceInfo);
544 if( pDeviceInfo->DeviceType == DeviceType )
545 return pDeviceInfo;
546 }
547 }
548
549 return NULL;
550 }
551
552
553 //--------------------------------------------------------------------------------------
554 //
555 //--------------------------------------------------------------------------------------
GetDeviceSettingsCombo(UINT AdapterOrdinal,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed)556 CD3DEnumDeviceSettingsCombo* CD3DEnumeration::GetDeviceSettingsCombo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed )
557 {
558 CD3DEnumDeviceInfo* pDeviceInfo = GetDeviceInfo( AdapterOrdinal, DeviceType );
559 if( pDeviceInfo )
560 {
561 for( int iDeviceCombo=0; iDeviceCombo<pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ )
562 {
563 CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt(iDeviceCombo);
564 if( pDeviceSettingsCombo->AdapterFormat == AdapterFormat &&
565 pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat &&
566 pDeviceSettingsCombo->Windowed == bWindowed )
567 return pDeviceSettingsCombo;
568 }
569 }
570
571 return NULL;
572 }
573
574
575 //--------------------------------------------------------------------------------------
576 // Returns the number of color channel bits in the specified D3DFORMAT
577 //--------------------------------------------------------------------------------------
DXUTColorChannelBits(D3DFORMAT fmt)578 UINT DXUTColorChannelBits( D3DFORMAT fmt )
579 {
580 switch( fmt )
581 {
582 case D3DFMT_R8G8B8:
583 return 8;
584 case D3DFMT_A8R8G8B8:
585 return 8;
586 case D3DFMT_X8R8G8B8:
587 return 8;
588 case D3DFMT_R5G6B5:
589 return 5;
590 case D3DFMT_X1R5G5B5:
591 return 5;
592 case D3DFMT_A1R5G5B5:
593 return 5;
594 case D3DFMT_A4R4G4B4:
595 return 4;
596 case D3DFMT_R3G3B2:
597 return 2;
598 case D3DFMT_A8R3G3B2:
599 return 2;
600 case D3DFMT_X4R4G4B4:
601 return 4;
602 case D3DFMT_A2B10G10R10:
603 return 10;
604 case D3DFMT_A8B8G8R8:
605 return 8;
606 case D3DFMT_A2R10G10B10:
607 return 10;
608 case D3DFMT_A16B16G16R16:
609 return 16;
610 default:
611 return 0;
612 }
613 }
614
615
616
617
618 //--------------------------------------------------------------------------------------
619 // Returns the number of alpha channel bits in the specified D3DFORMAT
620 //--------------------------------------------------------------------------------------
DXUTAlphaChannelBits(D3DFORMAT fmt)621 UINT DXUTAlphaChannelBits( D3DFORMAT fmt )
622 {
623 switch( fmt )
624 {
625 case D3DFMT_R8G8B8:
626 return 0;
627 case D3DFMT_A8R8G8B8:
628 return 8;
629 case D3DFMT_X8R8G8B8:
630 return 0;
631 case D3DFMT_R5G6B5:
632 return 0;
633 case D3DFMT_X1R5G5B5:
634 return 0;
635 case D3DFMT_A1R5G5B5:
636 return 1;
637 case D3DFMT_A4R4G4B4:
638 return 4;
639 case D3DFMT_R3G3B2:
640 return 0;
641 case D3DFMT_A8R3G3B2:
642 return 8;
643 case D3DFMT_X4R4G4B4:
644 return 0;
645 case D3DFMT_A2B10G10R10:
646 return 2;
647 case D3DFMT_A8B8G8R8:
648 return 8;
649 case D3DFMT_A2R10G10B10:
650 return 2;
651 case D3DFMT_A16B16G16R16:
652 return 16;
653 default:
654 return 0;
655 }
656 }
657
658
659
660
661 //--------------------------------------------------------------------------------------
662 // Returns the number of depth bits in the specified D3DFORMAT
663 //--------------------------------------------------------------------------------------
DXUTDepthBits(D3DFORMAT fmt)664 UINT DXUTDepthBits( D3DFORMAT fmt )
665 {
666 switch( fmt )
667 {
668 case D3DFMT_D32F_LOCKABLE:
669 case D3DFMT_D32:
670 return 32;
671
672 case D3DFMT_D24X8:
673 case D3DFMT_D24S8:
674 case D3DFMT_D24X4S4:
675 case D3DFMT_D24FS8:
676 return 24;
677
678 case D3DFMT_D16_LOCKABLE:
679 case D3DFMT_D16:
680 return 16;
681
682 case D3DFMT_D15S1:
683 return 15;
684
685 default:
686 return 0;
687 }
688 }
689
690
691
692
693 //--------------------------------------------------------------------------------------
694 // Returns the number of stencil bits in the specified D3DFORMAT
695 //--------------------------------------------------------------------------------------
DXUTStencilBits(D3DFORMAT fmt)696 UINT DXUTStencilBits( D3DFORMAT fmt )
697 {
698 switch( fmt )
699 {
700 case D3DFMT_D16_LOCKABLE:
701 case D3DFMT_D16:
702 case D3DFMT_D32F_LOCKABLE:
703 case D3DFMT_D32:
704 case D3DFMT_D24X8:
705 return 0;
706
707 case D3DFMT_D15S1:
708 return 1;
709
710 case D3DFMT_D24X4S4:
711 return 4;
712
713 case D3DFMT_D24S8:
714 case D3DFMT_D24FS8:
715 return 8;
716
717 default:
718 return 0;
719 }
720 }
721
722
723
724 //--------------------------------------------------------------------------------------
725 // Used to sort D3DDISPLAYMODEs
726 //--------------------------------------------------------------------------------------
SortModesCallback(const void * arg1,const void * arg2)727 static int __cdecl SortModesCallback( const void* arg1, const void* arg2 )
728 {
729 D3DDISPLAYMODE* pdm1 = (D3DDISPLAYMODE*)arg1;
730 D3DDISPLAYMODE* pdm2 = (D3DDISPLAYMODE*)arg2;
731
732 if (pdm1->Width > pdm2->Width)
733 return 1;
734 if (pdm1->Width < pdm2->Width)
735 return -1;
736 if (pdm1->Height > pdm2->Height)
737 return 1;
738 if (pdm1->Height < pdm2->Height)
739 return -1;
740 if (pdm1->Format > pdm2->Format)
741 return 1;
742 if (pdm1->Format < pdm2->Format)
743 return -1;
744 if (pdm1->RefreshRate > pdm2->RefreshRate)
745 return 1;
746 if (pdm1->RefreshRate < pdm2->RefreshRate)
747 return -1;
748 return 0;
749 }
750
751
752
753 //--------------------------------------------------------------------------------------
~CD3DEnumAdapterInfo(void)754 CD3DEnumAdapterInfo::~CD3DEnumAdapterInfo( void )
755 {
756 CD3DEnumDeviceInfo* pDeviceInfo;
757 for( int i=0; i<deviceInfoList.GetSize(); i++ )
758 {
759 pDeviceInfo = deviceInfoList.GetAt(i);
760 delete pDeviceInfo;
761 }
762 deviceInfoList.RemoveAll();
763 }
764
765
766
767
768 //--------------------------------------------------------------------------------------
~CD3DEnumDeviceInfo(void)769 CD3DEnumDeviceInfo::~CD3DEnumDeviceInfo( void )
770 {
771 CD3DEnumDeviceSettingsCombo* pDeviceCombo;
772 for( int i=0; i<deviceSettingsComboList.GetSize(); i++ )
773 {
774 pDeviceCombo = deviceSettingsComboList.GetAt(i);
775 delete pDeviceCombo;
776 }
777 deviceSettingsComboList.RemoveAll();
778 }
779
780
781 //--------------------------------------------------------------------------------------
ResetPossibleDepthStencilFormats()782 void CD3DEnumeration::ResetPossibleDepthStencilFormats()
783 {
784 m_DepthStecilPossibleList.RemoveAll();
785 m_DepthStecilPossibleList.Add( D3DFMT_D16 );
786 m_DepthStecilPossibleList.Add( D3DFMT_D15S1 );
787 m_DepthStecilPossibleList.Add( D3DFMT_D24X8 );
788 m_DepthStecilPossibleList.Add( D3DFMT_D24S8 );
789 m_DepthStecilPossibleList.Add( D3DFMT_D24X4S4 );
790 m_DepthStecilPossibleList.Add( D3DFMT_D32 );
791 }
792
793
794 //--------------------------------------------------------------------------------------
GetPossibleDepthStencilFormatList()795 CGrowableArray<D3DFORMAT>* CD3DEnumeration::GetPossibleDepthStencilFormatList()
796 {
797 return &m_DepthStecilPossibleList;
798 }
799
800
801 //--------------------------------------------------------------------------------------
GetPossibleMultisampleTypeList()802 CGrowableArray<D3DMULTISAMPLE_TYPE>* CD3DEnumeration::GetPossibleMultisampleTypeList()
803 {
804 return &m_MultiSampleTypeList;
805 }
806
807
808 //--------------------------------------------------------------------------------------
ResetPossibleMultisampleTypeList()809 void CD3DEnumeration::ResetPossibleMultisampleTypeList()
810 {
811 m_MultiSampleTypeList.RemoveAll();
812 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_NONE );
813 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_NONMASKABLE );
814 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_2_SAMPLES );
815 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_3_SAMPLES );
816 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_4_SAMPLES );
817 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_5_SAMPLES );
818 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_6_SAMPLES );
819 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_7_SAMPLES );
820 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_8_SAMPLES );
821 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_9_SAMPLES );
822 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_10_SAMPLES );
823 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_11_SAMPLES );
824 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_12_SAMPLES );
825 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_13_SAMPLES );
826 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_14_SAMPLES );
827 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_15_SAMPLES );
828 m_MultiSampleTypeList.Add( D3DMULTISAMPLE_16_SAMPLES );
829 }
830
831
832 //--------------------------------------------------------------------------------------
GetPossibleVertexProcessingList(bool * pbSoftwareVP,bool * pbHardwareVP,bool * pbPureHarewareVP,bool * pbMixedVP)833 void CD3DEnumeration::GetPossibleVertexProcessingList( bool* pbSoftwareVP, bool* pbHardwareVP, bool* pbPureHarewareVP, bool* pbMixedVP )
834 {
835 *pbSoftwareVP = m_bSoftwareVP;
836 *pbHardwareVP = m_bHardwareVP;
837 *pbPureHarewareVP = m_bPureHarewareVP;
838 *pbMixedVP = m_bMixedVP;
839 }
840
841
842 //--------------------------------------------------------------------------------------
SetPossibleVertexProcessingList(bool bSoftwareVP,bool bHardwareVP,bool bPureHarewareVP,bool bMixedVP)843 void CD3DEnumeration::SetPossibleVertexProcessingList( bool bSoftwareVP, bool bHardwareVP, bool bPureHarewareVP, bool bMixedVP )
844 {
845 m_bSoftwareVP = bSoftwareVP;
846 m_bHardwareVP = bHardwareVP;
847 m_bPureHarewareVP = bPureHarewareVP;
848 m_bMixedVP = bMixedVP;
849 }
850
851
852 //--------------------------------------------------------------------------------------
GetPossiblePresentIntervalList()853 CGrowableArray<UINT>* CD3DEnumeration::GetPossiblePresentIntervalList()
854 {
855 return &m_PresentIntervalList;
856 }
857
858
859 //--------------------------------------------------------------------------------------
ResetPossiblePresentIntervalList()860 void CD3DEnumeration::ResetPossiblePresentIntervalList()
861 {
862 m_PresentIntervalList.RemoveAll();
863 m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_IMMEDIATE );
864 m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_DEFAULT );
865 m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_ONE );
866 m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_TWO );
867 m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_THREE );
868 m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_FOUR );
869 }
870
871
872 //--------------------------------------------------------------------------------------
SetResolutionMinMax(UINT nMinWidth,UINT nMinHeight,UINT nMaxWidth,UINT nMaxHeight)873 void CD3DEnumeration::SetResolutionMinMax( UINT nMinWidth, UINT nMinHeight,
874 UINT nMaxWidth, UINT nMaxHeight )
875 {
876 m_nMinWidth = nMinWidth;
877 m_nMinHeight = nMinHeight;
878 m_nMaxWidth = nMaxWidth;
879 m_nMaxHeight = nMaxHeight;
880 }
881
882
883 //--------------------------------------------------------------------------------------
SetRefreshMinMax(UINT nMin,UINT nMax)884 void CD3DEnumeration::SetRefreshMinMax( UINT nMin, UINT nMax )
885 {
886 m_nRefreshMin = nMin;
887 m_nRefreshMax = nMax;
888 }
889
890
891 //--------------------------------------------------------------------------------------
SetMultisampleQualityMax(UINT nMax)892 void CD3DEnumeration::SetMultisampleQualityMax( UINT nMax )
893 {
894 if( nMax > 0xFFFF )
895 nMax = 0xFFFF;
896 m_nMultisampleQualityMax = nMax;
897 }
898
899