Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Demos / DX11ClothDemo / DXUT / Core / DXUTDevice11.cpp
1 //--------------------------------------------------------------------------------------\r
2 // File: DXUTDevice11.cpp\r
3 //\r
4 // Enumerates D3D adapters, devices, modes, etc.\r
5 //\r
6 // Copyright (c) Microsoft Corporation. All rights reserved.\r
7 //--------------------------------------------------------------------------------------\r
8 #include "DXUT.h"\r
9 #undef min // use __min instead\r
10 #undef max // use __max instead\r
11 \r
12 //--------------------------------------------------------------------------------------\r
13 // Forward declarations\r
14 //--------------------------------------------------------------------------------------\r
15 extern void DXUTGetCallbackD3D11DeviceAcceptable( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE* ppCallbackIsDeviceAcceptable, void** ppUserContext );\r
16 \r
17 static int __cdecl SortModesCallback( const void* arg1, const void* arg2 );\r
18 \r
19 CD3D11Enumeration*  g_pDXUTD3D11Enumeration = NULL;\r
20 \r
21 \r
22 \r
23 \r
24 HRESULT WINAPI DXUTCreateD3D11Enumeration()\r
25 {\r
26     if( g_pDXUTD3D11Enumeration == NULL )\r
27     {\r
28         g_pDXUTD3D11Enumeration = new CD3D11Enumeration();\r
29         if( NULL == g_pDXUTD3D11Enumeration )\r
30             return E_OUTOFMEMORY;\r
31     }\r
32     return S_OK;\r
33 }\r
34 \r
35 void WINAPI DXUTDestroyD3D11Enumeration()\r
36 {\r
37     SAFE_DELETE( g_pDXUTD3D11Enumeration );\r
38 }\r
39 \r
40 class DXUTMemoryHelperD3D11Enum\r
41 {\r
42 public:\r
43 DXUTMemoryHelperD3D11Enum()\r
44 {\r
45     DXUTCreateD3D11Enumeration();\r
46 }\r
47 ~DXUTMemoryHelperD3D11Enum()\r
48 {\r
49     DXUTDestroyD3D11Enumeration();\r
50 }\r
51 };\r
52 \r
53 \r
54 //--------------------------------------------------------------------------------------\r
55 CD3D11Enumeration* WINAPI DXUTGetD3D11Enumeration( bool bForceEnumerate, bool bEnumerateAllAdapterFormats, D3D_FEATURE_LEVEL forceFL )\r
56 {\r
57     // Using an static class with accessor function to allow control of the construction order\r
58     static DXUTMemoryHelperD3D11Enum d3d11enumMemory;\r
59     if( g_pDXUTD3D11Enumeration && ( !g_pDXUTD3D11Enumeration->HasEnumerated() || bForceEnumerate ) )\r
60     {\r
61         g_pDXUTD3D11Enumeration->SetEnumerateAllAdapterFormats( bEnumerateAllAdapterFormats );\r
62         LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE pCallbackIsDeviceAcceptable;\r
63         void* pUserContext;\r
64         DXUTGetCallbackD3D11DeviceAcceptable( &pCallbackIsDeviceAcceptable, &pUserContext );\r
65         g_pDXUTD3D11Enumeration->SetForceFeatureLevel(forceFL);\r
66 \r
67         g_pDXUTD3D11Enumeration->Enumerate( pCallbackIsDeviceAcceptable, pUserContext );\r
68     }\r
69 \r
70     return g_pDXUTD3D11Enumeration;\r
71 }\r
72 \r
73 \r
74 //--------------------------------------------------------------------------------------\r
75 CD3D11Enumeration::CD3D11Enumeration()\r
76 {\r
77     m_bHasEnumerated = false;\r
78     m_IsD3D11DeviceAcceptableFunc = NULL;\r
79     m_pIsD3D11DeviceAcceptableFuncUserContext = NULL;\r
80 \r
81     m_nMinWidth = 640;\r
82     m_nMinHeight = 480;\r
83     m_nMaxWidth = UINT_MAX;\r
84     m_nMaxHeight = UINT_MAX;\r
85     m_bEnumerateAllAdapterFormats = false;\r
86 \r
87     m_nRefreshMin = 0;\r
88     m_nRefreshMax = UINT_MAX;\r
89 \r
90     ResetPossibleDepthStencilFormats();\r
91 }\r
92 \r
93 \r
94 //--------------------------------------------------------------------------------------\r
95 CD3D11Enumeration::~CD3D11Enumeration()\r
96 {\r
97     ClearAdapterInfoList();\r
98 }\r
99 \r
100 \r
101 //--------------------------------------------------------------------------------------\r
102 // Enumerate for each adapter all of the supported display modes, \r
103 // device types, adapter formats, back buffer formats, window/full screen support, \r
104 // depth stencil formats, multisampling types/qualities, and presentations intervals.\r
105 //\r
106 // For each combination of device type (HAL/REF), adapter format, back buffer format, and\r
107 // IsWindowed it will call the app's ConfirmDevice callback.  This allows the app\r
108 // to reject or allow that combination based on its caps/etc.  It also allows the \r
109 // app to change the BehaviorFlags.  The BehaviorFlags defaults non-pure HWVP \r
110 // if supported otherwise it will default to SWVP, however the app can change this \r
111 // through the ConfirmDevice callback.\r
112 //--------------------------------------------------------------------------------------\r
113 HRESULT CD3D11Enumeration::Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc,\r
114                                       void* pIsD3D11DeviceAcceptableFuncUserContext )\r
115 {\r
116     CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D11 Enumeration" );\r
117     HRESULT hr;\r
118     IDXGIFactory1* pFactory = DXUTGetDXGIFactory();\r
119     if( pFactory == NULL )\r
120         return E_FAIL;\r
121 \r
122     m_bHasEnumerated = true;\r
123     m_IsD3D11DeviceAcceptableFunc = IsD3D11DeviceAcceptableFunc;\r
124     m_pIsD3D11DeviceAcceptableFuncUserContext = pIsD3D11DeviceAcceptableFuncUserContext;\r
125 \r
126     ClearAdapterInfoList();\r
127 \r
128     for( int index = 0; ; ++index )\r
129     {\r
130         IDXGIAdapter* pAdapter = NULL;\r
131         hr = pFactory->EnumAdapters( index, &pAdapter );\r
132         if( FAILED( hr ) ) // DXGIERR_NOT_FOUND is expected when the end of the list is hit\r
133             break;\r
134 \r
135         CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo;\r
136         if( !pAdapterInfo )\r
137         {\r
138             SAFE_RELEASE( pAdapter );\r
139             return E_OUTOFMEMORY;\r
140         }\r
141         ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) );\r
142         pAdapterInfo->AdapterOrdinal = index;\r
143         pAdapter->GetDesc( &pAdapterInfo->AdapterDesc );\r
144         pAdapterInfo->m_pAdapter = pAdapter;\r
145 \r
146         // Enumerate the device driver types on the adapter.\r
147         hr = EnumerateDevices( pAdapterInfo );\r
148         if( FAILED( hr ) )\r
149         {\r
150             delete pAdapterInfo;\r
151             continue;\r
152         }\r
153 \r
154         hr = EnumerateOutputs( pAdapterInfo );\r
155         if( FAILED( hr ) || pAdapterInfo->outputInfoList.GetSize() <= 0 )\r
156         {\r
157             delete pAdapterInfo;\r
158             continue;\r
159         }\r
160 \r
161         // Get info for each devicecombo on this device\r
162         if( FAILED( hr = EnumerateDeviceCombos( pFactory, pAdapterInfo ) ) )\r
163         {\r
164             delete pAdapterInfo;\r
165             continue;\r
166         }\r
167 \r
168         hr = m_AdapterInfoList.Add( pAdapterInfo );\r
169         if( FAILED( hr ) )\r
170         {\r
171             delete pAdapterInfo;\r
172             return hr;\r
173         }\r
174     }\r
175 \r
176 \r
177     //  If we did not get an adapter then we should still enumerate WARP and Ref.\r
178     if (m_AdapterInfoList.GetSize() == 0) {\r
179 \r
180 \r
181         CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo;\r
182         if( !pAdapterInfo )\r
183         {\r
184             return E_OUTOFMEMORY;\r
185         }\r
186         ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) );\r
187         pAdapterInfo->bAdapterUnavailable = true;\r
188 \r
189         hr = EnumerateDevices( pAdapterInfo );\r
190 \r
191         // Get info for each devicecombo on this device\r
192         if( FAILED( hr = EnumerateDeviceCombosNoAdapter(  pAdapterInfo ) ) )\r
193         {\r
194             delete pAdapterInfo;\r
195         }\r
196 \r
197         if (!FAILED(hr)) hr = m_AdapterInfoList.Add( pAdapterInfo );\r
198     }\r
199 \r
200     //\r
201     // Check for 2 or more adapters with the same name. Append the name\r
202     // with some instance number if that's the case to help distinguish\r
203     // them.\r
204     //\r
205     bool bUniqueDesc = true;\r
206     CD3D11EnumAdapterInfo* pAdapterInfo;\r
207     for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ )\r
208     {\r
209         CD3D11EnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt( i );\r
210 \r
211         for( int j = i + 1; j < m_AdapterInfoList.GetSize(); j++ )\r
212         {\r
213             CD3D11EnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt( j );\r
214             if( wcsncmp( pAdapterInfo1->AdapterDesc.Description,\r
215                 pAdapterInfo2->AdapterDesc.Description, DXGI_MAX_DEVICE_IDENTIFIER_STRING ) == 0 )\r
216             {\r
217                 bUniqueDesc = false;\r
218                 break;\r
219             }\r
220         }\r
221 \r
222         if( !bUniqueDesc )\r
223             break;\r
224     }\r
225 \r
226     for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ )\r
227     {\r
228         pAdapterInfo = m_AdapterInfoList.GetAt( i );\r
229 \r
230         wcscpy_s( pAdapterInfo->szUniqueDescription, 100, pAdapterInfo->AdapterDesc.Description );\r
231         if( !bUniqueDesc )\r
232         {\r
233             WCHAR sz[100];\r
234             swprintf_s( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal );\r
235             wcscat_s( pAdapterInfo->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, sz );\r
236         }\r
237     }\r
238 \r
239     return S_OK;\r
240 }\r
241 \r
242 \r
243 //--------------------------------------------------------------------------------------\r
244 HRESULT CD3D11Enumeration::EnumerateOutputs( CD3D11EnumAdapterInfo* pAdapterInfo )\r
245 {\r
246     HRESULT hr;\r
247     IDXGIOutput* pOutput;\r
248 \r
249     for( int iOutput = 0; ; ++iOutput )\r
250     {\r
251         pOutput = NULL;\r
252         hr = pAdapterInfo->m_pAdapter->EnumOutputs( iOutput, &pOutput );\r
253         if( DXGI_ERROR_NOT_FOUND == hr )\r
254         {\r
255             return S_OK;\r
256         }\r
257         else if( FAILED( hr ) )\r
258         {\r
259             return hr;  //Something bad happened.\r
260         }\r
261         else //Success!\r
262         {\r
263             CD3D11EnumOutputInfo* pOutputInfo = new CD3D11EnumOutputInfo;\r
264             if( !pOutputInfo )\r
265             {\r
266                 SAFE_RELEASE( pOutput );\r
267                 return E_OUTOFMEMORY;\r
268             }\r
269             ZeroMemory( pOutputInfo, sizeof( CD3D11EnumOutputInfo ) );\r
270             pOutput->GetDesc( &pOutputInfo->Desc );\r
271             pOutputInfo->Output = iOutput;\r
272             pOutputInfo->m_pOutput = pOutput;\r
273 \r
274             EnumerateDisplayModes( pOutputInfo );\r
275             if( pOutputInfo->displayModeList.GetSize() <= 0 )\r
276             {\r
277                 // If this output has no valid display mode, do not save it.\r
278                 delete pOutputInfo;\r
279                 continue;\r
280             }\r
281 \r
282             hr = pAdapterInfo->outputInfoList.Add( pOutputInfo );\r
283             if( FAILED( hr ) )\r
284             {\r
285                 delete pOutputInfo;\r
286                 return hr;\r
287             }\r
288         }\r
289     }\r
290 }\r
291 \r
292 \r
293 //--------------------------------------------------------------------------------------\r
294 HRESULT CD3D11Enumeration::EnumerateDisplayModes( CD3D11EnumOutputInfo* pOutputInfo )\r
295 {\r
296     HRESULT hr = S_OK;\r
297     DXGI_FORMAT allowedAdapterFormatArray[] =\r
298     {\r
299         DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,     //This is DXUT's preferred mode\r
300 \r
301         DXGI_FORMAT_R8G8B8A8_UNORM,                     \r
302         DXGI_FORMAT_R16G16B16A16_FLOAT,\r
303         DXGI_FORMAT_R10G10B10A2_UNORM\r
304     };\r
305     int allowedAdapterFormatArrayCount = sizeof( allowedAdapterFormatArray ) / sizeof( allowedAdapterFormatArray[0] );\r
306 \r
307     // Swap perferred modes for apps running in linear space\r
308     DXGI_FORMAT RemoteMode = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;\r
309     if( !DXUTIsInGammaCorrectMode() )\r
310     {\r
311         allowedAdapterFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM;\r
312         allowedAdapterFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;\r
313         RemoteMode = DXGI_FORMAT_R8G8B8A8_UNORM;\r
314     }\r
315 \r
316     // The fast path only enumerates R8G8B8A8_UNORM_SRGB modes\r
317     if( !m_bEnumerateAllAdapterFormats )\r
318         allowedAdapterFormatArrayCount = 1;\r
319 \r
320     for( int f = 0; f < allowedAdapterFormatArrayCount; ++f )\r
321     {\r
322         // Fast-path: Try to grab at least 512 modes.\r
323         //                        This is to avoid calling GetDisplayModeList more times than necessary.\r
324         //                        GetDisplayModeList is an expensive call.\r
325         UINT NumModes = 512;\r
326         DXGI_MODE_DESC* pDesc = new DXGI_MODE_DESC[ NumModes ];\r
327         assert( pDesc );\r
328         if( !pDesc )\r
329             return E_OUTOFMEMORY;\r
330 \r
331         hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f],\r
332                                                          DXGI_ENUM_MODES_SCALING,\r
333                                                          &NumModes,\r
334                                                          pDesc );\r
335         if( DXGI_ERROR_NOT_FOUND == hr )\r
336         {\r
337             SAFE_DELETE_ARRAY( pDesc );\r
338             NumModes = 0;\r
339             break;\r
340         }\r
341         else if( MAKE_DXGI_HRESULT( 34 ) == hr && RemoteMode == allowedAdapterFormatArray[f] )\r
342         {\r
343             // DXGI cannot enumerate display modes over a remote session.  Therefore, create a fake display\r
344             // mode for the current screen resolution for the remote session.\r
345             if( 0 != GetSystemMetrics( 0x1000 ) ) // SM_REMOTESESSION\r
346             {\r
347                 DEVMODE DevMode;\r
348                 DevMode.dmSize = sizeof( DEVMODE );\r
349                 if( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &DevMode ) )\r
350                 {\r
351                     NumModes = 1;\r
352                     pDesc[0].Width = DevMode.dmPelsWidth;\r
353                     pDesc[0].Height = DevMode.dmPelsHeight;\r
354                     pDesc[0].Format = DXGI_FORMAT_R8G8B8A8_UNORM;\r
355                     pDesc[0].RefreshRate.Numerator = 60;\r
356                     pDesc[0].RefreshRate.Denominator = 1;\r
357                     pDesc[0].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;\r
358                     pDesc[0].Scaling = DXGI_MODE_SCALING_CENTERED;\r
359                     hr = S_OK;\r
360                 }\r
361             }\r
362         }\r
363         else if( DXGI_ERROR_MORE_DATA == hr )\r
364         {\r
365             // Slow path.  There were more than 512 modes.\r
366             SAFE_DELETE_ARRAY( pDesc );\r
367             hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f],\r
368                                                              DXGI_ENUM_MODES_SCALING,\r
369                                                              &NumModes,\r
370                                                              NULL );\r
371             if( FAILED( hr ) )\r
372             {\r
373                 NumModes = 0;\r
374                 break;\r
375             }\r
376 \r
377             pDesc = new DXGI_MODE_DESC[ NumModes ];\r
378             assert( pDesc );\r
379             if( !pDesc )\r
380                 return E_OUTOFMEMORY;\r
381 \r
382             hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f],\r
383                                                              DXGI_ENUM_MODES_SCALING,\r
384                                                              &NumModes,\r
385                                                              pDesc );\r
386             if( FAILED( hr ) )\r
387             {\r
388                 SAFE_DELETE_ARRAY( pDesc );\r
389                 NumModes = 0;\r
390                 break;\r
391             }\r
392 \r
393         }\r
394 \r
395         if( 0 == NumModes && 0 == f )\r
396         {\r
397             // No R8G8B8A8_UNORM_SRGB modes!\r
398             // Abort the fast-path if we're on it\r
399             allowedAdapterFormatArrayCount = sizeof( allowedAdapterFormatArray ) / sizeof\r
400                 ( allowedAdapterFormatArray[0] );\r
401             SAFE_DELETE_ARRAY( pDesc );\r
402             continue;\r
403         }\r
404 \r
405         if( SUCCEEDED( hr ) )\r
406         {\r
407             for( UINT m = 0; m < NumModes; m++ )\r
408             {\r
409                 pOutputInfo->displayModeList.Add( pDesc[m] );\r
410             }\r
411         }\r
412 \r
413         SAFE_DELETE_ARRAY( pDesc );\r
414     }\r
415 \r
416     return hr;\r
417 }\r
418 \r
419 \r
420 //--------------------------------------------------------------------------------------\r
421 HRESULT CD3D11Enumeration::EnumerateDevices( CD3D11EnumAdapterInfo* pAdapterInfo )\r
422 {\r
423     HRESULT hr;\r
424     DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();\r
425     const D3D_DRIVER_TYPE devTypeArray[] =\r
426     {\r
427         D3D_DRIVER_TYPE_HARDWARE,\r
428         D3D_DRIVER_TYPE_WARP,\r
429         D3D_DRIVER_TYPE_REFERENCE\r
430     };\r
431     const UINT devTypeArrayCount = sizeof( devTypeArray ) / sizeof( devTypeArray[0] );\r
432 \r
433     // Enumerate each Direct3D device type\r
434     for( UINT iDeviceType = 0; iDeviceType < devTypeArrayCount; iDeviceType++ )\r
435     {\r
436         CD3D11EnumDeviceInfo* pDeviceInfo = new CD3D11EnumDeviceInfo;\r
437         if( pDeviceInfo == NULL )\r
438             return E_OUTOFMEMORY;\r
439 \r
440         // Fill struct w/ AdapterOrdinal and D3DX10_DRIVER_TYPE\r
441         pDeviceInfo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal;\r
442         pDeviceInfo->DeviceType = devTypeArray[iDeviceType];\r
443 \r
444         D3D_FEATURE_LEVEL FeatureLevels[] =\r
445         {\r
446                     D3D_FEATURE_LEVEL_11_0,\r
447                     D3D_FEATURE_LEVEL_10_1,\r
448                     D3D_FEATURE_LEVEL_10_0,\r
449                     D3D_FEATURE_LEVEL_9_3,\r
450                     D3D_FEATURE_LEVEL_9_2,\r
451                     D3D_FEATURE_LEVEL_9_1\r
452         };\r
453         UINT NumFeatureLevels = ARRAYSIZE( FeatureLevels );\r
454 \r
455         // Call D3D11CreateDevice to ensure that this is a D3D11 device.\r
456         ID3D11Device* pd3dDevice = NULL;\r
457         ID3D11DeviceContext* pd3dDeviceContext = NULL;\r
458         IDXGIAdapter* pAdapter = NULL;\r
459         //if( devTypeArray[iDeviceType] == D3D_DRIVER_TYPE_HARDWARE )\r
460         //    pAdapter = pAdapterInfo->m_pAdapter;\r
461         hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter,\r
462                                              devTypeArray[iDeviceType],\r
463                                              ( HMODULE )0,\r
464                                              0,\r
465                                              FeatureLevels,\r
466                                              NumFeatureLevels,\r
467                                              D3D11_SDK_VERSION,\r
468                                              &pd3dDevice,\r
469                                              &pDeviceInfo->MaxLevel,\r
470                                              &pd3dDeviceContext );\r
471         if( FAILED( hr ) || pDeviceInfo->MaxLevel < deviceSettings.MinimumFeatureLevel)\r
472         {\r
473             delete pDeviceInfo;\r
474             continue;\r
475         }\r
476         \r
477         if (g_forceFL == 0 || g_forceFL == pDeviceInfo->MaxLevel) { \r
478             pDeviceInfo->SelectedLevel = pDeviceInfo->MaxLevel;\r
479         }\r
480         else if (g_forceFL > pDeviceInfo->MaxLevel) {\r
481             delete pDeviceInfo;\r
482             SAFE_RELEASE( pd3dDevice );\r
483             SAFE_RELEASE( pd3dDeviceContext );        \r
484             continue;\r
485         } else {\r
486             // A device was created with a higher feature level that the user-specified feature level.\r
487             SAFE_RELEASE( pd3dDevice );\r
488             SAFE_RELEASE( pd3dDeviceContext );\r
489             D3D_FEATURE_LEVEL rtFL;\r
490             hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter,\r
491                                              devTypeArray[iDeviceType],\r
492                                              ( HMODULE )0,\r
493                                              0,\r
494                                              &g_forceFL,\r
495                                              1,\r
496                                              D3D11_SDK_VERSION,\r
497                                              &pd3dDevice,\r
498                                              &rtFL,\r
499                                              &pd3dDeviceContext );\r
500 \r
501             if( !FAILED( hr ) && rtFL == g_forceFL ) {\r
502                 \r
503                 pDeviceInfo->SelectedLevel = g_forceFL;\r
504             }else {\r
505                 delete pDeviceInfo;\r
506                 SAFE_RELEASE( pd3dDevice );\r
507                 SAFE_RELEASE( pd3dDeviceContext );        \r
508                 continue;\r
509             }\r
510         }\r
511 \r
512         IDXGIDevice1* pDXGIDev = NULL;\r
513         hr = pd3dDevice->QueryInterface( __uuidof( IDXGIDevice1 ), ( LPVOID* )&pDXGIDev );\r
514         if( SUCCEEDED( hr ) && pDXGIDev )\r
515         {\r
516             SAFE_RELEASE( pAdapterInfo->m_pAdapter );\r
517             pDXGIDev->GetAdapter( &pAdapterInfo->m_pAdapter );\r
518         }\r
519         SAFE_RELEASE( pDXGIDev );\r
520 \r
521 \r
522         D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS ho;\r
523         pd3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &ho, sizeof(ho));\r
524         pDeviceInfo->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = ho.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x; \r
525         SAFE_RELEASE( pd3dDeviceContext );             \r
526         SAFE_RELEASE( pd3dDevice );\r
527         pAdapterInfo->deviceInfoList.Add( pDeviceInfo );\r
528     }\r
529 \r
530     return S_OK;\r
531 }\r
532 \r
533 \r
534 HRESULT CD3D11Enumeration::EnumerateDeviceCombosNoAdapter(  CD3D11EnumAdapterInfo* pAdapterInfo )\r
535 {\r
536     // Iterate through each combination of device driver type, output,\r
537     // adapter format, and backbuffer format to build the adapter's device combo list.\r
538     //\r
539 \r
540         for( int device = 0; device < pAdapterInfo->deviceInfoList.GetSize(); ++device )\r
541         {\r
542             CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( device );\r
543 \r
544             DXGI_FORMAT BufferFormatArray[] =\r
545             {\r
546                 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,   //This is DXUT's preferred mode\r
547 \r
548                 DXGI_FORMAT_R8G8B8A8_UNORM,             \r
549                 DXGI_FORMAT_R16G16B16A16_FLOAT,\r
550                 DXGI_FORMAT_R10G10B10A2_UNORM\r
551             };\r
552             const UINT BufferFormatArrayCount = sizeof( BufferFormatArray ) / sizeof\r
553                 ( BufferFormatArray[0] );\r
554 \r
555             // Swap perferred modes for apps running in linear space\r
556             if( !DXUTIsInGammaCorrectMode() )\r
557             {\r
558                 BufferFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM;\r
559                 BufferFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;\r
560             }\r
561 \r
562             for( UINT iBufferFormat = 0; iBufferFormat < BufferFormatArrayCount; iBufferFormat++ )\r
563             {\r
564                 DXGI_FORMAT BufferFormat = BufferFormatArray[iBufferFormat];\r
565 \r
566 \r
567 \r
568                     // determine if there are any modes for this particular format\r
569 \r
570 \r
571                     // If an application callback function has been provided, make sure this device\r
572                     // is acceptable to the app.\r
573                     if( m_IsD3D11DeviceAcceptableFunc != NULL )\r
574                     {\r
575                         if( !m_IsD3D11DeviceAcceptableFunc( pAdapterInfo, \r
576                                                             0,\r
577                                                             pDeviceInfo, \r
578                                                             BufferFormat,\r
579                                                             TRUE,\r
580                                                             m_pIsD3D11DeviceAcceptableFuncUserContext ) )\r
581                             continue;\r
582                     }\r
583 \r
584                     // At this point, we have an adapter/device/backbufferformat/iswindowed\r
585                     // DeviceCombo that is supported by the system. We still \r
586                     // need to find one or more suitable depth/stencil buffer format,\r
587                     // multisample type, and present interval.\r
588                     CD3D11EnumDeviceSettingsCombo* pDeviceCombo = new CD3D11EnumDeviceSettingsCombo;\r
589                     if( pDeviceCombo == NULL )\r
590                         return E_OUTOFMEMORY;\r
591 \r
592                     pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal;\r
593                     pDeviceCombo->DeviceType = pDeviceInfo->DeviceType;\r
594                     pDeviceCombo->BackBufferFormat = BufferFormat;\r
595                     pDeviceCombo->Windowed = TRUE;\r
596                     pDeviceCombo->Output = 0;\r
597                     pDeviceCombo->pAdapterInfo = pAdapterInfo;\r
598                     pDeviceCombo->pDeviceInfo = pDeviceInfo;\r
599                     pDeviceCombo->pOutputInfo = NULL;\r
600 \r
601                     BuildMultiSampleQualityList( BufferFormat, pDeviceCombo );\r
602 \r
603                     if( FAILED( pAdapterInfo->deviceSettingsComboList.Add( pDeviceCombo ) ) )\r
604                         delete pDeviceCombo;\r
605                 }\r
606                     \r
607         }\r
608 \r
609 \r
610     return S_OK;\r
611 }\r
612 \r
613 \r
614 //--------------------------------------------------------------------------------------\r
615 HRESULT CD3D11Enumeration::EnumerateDeviceCombos( IDXGIFactory1* pFactory, CD3D11EnumAdapterInfo* pAdapterInfo )\r
616 {\r
617     // Iterate through each combination of device driver type, output,\r
618     // adapter format, and backbuffer format to build the adapter's device combo list.\r
619     //\r
620 \r
621     for( int output = 0; output < pAdapterInfo->outputInfoList.GetSize(); ++output )\r
622     {\r
623         CD3D11EnumOutputInfo* pOutputInfo = pAdapterInfo->outputInfoList.GetAt( output );\r
624 \r
625         for( int device = 0; device < pAdapterInfo->deviceInfoList.GetSize(); ++device )\r
626         {\r
627             CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( device );\r
628 \r
629             DXGI_FORMAT backBufferFormatArray[] =\r
630             {\r
631                 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,   //This is DXUT's preferred mode\r
632 \r
633                 DXGI_FORMAT_R8G8B8A8_UNORM,             \r
634                 DXGI_FORMAT_R16G16B16A16_FLOAT,\r
635                 DXGI_FORMAT_R10G10B10A2_UNORM\r
636             };\r
637             const UINT backBufferFormatArrayCount = sizeof( backBufferFormatArray ) / sizeof\r
638                 ( backBufferFormatArray[0] );\r
639 \r
640             // Swap perferred modes for apps running in linear space\r
641             if( !DXUTIsInGammaCorrectMode() )\r
642             {\r
643                 backBufferFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM;\r
644                 backBufferFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;\r
645             }\r
646 \r
647             for( UINT iBackBufferFormat = 0; iBackBufferFormat < backBufferFormatArrayCount; iBackBufferFormat++ )\r
648             {\r
649                 DXGI_FORMAT backBufferFormat = backBufferFormatArray[iBackBufferFormat];\r
650 \r
651                 for( int nWindowed = 0; nWindowed < 2; nWindowed++ )\r
652                 {\r
653                     if( !nWindowed && pOutputInfo->displayModeList.GetSize() == 0 )\r
654                         continue;\r
655 \r
656                     // determine if there are any modes for this particular format\r
657                     UINT iModes = 0;\r
658                     for( int i = 0; i < pOutputInfo->displayModeList.GetSize(); i++ )\r
659                     {\r
660                         if( backBufferFormat == pOutputInfo->displayModeList.GetAt( i ).Format )\r
661                             iModes ++;\r
662                     }\r
663                     if( 0 == iModes )\r
664                         continue;\r
665 \r
666                     // If an application callback function has been provided, make sure this device\r
667                     // is acceptable to the app.\r
668                     if( m_IsD3D11DeviceAcceptableFunc != NULL )\r
669                     {\r
670                         if( !m_IsD3D11DeviceAcceptableFunc( pAdapterInfo, output,\r
671                                                             pDeviceInfo, backBufferFormat,\r
672                                                             FALSE != nWindowed,\r
673                                                             m_pIsD3D11DeviceAcceptableFuncUserContext ) )\r
674                             continue;\r
675                     }\r
676 \r
677                     // At this point, we have an adapter/device/backbufferformat/iswindowed\r
678                     // DeviceCombo that is supported by the system. We still \r
679                     // need to find one or more suitable depth/stencil buffer format,\r
680                     // multisample type, and present interval.\r
681                     CD3D11EnumDeviceSettingsCombo* pDeviceCombo = new CD3D11EnumDeviceSettingsCombo;\r
682                     if( pDeviceCombo == NULL )\r
683                         return E_OUTOFMEMORY;\r
684 \r
685                     pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal;\r
686                     pDeviceCombo->DeviceType = pDeviceInfo->DeviceType;\r
687                     pDeviceCombo->BackBufferFormat = backBufferFormat;\r
688                     pDeviceCombo->Windowed = ( nWindowed != 0 );\r
689                     pDeviceCombo->Output = pOutputInfo->Output;\r
690                     pDeviceCombo->pAdapterInfo = pAdapterInfo;\r
691                     pDeviceCombo->pDeviceInfo = pDeviceInfo;\r
692                     pDeviceCombo->pOutputInfo = pOutputInfo;\r
693 \r
694                     BuildMultiSampleQualityList( backBufferFormat, pDeviceCombo );\r
695 \r
696                     if( FAILED( pAdapterInfo->deviceSettingsComboList.Add( pDeviceCombo ) ) )\r
697                         delete pDeviceCombo;\r
698                 }\r
699             }\r
700         }\r
701     }\r
702 \r
703     return S_OK;\r
704 }\r
705 \r
706 \r
707 //--------------------------------------------------------------------------------------\r
708 // Release all the allocated CD3D11EnumAdapterInfo objects and empty the list\r
709 //--------------------------------------------------------------------------------------\r
710 void CD3D11Enumeration::ClearAdapterInfoList()\r
711 {\r
712     CD3D11EnumAdapterInfo* pAdapterInfo;\r
713     for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ )\r
714     {\r
715         pAdapterInfo = m_AdapterInfoList.GetAt( i );\r
716         delete pAdapterInfo;\r
717     }\r
718 \r
719     m_AdapterInfoList.RemoveAll();\r
720 }\r
721 \r
722 \r
723 //--------------------------------------------------------------------------------------\r
724 void CD3D11Enumeration::ResetPossibleDepthStencilFormats()\r
725 {\r
726     m_DepthStencilPossibleList.RemoveAll();\r
727     m_DepthStencilPossibleList.Add( DXGI_FORMAT_D32_FLOAT_S8X24_UINT );\r
728     m_DepthStencilPossibleList.Add( DXGI_FORMAT_D32_FLOAT );\r
729     m_DepthStencilPossibleList.Add( DXGI_FORMAT_D24_UNORM_S8_UINT );\r
730     m_DepthStencilPossibleList.Add( DXGI_FORMAT_D16_UNORM );\r
731 }\r
732 \r
733 //--------------------------------------------------------------------------------------\r
734 void CD3D11Enumeration::SetEnumerateAllAdapterFormats( bool bEnumerateAllAdapterFormats )\r
735 {\r
736     m_bEnumerateAllAdapterFormats = bEnumerateAllAdapterFormats;\r
737 }\r
738 \r
739 \r
740 //--------------------------------------------------------------------------------------\r
741 void CD3D11Enumeration::BuildMultiSampleQualityList( DXGI_FORMAT fmt, CD3D11EnumDeviceSettingsCombo* pDeviceCombo )\r
742 {\r
743     ID3D11Device* pd3dDevice = NULL;\r
744     ID3D11DeviceContext* pd3dDeviceContext = NULL;\r
745     IDXGIAdapter* pAdapter = NULL;\r
746     \r
747     //if( pDeviceCombo->DeviceType == D3D_DRIVER_TYPE_HARDWARE )\r
748     //    DXUTGetDXGIFactory()->EnumAdapters( pDeviceCombo->pAdapterInfo->AdapterOrdinal, &pAdapter );\r
749 \r
750     //DXGI_ADAPTER_DESC dad;\r
751     //pAdapter->GetDesc(&dad);\r
752 \r
753     D3D_FEATURE_LEVEL *FeatureLevels = &(pDeviceCombo->pDeviceInfo->SelectedLevel);\r
754     D3D_FEATURE_LEVEL returnedFeatureLevel;\r
755 \r
756     UINT NumFeatureLevels = 1;\r
757 \r
758     HRESULT hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter, \r
759                                                 pDeviceCombo->DeviceType,\r
760                                                 ( HMODULE )0,\r
761                                                 0,\r
762                                                 FeatureLevels,\r
763                                                 NumFeatureLevels,\r
764                                                 D3D11_SDK_VERSION,\r
765                                                 &pd3dDevice,\r
766                                                 &returnedFeatureLevel,\r
767                                                 &pd3dDeviceContext )  ;\r
768 \r
769     if( FAILED( hr))  return;\r
770 \r
771     if (returnedFeatureLevel != pDeviceCombo->pDeviceInfo->SelectedLevel) return;\r
772 \r
773     for( int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++i )\r
774     {\r
775         UINT Quality;\r
776         if( SUCCEEDED( pd3dDevice->CheckMultisampleQualityLevels( fmt, i, &Quality ) ) && Quality > 0 )\r
777         {\r
778             //From D3D10 docs: When multisampling a texture, the number of quality levels available for an adapter is dependent on the texture \r
779             //format used and the number of samples requested. The maximum sample count is defined by \r
780             //D3D10_MAX_MULTISAMPLE_SAMPLE_COUNT in d3d10.h. If the returned value of pNumQualityLevels is 0, \r
781             //the format and sample count combination is not supported for the installed adapter.\r
782 \r
783             if (Quality != 0) {\r
784                 pDeviceCombo->multiSampleCountList.Add( i );\r
785                 pDeviceCombo->multiSampleQualityList.Add( Quality );\r
786             }\r
787         }\r
788     }\r
789 \r
790     SAFE_RELEASE( pAdapter );\r
791     SAFE_RELEASE( pd3dDevice );\r
792     SAFE_RELEASE (pd3dDeviceContext);\r
793 }\r
794 \r
795 \r
796 //--------------------------------------------------------------------------------------\r
797 // Call GetAdapterInfoList() after Enumerate() to get a STL vector of \r
798 //       CD3D11EnumAdapterInfo* \r
799 //--------------------------------------------------------------------------------------\r
800 CGrowableArray <CD3D11EnumAdapterInfo*>* CD3D11Enumeration::GetAdapterInfoList()\r
801 {\r
802     return &m_AdapterInfoList;\r
803 }\r
804 \r
805 \r
806 //--------------------------------------------------------------------------------------\r
807 CD3D11EnumAdapterInfo* CD3D11Enumeration::GetAdapterInfo( UINT AdapterOrdinal )\r
808 {\r
809     for( int iAdapter = 0; iAdapter < m_AdapterInfoList.GetSize(); iAdapter++ )\r
810     {\r
811         CD3D11EnumAdapterInfo* pAdapterInfo = m_AdapterInfoList.GetAt( iAdapter );\r
812         if( pAdapterInfo->AdapterOrdinal == AdapterOrdinal )\r
813             return pAdapterInfo;\r
814     }\r
815 \r
816     return NULL;\r
817 }\r
818 \r
819 \r
820 //--------------------------------------------------------------------------------------\r
821 CD3D11EnumDeviceInfo* CD3D11Enumeration::GetDeviceInfo( UINT AdapterOrdinal, D3D_DRIVER_TYPE DeviceType )\r
822 {\r
823     CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );\r
824     if( pAdapterInfo )\r
825     {\r
826         for( int iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ )\r
827         {\r
828             CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( iDeviceInfo );\r
829             if( pDeviceInfo->DeviceType == DeviceType )\r
830                 return pDeviceInfo;\r
831         }\r
832     }\r
833 \r
834     return NULL;\r
835 }\r
836 \r
837 \r
838 //--------------------------------------------------------------------------------------\r
839 CD3D11EnumOutputInfo* CD3D11Enumeration::GetOutputInfo( UINT AdapterOrdinal, UINT Output )\r
840 {\r
841     CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );\r
842     if( pAdapterInfo && pAdapterInfo->outputInfoList.GetSize() > int( Output ) )\r
843     {\r
844         return pAdapterInfo->outputInfoList.GetAt( Output );\r
845     }\r
846 \r
847     return NULL;\r
848 }\r
849 \r
850 \r
851 //--------------------------------------------------------------------------------------\r
852 CD3D11EnumDeviceSettingsCombo* CD3D11Enumeration::GetDeviceSettingsCombo( UINT AdapterOrdinal,\r
853                                                                           D3D_DRIVER_TYPE DeviceType, UINT Output,\r
854                                                                           DXGI_FORMAT BackBufferFormat, BOOL Windowed )\r
855 {\r
856     CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );\r
857     if( pAdapterInfo )\r
858     {\r
859         for( int iDeviceCombo = 0; iDeviceCombo < pAdapterInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ )\r
860         {\r
861             CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo = pAdapterInfo->deviceSettingsComboList.GetAt(\r
862                 iDeviceCombo );\r
863             if( pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat &&\r
864                 pDeviceSettingsCombo->Windowed == Windowed )\r
865                 return pDeviceSettingsCombo;\r
866         }\r
867     }\r
868 \r
869     return NULL;\r
870 }\r
871 \r
872 \r
873 //--------------------------------------------------------------------------------------\r
874 CD3D11EnumOutputInfo::~CD3D11EnumOutputInfo( void )\r
875 {\r
876     SAFE_RELEASE( m_pOutput );\r
877     displayModeList.RemoveAll();\r
878 }\r
879 \r
880 \r
881 //--------------------------------------------------------------------------------------\r
882 CD3D11EnumDeviceInfo::~CD3D11EnumDeviceInfo()\r
883 {\r
884 }\r
885 \r
886 \r
887 //--------------------------------------------------------------------------------------\r
888 CD3D11EnumAdapterInfo::~CD3D11EnumAdapterInfo( void )\r
889 {\r
890     for( int i = 0; i < outputInfoList.GetSize(); i++ )\r
891     {\r
892         CD3D11EnumOutputInfo* pOutputInfo = outputInfoList.GetAt( i );\r
893         delete pOutputInfo;\r
894     }\r
895     outputInfoList.RemoveAll();\r
896 \r
897     for( int i = 0; i < deviceInfoList.GetSize(); ++i )\r
898     {\r
899         CD3D11EnumDeviceInfo* pDeviceInfo = deviceInfoList.GetAt( i );\r
900         delete pDeviceInfo;\r
901     }\r
902     deviceInfoList.RemoveAll();\r
903 \r
904     for( int i = 0; i < deviceSettingsComboList.GetSize(); ++i )\r
905     {\r
906         CD3D11EnumDeviceSettingsCombo* pDeviceCombo = deviceSettingsComboList.GetAt( i );\r
907         delete pDeviceCombo;\r
908     }\r
909     deviceSettingsComboList.RemoveAll();\r
910 \r
911     SAFE_RELEASE( m_pAdapter );\r
912 }\r
913 \r
914 //--------------------------------------------------------------------------------------\r
915 // Returns the number of color channel bits in the specified DXGI_FORMAT\r
916 //--------------------------------------------------------------------------------------\r
917 UINT WINAPI DXUTGetDXGIColorChannelBits( DXGI_FORMAT fmt )\r
918 {\r
919     switch( fmt )\r
920     {\r
921         case DXGI_FORMAT_R32G32B32A32_TYPELESS:\r
922         case DXGI_FORMAT_R32G32B32A32_FLOAT:\r
923         case DXGI_FORMAT_R32G32B32A32_UINT:\r
924         case DXGI_FORMAT_R32G32B32A32_SINT:\r
925         case DXGI_FORMAT_R32G32B32_TYPELESS:\r
926         case DXGI_FORMAT_R32G32B32_FLOAT:\r
927         case DXGI_FORMAT_R32G32B32_UINT:\r
928         case DXGI_FORMAT_R32G32B32_SINT:\r
929             return 32;\r
930 \r
931         case DXGI_FORMAT_R16G16B16A16_TYPELESS:\r
932         case DXGI_FORMAT_R16G16B16A16_FLOAT:\r
933         case DXGI_FORMAT_R16G16B16A16_UNORM:\r
934         case DXGI_FORMAT_R16G16B16A16_UINT:\r
935         case DXGI_FORMAT_R16G16B16A16_SNORM:\r
936         case DXGI_FORMAT_R16G16B16A16_SINT:\r
937             return 16;\r
938 \r
939         case DXGI_FORMAT_R10G10B10A2_TYPELESS:\r
940         case DXGI_FORMAT_R10G10B10A2_UNORM:\r
941         case DXGI_FORMAT_R10G10B10A2_UINT:\r
942             return 10;\r
943 \r
944         case DXGI_FORMAT_R8G8B8A8_TYPELESS:\r
945         case DXGI_FORMAT_R8G8B8A8_UNORM:\r
946         case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:\r
947         case DXGI_FORMAT_R8G8B8A8_UINT:\r
948         case DXGI_FORMAT_R8G8B8A8_SNORM:\r
949         case DXGI_FORMAT_R8G8B8A8_SINT:\r
950             return 8;\r
951 \r
952         case DXGI_FORMAT_B5G6R5_UNORM:\r
953         case DXGI_FORMAT_B5G5R5A1_UNORM:\r
954             return 5;\r
955 \r
956         default:\r
957             return 0;\r
958     }\r
959 }\r
960 \r
961 //--------------------------------------------------------------------------------------\r
962 // Returns a ranking number that describes how closely this device \r
963 // combo matches the optimal combo based on the match options and the optimal device settings\r
964 //--------------------------------------------------------------------------------------\r
965 float DXUTRankD3D11DeviceCombo( CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo,\r
966                                 DXUTD3D11DeviceSettings* pOptimalDeviceSettings,\r
967                                 DXGI_MODE_DESC* pAdapterDisplayMode,\r
968                                 int &bestModeIndex,\r
969                                 int &bestMSAAIndex\r
970                                 )\r
971 {\r
972     float fCurRanking = 0.0f;\r
973 \r
974     // Arbitrary weights.  Gives preference to the ordinal, device type, and windowed\r
975     const float fAdapterOrdinalWeight   = 1000.0f;\r
976     const float fAdapterOutputWeight    = 500.0f;\r
977     const float fDeviceTypeWeight       = 100.0f;\r
978     const float fWARPOverRefWeight       = 80.0f;\r
979 \r
980     const float fWindowWeight           = 10.0f;\r
981     const float fResolutionWeight       = 1.0f;\r
982     const float fBackBufferFormatWeight = 1.0f;\r
983     const float fMultiSampleWeight      = 1.0f;\r
984     const float fRefreshRateWeight      = 1.0f;\r
985 \r
986     //---------------------\r
987     // Adapter ordinal\r
988     //---------------------\r
989     if( pDeviceSettingsCombo->AdapterOrdinal == pOptimalDeviceSettings->AdapterOrdinal )\r
990         fCurRanking += fAdapterOrdinalWeight;\r
991 \r
992     //---------------------\r
993     // Adapter ordinal\r
994     //---------------------\r
995     if( pDeviceSettingsCombo->Output == pOptimalDeviceSettings->Output )\r
996         fCurRanking += fAdapterOutputWeight;\r
997 \r
998     //---------------------\r
999     // Device type\r
1000     //---------------------\r
1001     if( pDeviceSettingsCombo->DeviceType == pOptimalDeviceSettings->DriverType )\r
1002         fCurRanking += fDeviceTypeWeight;\r
1003     else if (pDeviceSettingsCombo->DeviceType == D3D_DRIVER_TYPE_WARP && pOptimalDeviceSettings->DriverType == D3D_DRIVER_TYPE_HARDWARE) {\r
1004         fCurRanking += fWARPOverRefWeight;\r
1005     }\r
1006 \r
1007     // Slightly prefer HAL \r
1008     if( pDeviceSettingsCombo->DeviceType == D3DDEVTYPE_HAL )\r
1009         fCurRanking += 0.1f;\r
1010 \r
1011     //---------------------\r
1012     // Windowed\r
1013     //---------------------\r
1014     if( pDeviceSettingsCombo->Windowed == pOptimalDeviceSettings->sd.Windowed )\r
1015         fCurRanking += fWindowWeight;\r
1016 \r
1017     //---------------------\r
1018     // Resolution\r
1019     //---------------------\r
1020     bool bResolutionFound = false;\r
1021     unsigned int best = 0xffffffff;\r
1022     bestModeIndex=0;\r
1023     for( int idm = 0; pDeviceSettingsCombo->pOutputInfo != NULL && idm < pDeviceSettingsCombo->pOutputInfo->displayModeList.GetSize() && !bResolutionFound; idm++ )\r
1024     {\r
1025         DXGI_MODE_DESC displayMode = pDeviceSettingsCombo->pOutputInfo->displayModeList.GetAt( idm );\r
1026         if( displayMode.Width == pOptimalDeviceSettings->sd.BufferDesc.Width &&\r
1027             displayMode.Height == pOptimalDeviceSettings->sd.BufferDesc.Height )\r
1028             bResolutionFound = true;\r
1029 \r
1030         unsigned int current = \r
1031             (UINT) abs ((int)displayMode.Width  - (int)pOptimalDeviceSettings->sd.BufferDesc.Width) + \r
1032             (UINT) abs ((int)displayMode.Height - (int)pOptimalDeviceSettings->sd.BufferDesc.Height );\r
1033 \r
1034         if (current < best) {\r
1035             best = current;\r
1036             bestModeIndex= idm;\r
1037 \r
1038         }\r
1039 \r
1040     }\r
1041     if( bResolutionFound )\r
1042         fCurRanking += fResolutionWeight;\r
1043 \r
1044     //---------------------\r
1045     // Back buffer format\r
1046     //---------------------\r
1047     if( pDeviceSettingsCombo->BackBufferFormat == pOptimalDeviceSettings->sd.BufferDesc.Format )\r
1048     {\r
1049         fCurRanking += fBackBufferFormatWeight;\r
1050     }\r
1051     else\r
1052     {\r
1053         int nBitDepthDelta = abs( ( long )DXUTGetDXGIColorChannelBits( pDeviceSettingsCombo->BackBufferFormat ) -\r
1054                                   ( long )DXUTGetDXGIColorChannelBits(\r
1055                                   pOptimalDeviceSettings->sd.BufferDesc.Format ) );\r
1056         float fScale = __max( 0.9f - ( float )nBitDepthDelta * 0.2f, 0.0f );\r
1057         fCurRanking += fScale * fBackBufferFormatWeight;\r
1058     }\r
1059 \r
1060     //---------------------\r
1061     // Back buffer count\r
1062     //---------------------\r
1063     // No caps for the back buffer count\r
1064 \r
1065     //---------------------\r
1066     // Multisample\r
1067     //---------------------\r
1068     bool bMultiSampleFound = false;\r
1069     bestMSAAIndex = 0;\r
1070     for( int i = 0; i < pDeviceSettingsCombo->multiSampleCountList.GetSize(); i++ )\r
1071     {\r
1072         UINT Count = pDeviceSettingsCombo->multiSampleCountList.GetAt( i );\r
1073 \r
1074         if( Count == pOptimalDeviceSettings->sd.SampleDesc.Count  )\r
1075         {\r
1076             bestMSAAIndex = i;\r
1077             bMultiSampleFound = true;\r
1078             break;\r
1079         }\r
1080     }\r
1081     if( bMultiSampleFound )\r
1082         fCurRanking += fMultiSampleWeight;\r
1083 \r
1084     //---------------------\r
1085     // Swap effect\r
1086     //---------------------\r
1087     // No caps for swap effects\r
1088 \r
1089     //---------------------\r
1090     // Depth stencil \r
1091     //---------------------\r
1092     // No caps for swap effects\r
1093 \r
1094     //---------------------\r
1095     // Present flags\r
1096     //---------------------\r
1097     // No caps for the present flags\r
1098 \r
1099     //---------------------\r
1100     // Refresh rate\r
1101     //---------------------\r
1102     bool bRefreshFound = false;\r
1103     for( int idm = 0; pDeviceSettingsCombo->pOutputInfo != NULL && idm < pDeviceSettingsCombo->pOutputInfo->displayModeList.GetSize(); idm++ )\r
1104     {\r
1105         DXGI_MODE_DESC displayMode = pDeviceSettingsCombo->pOutputInfo->displayModeList.GetAt( idm );\r
1106         if( fabs( float( displayMode.RefreshRate.Numerator ) / displayMode.RefreshRate.Denominator -\r
1107                   float( pOptimalDeviceSettings->sd.BufferDesc.RefreshRate.Numerator ) /\r
1108                   pOptimalDeviceSettings->sd.BufferDesc.RefreshRate.Denominator ) < 0.1f )\r
1109             bRefreshFound = true;\r
1110     }\r
1111     if( bRefreshFound )\r
1112         fCurRanking += fRefreshRateWeight;\r
1113 \r
1114     //---------------------\r
1115     // Present interval\r
1116     //---------------------\r
1117     // No caps for the present flags\r
1118 \r
1119     return fCurRanking;\r
1120 }\r
1121 \r
1122 \r
1123 //--------------------------------------------------------------------------------------\r
1124 // Returns the DXGI_MODE_DESC struct for a given adapter and output \r
1125 //--------------------------------------------------------------------------------------\r
1126 HRESULT WINAPI DXUTGetD3D11AdapterDisplayMode( UINT AdapterOrdinal, UINT nOutput, DXGI_MODE_DESC* pModeDesc )\r
1127 {\r
1128     if( !pModeDesc )\r
1129         return E_INVALIDARG;\r
1130 \r
1131     CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration();\r
1132     CD3D11EnumOutputInfo* pOutputInfo = pD3DEnum->GetOutputInfo( AdapterOrdinal, nOutput );\r
1133     if( pOutputInfo )\r
1134     {\r
1135         pModeDesc->Width = 640;\r
1136         pModeDesc->Height = 480;\r
1137         pModeDesc->RefreshRate.Numerator = 60;\r
1138         pModeDesc->RefreshRate.Denominator = 1;\r
1139         pModeDesc->Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;\r
1140         pModeDesc->Scaling = DXGI_MODE_SCALING_UNSPECIFIED;\r
1141         pModeDesc->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;\r
1142 \r
1143         DXGI_OUTPUT_DESC Desc;\r
1144         pOutputInfo->m_pOutput->GetDesc( &Desc );\r
1145         pModeDesc->Width = Desc.DesktopCoordinates.right - Desc.DesktopCoordinates.left;\r
1146         pModeDesc->Height = Desc.DesktopCoordinates.bottom - Desc.DesktopCoordinates.top;\r
1147     }\r
1148 \r
1149     // TODO: verify this is needed\r
1150     if( pModeDesc->Format == DXGI_FORMAT_B8G8R8A8_UNORM )\r
1151         pModeDesc->Format = DXGI_FORMAT_R8G8B8A8_UNORM;\r
1152 \r
1153     return S_OK;\r
1154 }\r