summaryrefslogtreecommitdiff
path: root/sample/d3d11/common/DXUTDevice11.cpp
diff options
context:
space:
mode:
authorJason Maskell <[email protected]>2016-05-09 10:39:54 +0200
committerJason Maskell <[email protected]>2016-05-09 10:39:54 +0200
commit79b3462799c28af8ba586349bd671b1b56e72353 (patch)
tree3b06e36c390254c0dc7f3733a0d32af213d87293 /sample/d3d11/common/DXUTDevice11.cpp
downloadwaveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.tar.xz
waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.zip
Initial commit with PS4 and XBone stuff trimmed.
Diffstat (limited to 'sample/d3d11/common/DXUTDevice11.cpp')
-rw-r--r--sample/d3d11/common/DXUTDevice11.cpp1154
1 files changed, 1154 insertions, 0 deletions
diff --git a/sample/d3d11/common/DXUTDevice11.cpp b/sample/d3d11/common/DXUTDevice11.cpp
new file mode 100644
index 0000000..d9dd494
--- /dev/null
+++ b/sample/d3d11/common/DXUTDevice11.cpp
@@ -0,0 +1,1154 @@
+//--------------------------------------------------------------------------------------
+// File: DXUTDevice11.cpp
+//
+// Enumerates D3D adapters, devices, modes, etc.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//--------------------------------------------------------------------------------------
+#include "DXUT.h"
+#undef min // use __min instead
+#undef max // use __max instead
+
+//--------------------------------------------------------------------------------------
+// Forward declarations
+//--------------------------------------------------------------------------------------
+extern void DXUTGetCallbackD3D11DeviceAcceptable( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE* ppCallbackIsDeviceAcceptable, void** ppUserContext );
+
+static int __cdecl SortModesCallback( const void* arg1, const void* arg2 );
+
+CD3D11Enumeration* g_pDXUTD3D11Enumeration = NULL;
+
+
+
+
+HRESULT WINAPI DXUTCreateD3D11Enumeration()
+{
+ if( g_pDXUTD3D11Enumeration == NULL )
+ {
+ g_pDXUTD3D11Enumeration = new CD3D11Enumeration();
+ if( NULL == g_pDXUTD3D11Enumeration )
+ return E_OUTOFMEMORY;
+ }
+ return S_OK;
+}
+
+void WINAPI DXUTDestroyD3D11Enumeration()
+{
+ SAFE_DELETE( g_pDXUTD3D11Enumeration );
+}
+
+class DXUTMemoryHelperD3D11Enum
+{
+public:
+DXUTMemoryHelperD3D11Enum()
+{
+ DXUTCreateD3D11Enumeration();
+}
+~DXUTMemoryHelperD3D11Enum()
+{
+ DXUTDestroyD3D11Enumeration();
+}
+};
+
+
+//--------------------------------------------------------------------------------------
+CD3D11Enumeration* WINAPI DXUTGetD3D11Enumeration( bool bForceEnumerate, bool bEnumerateAllAdapterFormats, D3D_FEATURE_LEVEL forceFL )
+{
+ // Using an static class with accessor function to allow control of the construction order
+ static DXUTMemoryHelperD3D11Enum d3d11enumMemory;
+ if( g_pDXUTD3D11Enumeration && ( !g_pDXUTD3D11Enumeration->HasEnumerated() || bForceEnumerate ) )
+ {
+ g_pDXUTD3D11Enumeration->SetEnumerateAllAdapterFormats( bEnumerateAllAdapterFormats );
+ LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE pCallbackIsDeviceAcceptable;
+ void* pUserContext;
+ DXUTGetCallbackD3D11DeviceAcceptable( &pCallbackIsDeviceAcceptable, &pUserContext );
+ g_pDXUTD3D11Enumeration->SetForceFeatureLevel(forceFL);
+
+ g_pDXUTD3D11Enumeration->Enumerate( pCallbackIsDeviceAcceptable, pUserContext );
+ }
+
+ return g_pDXUTD3D11Enumeration;
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11Enumeration::CD3D11Enumeration()
+{
+ m_bHasEnumerated = false;
+ m_IsD3D11DeviceAcceptableFunc = NULL;
+ m_pIsD3D11DeviceAcceptableFuncUserContext = NULL;
+
+ m_nMinWidth = 640;
+ m_nMinHeight = 480;
+ m_nMaxWidth = UINT_MAX;
+ m_nMaxHeight = UINT_MAX;
+ m_bEnumerateAllAdapterFormats = false;
+
+ m_nRefreshMin = 0;
+ m_nRefreshMax = UINT_MAX;
+
+ ResetPossibleDepthStencilFormats();
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11Enumeration::~CD3D11Enumeration()
+{
+ ClearAdapterInfoList();
+}
+
+
+//--------------------------------------------------------------------------------------
+// Enumerate for each adapter all of the supported display modes,
+// device types, adapter formats, back buffer formats, window/full screen support,
+// depth stencil formats, multisampling types/qualities, and presentations intervals.
+//
+// For each combination of device type (HAL/REF), adapter format, back buffer format, and
+// IsWindowed it will call the app's ConfirmDevice callback. This allows the app
+// to reject or allow that combination based on its caps/etc. It also allows the
+// app to change the BehaviorFlags. The BehaviorFlags defaults non-pure HWVP
+// if supported otherwise it will default to SWVP, however the app can change this
+// through the ConfirmDevice callback.
+//--------------------------------------------------------------------------------------
+HRESULT CD3D11Enumeration::Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc,
+ void* pIsD3D11DeviceAcceptableFuncUserContext )
+{
+ CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D11 Enumeration" );
+ HRESULT hr;
+ IDXGIFactory1* pFactory = DXUTGetDXGIFactory();
+ if( pFactory == NULL )
+ return E_FAIL;
+
+ m_bHasEnumerated = true;
+ m_IsD3D11DeviceAcceptableFunc = IsD3D11DeviceAcceptableFunc;
+ m_pIsD3D11DeviceAcceptableFuncUserContext = pIsD3D11DeviceAcceptableFuncUserContext;
+
+ ClearAdapterInfoList();
+
+ for( int index = 0; ; ++index )
+ {
+ IDXGIAdapter* pAdapter = NULL;
+ hr = pFactory->EnumAdapters( index, &pAdapter );
+ if( FAILED( hr ) ) // DXGIERR_NOT_FOUND is expected when the end of the list is hit
+ break;
+
+ CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo;
+ if( !pAdapterInfo )
+ {
+ SAFE_RELEASE( pAdapter );
+ return E_OUTOFMEMORY;
+ }
+ ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) );
+ pAdapterInfo->AdapterOrdinal = index;
+ pAdapter->GetDesc( &pAdapterInfo->AdapterDesc );
+ pAdapterInfo->m_pAdapter = pAdapter;
+
+ // Enumerate the device driver types on the adapter.
+ hr = EnumerateDevices( pAdapterInfo );
+ if( FAILED( hr ) )
+ {
+ delete pAdapterInfo;
+ continue;
+ }
+
+ hr = EnumerateOutputs( pAdapterInfo );
+ if( FAILED( hr ) || pAdapterInfo->outputInfoList.GetSize() <= 0 )
+ {
+ delete pAdapterInfo;
+ continue;
+ }
+
+ // Get info for each devicecombo on this device
+ if( FAILED( hr = EnumerateDeviceCombos( pFactory, pAdapterInfo ) ) )
+ {
+ delete pAdapterInfo;
+ continue;
+ }
+
+ hr = m_AdapterInfoList.Add( pAdapterInfo );
+ if( FAILED( hr ) )
+ {
+ delete pAdapterInfo;
+ return hr;
+ }
+ }
+
+
+ // If we did not get an adapter then we should still enumerate WARP and Ref.
+ if (m_AdapterInfoList.GetSize() == 0) {
+
+
+ CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo;
+ if( !pAdapterInfo )
+ {
+ return E_OUTOFMEMORY;
+ }
+ ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) );
+ pAdapterInfo->bAdapterUnavailable = true;
+
+ hr = EnumerateDevices( pAdapterInfo );
+
+ // Get info for each devicecombo on this device
+ if( FAILED( hr = EnumerateDeviceCombosNoAdapter( pAdapterInfo ) ) )
+ {
+ delete pAdapterInfo;
+ }
+
+ if (!FAILED(hr)) hr = m_AdapterInfoList.Add( pAdapterInfo );
+ }
+
+ //
+ // Check for 2 or more adapters with the same name. Append the name
+ // with some instance number if that's the case to help distinguish
+ // them.
+ //
+ bool bUniqueDesc = true;
+ CD3D11EnumAdapterInfo* pAdapterInfo;
+ for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ )
+ {
+ CD3D11EnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt( i );
+
+ for( int j = i + 1; j < m_AdapterInfoList.GetSize(); j++ )
+ {
+ CD3D11EnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt( j );
+ if( wcsncmp( pAdapterInfo1->AdapterDesc.Description,
+ pAdapterInfo2->AdapterDesc.Description, DXGI_MAX_DEVICE_IDENTIFIER_STRING ) == 0 )
+ {
+ bUniqueDesc = false;
+ break;
+ }
+ }
+
+ if( !bUniqueDesc )
+ break;
+ }
+
+ for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ )
+ {
+ pAdapterInfo = m_AdapterInfoList.GetAt( i );
+
+ wcscpy_s( pAdapterInfo->szUniqueDescription, 100, pAdapterInfo->AdapterDesc.Description );
+ if( !bUniqueDesc )
+ {
+ WCHAR sz[100];
+ swprintf_s( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal );
+ wcscat_s( pAdapterInfo->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, sz );
+ }
+ }
+
+ return S_OK;
+}
+
+
+//--------------------------------------------------------------------------------------
+HRESULT CD3D11Enumeration::EnumerateOutputs( CD3D11EnumAdapterInfo* pAdapterInfo )
+{
+ HRESULT hr;
+ IDXGIOutput* pOutput;
+
+ for( int iOutput = 0; ; ++iOutput )
+ {
+ pOutput = NULL;
+ hr = pAdapterInfo->m_pAdapter->EnumOutputs( iOutput, &pOutput );
+ if( DXGI_ERROR_NOT_FOUND == hr )
+ {
+ return S_OK;
+ }
+ else if( FAILED( hr ) )
+ {
+ return hr; //Something bad happened.
+ }
+ else //Success!
+ {
+ CD3D11EnumOutputInfo* pOutputInfo = new CD3D11EnumOutputInfo;
+ if( !pOutputInfo )
+ {
+ SAFE_RELEASE( pOutput );
+ return E_OUTOFMEMORY;
+ }
+ ZeroMemory( pOutputInfo, sizeof( CD3D11EnumOutputInfo ) );
+ pOutput->GetDesc( &pOutputInfo->Desc );
+ pOutputInfo->Output = iOutput;
+ pOutputInfo->m_pOutput = pOutput;
+
+ EnumerateDisplayModes( pOutputInfo );
+ if( pOutputInfo->displayModeList.GetSize() <= 0 )
+ {
+ // If this output has no valid display mode, do not save it.
+ delete pOutputInfo;
+ continue;
+ }
+
+ hr = pAdapterInfo->outputInfoList.Add( pOutputInfo );
+ if( FAILED( hr ) )
+ {
+ delete pOutputInfo;
+ return hr;
+ }
+ }
+ }
+}
+
+
+//--------------------------------------------------------------------------------------
+HRESULT CD3D11Enumeration::EnumerateDisplayModes( CD3D11EnumOutputInfo* pOutputInfo )
+{
+ HRESULT hr = S_OK;
+ DXGI_FORMAT allowedAdapterFormatArray[] =
+ {
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, //This is DXUT's preferred mode
+
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R10G10B10A2_UNORM
+ };
+ int allowedAdapterFormatArrayCount = sizeof( allowedAdapterFormatArray ) / sizeof( allowedAdapterFormatArray[0] );
+
+ // Swap perferred modes for apps running in linear space
+ DXGI_FORMAT RemoteMode = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ if( !DXUTIsInGammaCorrectMode() )
+ {
+ allowedAdapterFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
+ allowedAdapterFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ RemoteMode = DXGI_FORMAT_R8G8B8A8_UNORM;
+ }
+
+ // The fast path only enumerates R8G8B8A8_UNORM_SRGB modes
+ if( !m_bEnumerateAllAdapterFormats )
+ allowedAdapterFormatArrayCount = 1;
+
+ for( int f = 0; f < allowedAdapterFormatArrayCount; ++f )
+ {
+ // Fast-path: Try to grab at least 512 modes.
+ // This is to avoid calling GetDisplayModeList more times than necessary.
+ // GetDisplayModeList is an expensive call.
+ UINT NumModes = 512;
+ DXGI_MODE_DESC* pDesc = new DXGI_MODE_DESC[ NumModes ];
+ assert( pDesc );
+ if( !pDesc )
+ return E_OUTOFMEMORY;
+
+ hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f],
+ DXGI_ENUM_MODES_SCALING,
+ &NumModes,
+ pDesc );
+ if( DXGI_ERROR_NOT_FOUND == hr )
+ {
+ SAFE_DELETE_ARRAY( pDesc );
+ NumModes = 0;
+ break;
+ }
+ else if( MAKE_DXGI_HRESULT( 34 ) == hr && RemoteMode == allowedAdapterFormatArray[f] )
+ {
+ // DXGI cannot enumerate display modes over a remote session. Therefore, create a fake display
+ // mode for the current screen resolution for the remote session.
+ if( 0 != GetSystemMetrics( 0x1000 ) ) // SM_REMOTESESSION
+ {
+ DEVMODE DevMode;
+ DevMode.dmSize = sizeof( DEVMODE );
+ if( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &DevMode ) )
+ {
+ NumModes = 1;
+ pDesc[0].Width = DevMode.dmPelsWidth;
+ pDesc[0].Height = DevMode.dmPelsHeight;
+ pDesc[0].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ pDesc[0].RefreshRate.Numerator = 60;
+ pDesc[0].RefreshRate.Denominator = 1;
+ pDesc[0].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
+ pDesc[0].Scaling = DXGI_MODE_SCALING_CENTERED;
+ hr = S_OK;
+ }
+ }
+ }
+ else if( DXGI_ERROR_MORE_DATA == hr )
+ {
+ // Slow path. There were more than 512 modes.
+ SAFE_DELETE_ARRAY( pDesc );
+ hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f],
+ DXGI_ENUM_MODES_SCALING,
+ &NumModes,
+ NULL );
+ if( FAILED( hr ) )
+ {
+ NumModes = 0;
+ break;
+ }
+
+ pDesc = new DXGI_MODE_DESC[ NumModes ];
+ assert( pDesc );
+ if( !pDesc )
+ return E_OUTOFMEMORY;
+
+ hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f],
+ DXGI_ENUM_MODES_SCALING,
+ &NumModes,
+ pDesc );
+ if( FAILED( hr ) )
+ {
+ SAFE_DELETE_ARRAY( pDesc );
+ NumModes = 0;
+ break;
+ }
+
+ }
+
+ if( 0 == NumModes && 0 == f )
+ {
+ // No R8G8B8A8_UNORM_SRGB modes!
+ // Abort the fast-path if we're on it
+ allowedAdapterFormatArrayCount = sizeof( allowedAdapterFormatArray ) / sizeof
+ ( allowedAdapterFormatArray[0] );
+ SAFE_DELETE_ARRAY( pDesc );
+ continue;
+ }
+
+ if( SUCCEEDED( hr ) )
+ {
+ for( UINT m = 0; m < NumModes; m++ )
+ {
+ pOutputInfo->displayModeList.Add( pDesc[m] );
+ }
+ }
+
+ SAFE_DELETE_ARRAY( pDesc );
+ }
+
+ return hr;
+}
+
+
+//--------------------------------------------------------------------------------------
+HRESULT CD3D11Enumeration::EnumerateDevices( CD3D11EnumAdapterInfo* pAdapterInfo )
+{
+ HRESULT hr;
+ DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
+ const D3D_DRIVER_TYPE devTypeArray[] =
+ {
+ D3D_DRIVER_TYPE_HARDWARE,
+ D3D_DRIVER_TYPE_WARP,
+ D3D_DRIVER_TYPE_REFERENCE
+ };
+ const UINT devTypeArrayCount = sizeof( devTypeArray ) / sizeof( devTypeArray[0] );
+
+ // Enumerate each Direct3D device type
+ for( UINT iDeviceType = 0; iDeviceType < devTypeArrayCount; iDeviceType++ )
+ {
+ CD3D11EnumDeviceInfo* pDeviceInfo = new CD3D11EnumDeviceInfo;
+ if( pDeviceInfo == NULL )
+ return E_OUTOFMEMORY;
+
+ // Fill struct w/ AdapterOrdinal and D3DX10_DRIVER_TYPE
+ pDeviceInfo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal;
+ pDeviceInfo->DeviceType = devTypeArray[iDeviceType];
+
+ D3D_FEATURE_LEVEL FeatureLevels[] =
+ {
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
+ D3D_FEATURE_LEVEL_9_3,
+ D3D_FEATURE_LEVEL_9_2,
+ D3D_FEATURE_LEVEL_9_1
+ };
+ UINT NumFeatureLevels = ARRAYSIZE( FeatureLevels );
+
+ // Call D3D11CreateDevice to ensure that this is a D3D11 device.
+ ID3D11Device* pd3dDevice = NULL;
+ ID3D11DeviceContext* pd3dDeviceContext = NULL;
+ IDXGIAdapter* pAdapter = NULL;
+ //if( devTypeArray[iDeviceType] == D3D_DRIVER_TYPE_HARDWARE )
+ // pAdapter = pAdapterInfo->m_pAdapter;
+ hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter,
+ devTypeArray[iDeviceType],
+ ( HMODULE )0,
+ 0,
+ FeatureLevels,
+ NumFeatureLevels,
+ D3D11_SDK_VERSION,
+ &pd3dDevice,
+ &pDeviceInfo->MaxLevel,
+ &pd3dDeviceContext );
+ if( FAILED( hr ) || pDeviceInfo->MaxLevel < deviceSettings.MinimumFeatureLevel)
+ {
+ delete pDeviceInfo;
+ continue;
+ }
+
+ if (g_forceFL == 0 || g_forceFL == pDeviceInfo->MaxLevel) {
+ pDeviceInfo->SelectedLevel = pDeviceInfo->MaxLevel;
+ }
+ else if (g_forceFL > pDeviceInfo->MaxLevel) {
+ delete pDeviceInfo;
+ SAFE_RELEASE( pd3dDevice );
+ SAFE_RELEASE( pd3dDeviceContext );
+ continue;
+ } else {
+ // A device was created with a higher feature level that the user-specified feature level.
+ SAFE_RELEASE( pd3dDevice );
+ SAFE_RELEASE( pd3dDeviceContext );
+ D3D_FEATURE_LEVEL rtFL;
+ hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter,
+ devTypeArray[iDeviceType],
+ ( HMODULE )0,
+ 0,
+ &g_forceFL,
+ 1,
+ D3D11_SDK_VERSION,
+ &pd3dDevice,
+ &rtFL,
+ &pd3dDeviceContext );
+
+ if( !FAILED( hr ) && rtFL == g_forceFL ) {
+
+ pDeviceInfo->SelectedLevel = g_forceFL;
+ }else {
+ delete pDeviceInfo;
+ SAFE_RELEASE( pd3dDevice );
+ SAFE_RELEASE( pd3dDeviceContext );
+ continue;
+ }
+ }
+
+ IDXGIDevice1* pDXGIDev = NULL;
+ hr = pd3dDevice->QueryInterface( __uuidof( IDXGIDevice1 ), ( LPVOID* )&pDXGIDev );
+ if( SUCCEEDED( hr ) && pDXGIDev )
+ {
+ SAFE_RELEASE( pAdapterInfo->m_pAdapter );
+ pDXGIDev->GetAdapter( &pAdapterInfo->m_pAdapter );
+ }
+ SAFE_RELEASE( pDXGIDev );
+
+
+ D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS ho;
+ pd3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &ho, sizeof(ho));
+ pDeviceInfo->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = ho.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x;
+ SAFE_RELEASE( pd3dDeviceContext );
+ SAFE_RELEASE( pd3dDevice );
+ pAdapterInfo->deviceInfoList.Add( pDeviceInfo );
+ }
+
+ return S_OK;
+}
+
+
+HRESULT CD3D11Enumeration::EnumerateDeviceCombosNoAdapter( CD3D11EnumAdapterInfo* pAdapterInfo )
+{
+ // Iterate through each combination of device driver type, output,
+ // adapter format, and backbuffer format to build the adapter's device combo list.
+ //
+
+ for( int device = 0; device < pAdapterInfo->deviceInfoList.GetSize(); ++device )
+ {
+ CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( device );
+
+ DXGI_FORMAT BufferFormatArray[] =
+ {
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, //This is DXUT's preferred mode
+
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R10G10B10A2_UNORM
+ };
+ const UINT BufferFormatArrayCount = sizeof( BufferFormatArray ) / sizeof
+ ( BufferFormatArray[0] );
+
+ // Swap perferred modes for apps running in linear space
+ if( !DXUTIsInGammaCorrectMode() )
+ {
+ BufferFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
+ BufferFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ }
+
+ for( UINT iBufferFormat = 0; iBufferFormat < BufferFormatArrayCount; iBufferFormat++ )
+ {
+ DXGI_FORMAT BufferFormat = BufferFormatArray[iBufferFormat];
+
+
+
+ // determine if there are any modes for this particular format
+
+
+ // If an application callback function has been provided, make sure this device
+ // is acceptable to the app.
+ if( m_IsD3D11DeviceAcceptableFunc != NULL )
+ {
+ if( !m_IsD3D11DeviceAcceptableFunc( pAdapterInfo,
+ 0,
+ pDeviceInfo,
+ BufferFormat,
+ TRUE,
+ m_pIsD3D11DeviceAcceptableFuncUserContext ) )
+ continue;
+ }
+
+ // At this point, we have an adapter/device/backbufferformat/iswindowed
+ // DeviceCombo that is supported by the system. We still
+ // need to find one or more suitable depth/stencil buffer format,
+ // multisample type, and present interval.
+ CD3D11EnumDeviceSettingsCombo* pDeviceCombo = new CD3D11EnumDeviceSettingsCombo;
+ if( pDeviceCombo == NULL )
+ return E_OUTOFMEMORY;
+
+ pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal;
+ pDeviceCombo->DeviceType = pDeviceInfo->DeviceType;
+ pDeviceCombo->BackBufferFormat = BufferFormat;
+ pDeviceCombo->Windowed = TRUE;
+ pDeviceCombo->Output = 0;
+ pDeviceCombo->pAdapterInfo = pAdapterInfo;
+ pDeviceCombo->pDeviceInfo = pDeviceInfo;
+ pDeviceCombo->pOutputInfo = NULL;
+
+ BuildMultiSampleQualityList( BufferFormat, pDeviceCombo );
+
+ if( FAILED( pAdapterInfo->deviceSettingsComboList.Add( pDeviceCombo ) ) )
+ delete pDeviceCombo;
+ }
+
+ }
+
+
+ return S_OK;
+}
+
+
+//--------------------------------------------------------------------------------------
+HRESULT CD3D11Enumeration::EnumerateDeviceCombos( IDXGIFactory1* pFactory, CD3D11EnumAdapterInfo* pAdapterInfo )
+{
+ // Iterate through each combination of device driver type, output,
+ // adapter format, and backbuffer format to build the adapter's device combo list.
+ //
+
+ for( int output = 0; output < pAdapterInfo->outputInfoList.GetSize(); ++output )
+ {
+ CD3D11EnumOutputInfo* pOutputInfo = pAdapterInfo->outputInfoList.GetAt( output );
+
+ for( int device = 0; device < pAdapterInfo->deviceInfoList.GetSize(); ++device )
+ {
+ CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( device );
+
+ DXGI_FORMAT backBufferFormatArray[] =
+ {
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, //This is DXUT's preferred mode
+
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R10G10B10A2_UNORM
+ };
+ const UINT backBufferFormatArrayCount = sizeof( backBufferFormatArray ) / sizeof
+ ( backBufferFormatArray[0] );
+
+ // Swap perferred modes for apps running in linear space
+ if( !DXUTIsInGammaCorrectMode() )
+ {
+ backBufferFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
+ backBufferFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ }
+
+ for( UINT iBackBufferFormat = 0; iBackBufferFormat < backBufferFormatArrayCount; iBackBufferFormat++ )
+ {
+ DXGI_FORMAT backBufferFormat = backBufferFormatArray[iBackBufferFormat];
+
+ for( int nWindowed = 0; nWindowed < 2; nWindowed++ )
+ {
+ if( !nWindowed && pOutputInfo->displayModeList.GetSize() == 0 )
+ continue;
+
+ // determine if there are any modes for this particular format
+ UINT iModes = 0;
+ for( int i = 0; i < pOutputInfo->displayModeList.GetSize(); i++ )
+ {
+ if( backBufferFormat == pOutputInfo->displayModeList.GetAt( i ).Format )
+ iModes ++;
+ }
+ if( 0 == iModes )
+ continue;
+
+ // If an application callback function has been provided, make sure this device
+ // is acceptable to the app.
+ if( m_IsD3D11DeviceAcceptableFunc != NULL )
+ {
+ if( !m_IsD3D11DeviceAcceptableFunc( pAdapterInfo, output,
+ pDeviceInfo, backBufferFormat,
+ FALSE != nWindowed,
+ m_pIsD3D11DeviceAcceptableFuncUserContext ) )
+ continue;
+ }
+
+ // At this point, we have an adapter/device/backbufferformat/iswindowed
+ // DeviceCombo that is supported by the system. We still
+ // need to find one or more suitable depth/stencil buffer format,
+ // multisample type, and present interval.
+ CD3D11EnumDeviceSettingsCombo* pDeviceCombo = new CD3D11EnumDeviceSettingsCombo;
+ if( pDeviceCombo == NULL )
+ return E_OUTOFMEMORY;
+
+ pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal;
+ pDeviceCombo->DeviceType = pDeviceInfo->DeviceType;
+ pDeviceCombo->BackBufferFormat = backBufferFormat;
+ pDeviceCombo->Windowed = ( nWindowed != 0 );
+ pDeviceCombo->Output = pOutputInfo->Output;
+ pDeviceCombo->pAdapterInfo = pAdapterInfo;
+ pDeviceCombo->pDeviceInfo = pDeviceInfo;
+ pDeviceCombo->pOutputInfo = pOutputInfo;
+
+ BuildMultiSampleQualityList( backBufferFormat, pDeviceCombo );
+
+ if( FAILED( pAdapterInfo->deviceSettingsComboList.Add( pDeviceCombo ) ) )
+ delete pDeviceCombo;
+ }
+ }
+ }
+ }
+
+ return S_OK;
+}
+
+
+//--------------------------------------------------------------------------------------
+// Release all the allocated CD3D11EnumAdapterInfo objects and empty the list
+//--------------------------------------------------------------------------------------
+void CD3D11Enumeration::ClearAdapterInfoList()
+{
+ CD3D11EnumAdapterInfo* pAdapterInfo;
+ for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ )
+ {
+ pAdapterInfo = m_AdapterInfoList.GetAt( i );
+ delete pAdapterInfo;
+ }
+
+ m_AdapterInfoList.RemoveAll();
+}
+
+
+//--------------------------------------------------------------------------------------
+void CD3D11Enumeration::ResetPossibleDepthStencilFormats()
+{
+ m_DepthStencilPossibleList.RemoveAll();
+ m_DepthStencilPossibleList.Add( DXGI_FORMAT_D32_FLOAT_S8X24_UINT );
+ m_DepthStencilPossibleList.Add( DXGI_FORMAT_D32_FLOAT );
+ m_DepthStencilPossibleList.Add( DXGI_FORMAT_D24_UNORM_S8_UINT );
+ m_DepthStencilPossibleList.Add( DXGI_FORMAT_D16_UNORM );
+}
+
+//--------------------------------------------------------------------------------------
+void CD3D11Enumeration::SetEnumerateAllAdapterFormats( bool bEnumerateAllAdapterFormats )
+{
+ m_bEnumerateAllAdapterFormats = bEnumerateAllAdapterFormats;
+}
+
+
+//--------------------------------------------------------------------------------------
+void CD3D11Enumeration::BuildMultiSampleQualityList( DXGI_FORMAT fmt, CD3D11EnumDeviceSettingsCombo* pDeviceCombo )
+{
+ ID3D11Device* pd3dDevice = NULL;
+ ID3D11DeviceContext* pd3dDeviceContext = NULL;
+ IDXGIAdapter* pAdapter = NULL;
+
+ //if( pDeviceCombo->DeviceType == D3D_DRIVER_TYPE_HARDWARE )
+ // DXUTGetDXGIFactory()->EnumAdapters( pDeviceCombo->pAdapterInfo->AdapterOrdinal, &pAdapter );
+
+ //DXGI_ADAPTER_DESC dad;
+ //pAdapter->GetDesc(&dad);
+
+ D3D_FEATURE_LEVEL *FeatureLevels = &(pDeviceCombo->pDeviceInfo->SelectedLevel);
+ D3D_FEATURE_LEVEL returnedFeatureLevel;
+
+ UINT NumFeatureLevels = 1;
+
+ HRESULT hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter,
+ pDeviceCombo->DeviceType,
+ ( HMODULE )0,
+ 0,
+ FeatureLevels,
+ NumFeatureLevels,
+ D3D11_SDK_VERSION,
+ &pd3dDevice,
+ &returnedFeatureLevel,
+ &pd3dDeviceContext ) ;
+
+ if( FAILED( hr)) return;
+
+ if (returnedFeatureLevel != pDeviceCombo->pDeviceInfo->SelectedLevel) return;
+
+ for( int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++i )
+ {
+ UINT Quality;
+ if( SUCCEEDED( pd3dDevice->CheckMultisampleQualityLevels( fmt, i, &Quality ) ) && Quality > 0 )
+ {
+ //From D3D10 docs: When multisampling a texture, the number of quality levels available for an adapter is dependent on the texture
+ //format used and the number of samples requested. The maximum sample count is defined by
+ //D3D10_MAX_MULTISAMPLE_SAMPLE_COUNT in d3d10.h. If the returned value of pNumQualityLevels is 0,
+ //the format and sample count combination is not supported for the installed adapter.
+
+ if (Quality != 0) {
+ pDeviceCombo->multiSampleCountList.Add( i );
+ pDeviceCombo->multiSampleQualityList.Add( Quality );
+ }
+ }
+ }
+
+ SAFE_RELEASE( pAdapter );
+ SAFE_RELEASE( pd3dDevice );
+ SAFE_RELEASE (pd3dDeviceContext);
+}
+
+
+//--------------------------------------------------------------------------------------
+// Call GetAdapterInfoList() after Enumerate() to get a STL vector of
+// CD3D11EnumAdapterInfo*
+//--------------------------------------------------------------------------------------
+CGrowableArray <CD3D11EnumAdapterInfo*>* CD3D11Enumeration::GetAdapterInfoList()
+{
+ return &m_AdapterInfoList;
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11EnumAdapterInfo* CD3D11Enumeration::GetAdapterInfo( UINT AdapterOrdinal )
+{
+ for( int iAdapter = 0; iAdapter < m_AdapterInfoList.GetSize(); iAdapter++ )
+ {
+ CD3D11EnumAdapterInfo* pAdapterInfo = m_AdapterInfoList.GetAt( iAdapter );
+ if( pAdapterInfo->AdapterOrdinal == AdapterOrdinal )
+ return pAdapterInfo;
+ }
+
+ return NULL;
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11EnumDeviceInfo* CD3D11Enumeration::GetDeviceInfo( UINT AdapterOrdinal, D3D_DRIVER_TYPE DeviceType )
+{
+ CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );
+ if( pAdapterInfo )
+ {
+ for( int iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ )
+ {
+ CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( iDeviceInfo );
+ if( pDeviceInfo->DeviceType == DeviceType )
+ return pDeviceInfo;
+ }
+ }
+
+ return NULL;
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11EnumOutputInfo* CD3D11Enumeration::GetOutputInfo( UINT AdapterOrdinal, UINT Output )
+{
+ CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );
+ if( pAdapterInfo && pAdapterInfo->outputInfoList.GetSize() > int( Output ) )
+ {
+ return pAdapterInfo->outputInfoList.GetAt( Output );
+ }
+
+ return NULL;
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11EnumDeviceSettingsCombo* CD3D11Enumeration::GetDeviceSettingsCombo( UINT AdapterOrdinal,
+ D3D_DRIVER_TYPE DeviceType, UINT Output,
+ DXGI_FORMAT BackBufferFormat, BOOL Windowed )
+{
+ CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );
+ if( pAdapterInfo )
+ {
+ for( int iDeviceCombo = 0; iDeviceCombo < pAdapterInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ )
+ {
+ CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo = pAdapterInfo->deviceSettingsComboList.GetAt(
+ iDeviceCombo );
+ if( pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat &&
+ pDeviceSettingsCombo->Windowed == Windowed )
+ return pDeviceSettingsCombo;
+ }
+ }
+
+ return NULL;
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11EnumOutputInfo::~CD3D11EnumOutputInfo( void )
+{
+ SAFE_RELEASE( m_pOutput );
+ displayModeList.RemoveAll();
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11EnumDeviceInfo::~CD3D11EnumDeviceInfo()
+{
+}
+
+
+//--------------------------------------------------------------------------------------
+CD3D11EnumAdapterInfo::~CD3D11EnumAdapterInfo( void )
+{
+ for( int i = 0; i < outputInfoList.GetSize(); i++ )
+ {
+ CD3D11EnumOutputInfo* pOutputInfo = outputInfoList.GetAt( i );
+ delete pOutputInfo;
+ }
+ outputInfoList.RemoveAll();
+
+ for( int i = 0; i < deviceInfoList.GetSize(); ++i )
+ {
+ CD3D11EnumDeviceInfo* pDeviceInfo = deviceInfoList.GetAt( i );
+ delete pDeviceInfo;
+ }
+ deviceInfoList.RemoveAll();
+
+ for( int i = 0; i < deviceSettingsComboList.GetSize(); ++i )
+ {
+ CD3D11EnumDeviceSettingsCombo* pDeviceCombo = deviceSettingsComboList.GetAt( i );
+ delete pDeviceCombo;
+ }
+ deviceSettingsComboList.RemoveAll();
+
+ SAFE_RELEASE( m_pAdapter );
+}
+
+//--------------------------------------------------------------------------------------
+// Returns the number of color channel bits in the specified DXGI_FORMAT
+//--------------------------------------------------------------------------------------
+UINT WINAPI DXUTGetDXGIColorChannelBits( DXGI_FORMAT fmt )
+{
+ switch( fmt )
+ {
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ case DXGI_FORMAT_R32G32B32_UINT:
+ case DXGI_FORMAT_R32G32B32_SINT:
+ return 32;
+
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ return 16;
+
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ return 10;
+
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ return 8;
+
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ return 5;
+
+ default:
+ return 0;
+ }
+}
+
+//--------------------------------------------------------------------------------------
+// Returns a ranking number that describes how closely this device
+// combo matches the optimal combo based on the match options and the optimal device settings
+//--------------------------------------------------------------------------------------
+float DXUTRankD3D11DeviceCombo( CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo,
+ DXUTD3D11DeviceSettings* pOptimalDeviceSettings,
+ DXGI_MODE_DESC* pAdapterDisplayMode,
+ int &bestModeIndex,
+ int &bestMSAAIndex
+ )
+{
+ float fCurRanking = 0.0f;
+
+ // Arbitrary weights. Gives preference to the ordinal, device type, and windowed
+ const float fAdapterOrdinalWeight = 1000.0f;
+ const float fAdapterOutputWeight = 500.0f;
+ const float fDeviceTypeWeight = 100.0f;
+ const float fWARPOverRefWeight = 80.0f;
+
+ const float fWindowWeight = 10.0f;
+ const float fResolutionWeight = 1.0f;
+ const float fBackBufferFormatWeight = 1.0f;
+ const float fMultiSampleWeight = 1.0f;
+ const float fRefreshRateWeight = 1.0f;
+
+ //---------------------
+ // Adapter ordinal
+ //---------------------
+ if( pDeviceSettingsCombo->AdapterOrdinal == pOptimalDeviceSettings->AdapterOrdinal )
+ fCurRanking += fAdapterOrdinalWeight;
+
+ //---------------------
+ // Adapter ordinal
+ //---------------------
+ if( pDeviceSettingsCombo->Output == pOptimalDeviceSettings->Output )
+ fCurRanking += fAdapterOutputWeight;
+
+ //---------------------
+ // Device type
+ //---------------------
+ if( pDeviceSettingsCombo->DeviceType == pOptimalDeviceSettings->DriverType )
+ fCurRanking += fDeviceTypeWeight;
+ else if (pDeviceSettingsCombo->DeviceType == D3D_DRIVER_TYPE_WARP && pOptimalDeviceSettings->DriverType == D3D_DRIVER_TYPE_HARDWARE) {
+ fCurRanking += fWARPOverRefWeight;
+ }
+
+ // Slightly prefer HAL
+ if( pDeviceSettingsCombo->DeviceType == D3DDEVTYPE_HAL )
+ fCurRanking += 0.1f;
+
+ //---------------------
+ // Windowed
+ //---------------------
+ if( pDeviceSettingsCombo->Windowed == pOptimalDeviceSettings->sd.Windowed )
+ fCurRanking += fWindowWeight;
+
+ //---------------------
+ // Resolution
+ //---------------------
+ bool bResolutionFound = false;
+ unsigned int best = 0xffffffff;
+ bestModeIndex=0;
+ for( int idm = 0; pDeviceSettingsCombo->pOutputInfo != NULL && idm < pDeviceSettingsCombo->pOutputInfo->displayModeList.GetSize() && !bResolutionFound; idm++ )
+ {
+ DXGI_MODE_DESC displayMode = pDeviceSettingsCombo->pOutputInfo->displayModeList.GetAt( idm );
+ if( displayMode.Width == pOptimalDeviceSettings->sd.BufferDesc.Width &&
+ displayMode.Height == pOptimalDeviceSettings->sd.BufferDesc.Height )
+ bResolutionFound = true;
+
+ unsigned int current =
+ (UINT) abs ((int)displayMode.Width - (int)pOptimalDeviceSettings->sd.BufferDesc.Width) +
+ (UINT) abs ((int)displayMode.Height - (int)pOptimalDeviceSettings->sd.BufferDesc.Height );
+
+ if (current < best) {
+ best = current;
+ bestModeIndex= idm;
+
+ }
+
+ }
+ if( bResolutionFound )
+ fCurRanking += fResolutionWeight;
+
+ //---------------------
+ // Back buffer format
+ //---------------------
+ if( pDeviceSettingsCombo->BackBufferFormat == pOptimalDeviceSettings->sd.BufferDesc.Format )
+ {
+ fCurRanking += fBackBufferFormatWeight;
+ }
+ else
+ {
+ int nBitDepthDelta = abs( ( long )DXUTGetDXGIColorChannelBits( pDeviceSettingsCombo->BackBufferFormat ) -
+ ( long )DXUTGetDXGIColorChannelBits(
+ pOptimalDeviceSettings->sd.BufferDesc.Format ) );
+ float fScale = __max( 0.9f - ( float )nBitDepthDelta * 0.2f, 0.0f );
+ fCurRanking += fScale * fBackBufferFormatWeight;
+ }
+
+ //---------------------
+ // Back buffer count
+ //---------------------
+ // No caps for the back buffer count
+
+ //---------------------
+ // Multisample
+ //---------------------
+ bool bMultiSampleFound = false;
+ bestMSAAIndex = 0;
+ for( int i = 0; i < pDeviceSettingsCombo->multiSampleCountList.GetSize(); i++ )
+ {
+ UINT Count = pDeviceSettingsCombo->multiSampleCountList.GetAt( i );
+
+ if( Count == pOptimalDeviceSettings->sd.SampleDesc.Count )
+ {
+ bestMSAAIndex = i;
+ bMultiSampleFound = true;
+ break;
+ }
+ }
+ if( bMultiSampleFound )
+ fCurRanking += fMultiSampleWeight;
+
+ //---------------------
+ // Swap effect
+ //---------------------
+ // No caps for swap effects
+
+ //---------------------
+ // Depth stencil
+ //---------------------
+ // No caps for swap effects
+
+ //---------------------
+ // Present flags
+ //---------------------
+ // No caps for the present flags
+
+ //---------------------
+ // Refresh rate
+ //---------------------
+ bool bRefreshFound = false;
+ for( int idm = 0; pDeviceSettingsCombo->pOutputInfo != NULL && idm < pDeviceSettingsCombo->pOutputInfo->displayModeList.GetSize(); idm++ )
+ {
+ DXGI_MODE_DESC displayMode = pDeviceSettingsCombo->pOutputInfo->displayModeList.GetAt( idm );
+ if( fabs( float( displayMode.RefreshRate.Numerator ) / displayMode.RefreshRate.Denominator -
+ float( pOptimalDeviceSettings->sd.BufferDesc.RefreshRate.Numerator ) /
+ pOptimalDeviceSettings->sd.BufferDesc.RefreshRate.Denominator ) < 0.1f )
+ bRefreshFound = true;
+ }
+ if( bRefreshFound )
+ fCurRanking += fRefreshRateWeight;
+
+ //---------------------
+ // Present interval
+ //---------------------
+ // No caps for the present flags
+
+ return fCurRanking;
+}
+
+
+//--------------------------------------------------------------------------------------
+// Returns the DXGI_MODE_DESC struct for a given adapter and output
+//--------------------------------------------------------------------------------------
+HRESULT WINAPI DXUTGetD3D11AdapterDisplayMode( UINT AdapterOrdinal, UINT nOutput, DXGI_MODE_DESC* pModeDesc )
+{
+ if( !pModeDesc )
+ return E_INVALIDARG;
+
+ CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration();
+ CD3D11EnumOutputInfo* pOutputInfo = pD3DEnum->GetOutputInfo( AdapterOrdinal, nOutput );
+ if( pOutputInfo )
+ {
+ pModeDesc->Width = 640;
+ pModeDesc->Height = 480;
+ pModeDesc->RefreshRate.Numerator = 60;
+ pModeDesc->RefreshRate.Denominator = 1;
+ pModeDesc->Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ pModeDesc->Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+ pModeDesc->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+
+ DXGI_OUTPUT_DESC Desc;
+ pOutputInfo->m_pOutput->GetDesc( &Desc );
+ pModeDesc->Width = Desc.DesktopCoordinates.right - Desc.DesktopCoordinates.left;
+ pModeDesc->Height = Desc.DesktopCoordinates.bottom - Desc.DesktopCoordinates.top;
+ }
+
+ // TODO: verify this is needed
+ if( pModeDesc->Format == DXGI_FORMAT_B8G8R8A8_UNORM )
+ pModeDesc->Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+
+ return S_OK;
+}