//-------------------------------------------------------------------------------------- // File: DXUTSettingsDlg.cpp // // Dialog for selection of device settings // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=320437 //-------------------------------------------------------------------------------------- #include "DXUT.h" #include "DXUTgui.h" #include "DXUTsettingsDlg.h" //-------------------------------------------------------------------------------------- // Internal functions forward declarations //-------------------------------------------------------------------------------------- const WCHAR* DXUTPresentIntervalToString( _In_ UINT pi ); const WCHAR* DXUTDeviceTypeToString( _In_ D3D_DRIVER_TYPE devType ); const WCHAR* DXUTVertexProcessingTypeToString( _In_ DWORD vpt ); HRESULT DXUTSnapDeviceSettingsToEnumDevice( DXUTDeviceSettings* pDeviceSettings, bool forceEnum, D3D_FEATURE_LEVEL forceFL = D3D_FEATURE_LEVEL(0) ); //-------------------------------------------------------------------------------------- // Global state //-------------------------------------------------------------------------------------- DXUTDeviceSettings g_DeviceSettings; CD3DSettingsDlg* WINAPI DXUTGetD3DSettingsDialog() { // Using an accessor function gives control of the construction order static CD3DSettingsDlg dlg; return &dlg; } //-------------------------------------------------------------------------------------- CD3DSettingsDlg::CD3DSettingsDlg() : m_bActive( false ), m_pActiveDialog( nullptr ) { m_Levels[0] = D3D_FEATURE_LEVEL_9_1; m_Levels[1] = D3D_FEATURE_LEVEL_9_2; m_Levels[2] = D3D_FEATURE_LEVEL_9_3; m_Levels[3] = D3D_FEATURE_LEVEL_10_0; m_Levels[4] = D3D_FEATURE_LEVEL_10_1; m_Levels[5] = D3D_FEATURE_LEVEL_11_0; m_Levels[6] = D3D_FEATURE_LEVEL_11_1; #ifdef USE_DIRECT3D11_3 m_Levels[7] = D3D_FEATURE_LEVEL_12_0; m_Levels[8] = D3D_FEATURE_LEVEL_12_1; #endif } //-------------------------------------------------------------------------------------- CD3DSettingsDlg::~CD3DSettingsDlg() { // Release the memory used to hold the D3D11 refresh data in the combo box auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); if( pComboBox ) for( UINT i = 0; i < pComboBox->GetNumItems(); ++i ) { auto pRate = reinterpret_cast( pComboBox->GetItemData( i ) ); delete pRate; } } //-------------------------------------------------------------------------------------- void CD3DSettingsDlg::Init( _In_ CDXUTDialogResourceManager* pManager ) { assert( pManager ); m_Dialog.Init( pManager, false ); // Don't register this dialog. m_RevertModeDialog.Init( pManager, false ); // Don't register this dialog. m_pActiveDialog = &m_Dialog; CreateControls(); } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ void CD3DSettingsDlg::Init( CDXUTDialogResourceManager* pManager, LPCWSTR szControlTextureFileName ) { assert( pManager ); m_Dialog.Init( pManager, false, szControlTextureFileName ); // Don't register this dialog. m_RevertModeDialog.Init( pManager, false, szControlTextureFileName ); // Don't register this dialog. m_pActiveDialog = &m_Dialog; CreateControls(); } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ void CD3DSettingsDlg::Init( CDXUTDialogResourceManager* pManager, LPCWSTR pszControlTextureResourcename, HMODULE hModule ) { assert( pManager ); m_Dialog.Init( pManager, false, pszControlTextureResourcename, hModule ); // Don't register this dialog. m_RevertModeDialog.Init( pManager, false, pszControlTextureResourcename, hModule ); // Don't register this dialog m_pActiveDialog = &m_Dialog; CreateControls(); } //-------------------------------------------------------------------------------------- void CD3DSettingsDlg::CreateControls() { // Set up main settings dialog m_Dialog.EnableKeyboardInput( true ); m_Dialog.SetFont( 0, L"Arial", 15, FW_NORMAL ); m_Dialog.SetFont( 1, L"Arial", 28, FW_BOLD ); // Right-justify static controls auto pElement = m_Dialog.GetDefaultElement( DXUT_CONTROL_STATIC, 0 ); if( pElement ) { pElement->dwTextFormat = DT_VCENTER | DT_RIGHT; // Title CDXUTStatic* pStatic = nullptr; m_Dialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"Direct3D Settings", 10, 5, 400, 50, false, &pStatic ); pElement = pStatic->GetElement( 0 ); pElement->iFont = 1; pElement->dwTextFormat = DT_TOP | DT_LEFT; } //DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL_LABEL, L"Feature Level", 10, 60, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL, 200, 60, 400, 23 ); m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL )->SetDropHeight( 106 ); // DXUTSETTINGSDLG_ADAPTER m_Dialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"Display Adapter", 10, 85, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_ADAPTER, 200, 85, 400, 23 ); // DXUTSETTINGSDLG_DEVICE_TYPE m_Dialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"Render Device", 10, 110, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_DEVICE_TYPE, 200, 110, 400, 23 ); // DXUTSETTINGSDLG_WINDOWED, DXUTSETTINGSDLG_FULLSCREEN m_Dialog.AddRadioButton( DXUTSETTINGSDLG_WINDOWED, DXUTSETTINGSDLG_WINDOWED_GROUP, L"Windowed", 360, 157, 100, 16 ); m_Dialog.AddRadioButton( DXUTSETTINGSDLG_FULLSCREEN, DXUTSETTINGSDLG_WINDOWED_GROUP, L"Full Screen", 220, 157, 100, 16 ); // DXUTSETTINGSDLG_RES_SHOW_ALL m_Dialog.AddCheckBox( DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL, L"Show All Aspect Ratios", 420, 200, 200, 23, false ); // DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL, L"Adapter Output", 10, 175, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT, 200, 175, 400, 23 ); // DXUTSETTINGSDLG_D3D11_RESOLUTION m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL, L"Resolution", 10, 200, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION, 200, 200, 200, 23 ); m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION )->SetDropHeight( 106 ); // DXUTSETTINGSDLG_D3D11_REFRESH_RATE m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL, L"Refresh Rate", 10, 225, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE, 200, 225, 400, 23 ); // DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT_LABEL, L"Back Buffer Format", 10, 260, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT, 200, 260, 400, 23 ); // DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT_LABEL, L"Multisample Count", 10, 285, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT, 200, 285, 400, 23 ); // DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY_LABEL, L"Multisample Quality", 10, 310, 180, 23 ); m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY, 200, 310, 400, 23 ); // DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL_LABEL, L"Vertical Sync", 10, 335, 180, 23 ); m_Dialog.AddComboBox(DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL, 200, 335, 400, 23); auto pPresentIntervalComboBox = m_Dialog.GetComboBox(DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL); if (pPresentIntervalComboBox) { pPresentIntervalComboBox->AddItem(L"On", ULongToPtr(1)); pPresentIntervalComboBox->AddItem(L"Off", ULongToPtr(0)); } // DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE m_Dialog.AddCheckBox( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE, L"Create Debug Device", 200, 365, 180, 23 ); // DXUTSETTINGSDLG_OK, DXUTSETTINGSDLG_CANCEL m_Dialog.AddButton( DXUTSETTINGSDLG_OK, L"OK", 230, 440, 73, 31 ); m_Dialog.AddButton( DXUTSETTINGSDLG_CANCEL, L"Cancel", 315, 440, 73, 31, 0, true ); // Set up mode change dialog m_RevertModeDialog.EnableKeyboardInput( true ); m_RevertModeDialog.EnableNonUserEvents( true ); m_RevertModeDialog.SetFont( 0, L"Arial", 15, FW_NORMAL ); m_RevertModeDialog.SetFont( 1, L"Arial", 28, FW_BOLD ); pElement = m_RevertModeDialog.GetDefaultElement( DXUT_CONTROL_STATIC, 0 ); if( pElement ) { pElement->dwTextFormat = DT_VCENTER | DT_RIGHT; // Title CDXUTStatic* pStatic = nullptr; if ( SUCCEEDED(m_RevertModeDialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"Do you want to keep these display settings?", 10, 5, 640, 50, false, &pStatic ) ) ) pElement = pStatic->GetElement( 0 ); pElement->iFont = 1; pElement->dwTextFormat = DT_TOP | DT_LEFT; // Timeout static text control if ( SUCCEEDED(m_RevertModeDialog.AddStatic( DXUTSETTINGSDLG_STATIC_MODE_CHANGE_TIMEOUT, L"", 10, 90, 640, 30, false, &pStatic ) ) ) pElement = pStatic->GetElement( 0 ); pElement->iFont = 0; pElement->dwTextFormat = DT_TOP | DT_LEFT; } // DXUTSETTINGSDLG_MODE_CHANGE_ACCEPT, DXUTSETTINGSDLG_MODE_CHANGE_REVERT m_RevertModeDialog.AddButton( DXUTSETTINGSDLG_MODE_CHANGE_ACCEPT, L"Yes", 230, 50, 73, 31 ); m_RevertModeDialog.AddButton( DXUTSETTINGSDLG_MODE_CHANGE_REVERT, L"No", 315, 50, 73, 31, 0, true ); } //-------------------------------------------------------------------------------------- // Changes the UI defaults to the current device settings //-------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::Refresh() { g_DeviceSettings = DXUTGetDeviceSettings(); auto pD3DEnum = DXUTGetD3D11Enumeration(); // Fill the UI with the current settings AddD3D11DeviceType( g_DeviceSettings.d3d11.DriverType ); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_WINDOWED, true ); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_FULLSCREEN, (g_DeviceSettings.d3d11.DriverType != D3D_DRIVER_TYPE_WARP) ); SetWindowed( FALSE != g_DeviceSettings.d3d11.sd.Windowed ); auto pOutputInfo = GetCurrentD3D11OutputInfo(); AddD3D11AdapterOutput( pOutputInfo->Desc.DeviceName, g_DeviceSettings.d3d11.Output ); AddD3D11Resolution( g_DeviceSettings.d3d11.sd.BufferDesc.Width, g_DeviceSettings.d3d11.sd.BufferDesc.Height ); AddD3D11RefreshRate( g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate ); AddD3D11BackBufferFormat( g_DeviceSettings.d3d11.sd.BufferDesc.Format ); AddD3D11MultisampleCount( g_DeviceSettings.d3d11.sd.SampleDesc.Count ); AddD3D11MultisampleQuality( g_DeviceSettings.d3d11.sd.SampleDesc.Quality ); auto pBestDeviceSettingsCombo = pD3DEnum->GetDeviceSettingsCombo( g_DeviceSettings.d3d11.AdapterOrdinal, g_DeviceSettings.d3d11.sd.BufferDesc.Format, ( g_DeviceSettings.d3d11.sd.Windowed != 0 ) ); if( !pBestDeviceSettingsCombo ) return DXUT_ERR_MSGBOX( L"GetDeviceSettingsCombo", E_INVALIDARG ); CDXUTComboBox *pFeatureLevelBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL ); pFeatureLevelBox->RemoveAllItems(); D3D_FEATURE_LEVEL clampFL; if ( g_DeviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_WARP ) clampFL = DXUTGetD3D11Enumeration()->GetWARPFeaturevel(); else if ( g_DeviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE ) clampFL = DXUTGetD3D11Enumeration()->GetREFFeaturevel(); else clampFL = pBestDeviceSettingsCombo->pDeviceInfo->MaxLevel; for (int fli = 0; fli < TOTAL_FEATURE_LEVELS; fli++) { if (m_Levels[fli] >= g_DeviceSettings.MinimumFeatureLevel && m_Levels[fli] <= clampFL) { AddD3D11FeatureLevel( m_Levels[fli] ); } } pFeatureLevelBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.DeviceFeatureLevel ) ); // Get the adapters list from CD3D11Enumeration object auto pAdapterInfoList = pD3DEnum->GetAdapterInfoList(); if( pAdapterInfoList->empty() ) return DXUT_ERR_MSGBOX( L"CD3DSettingsDlg::OnCreatedDevice", DXUTERR_NOCOMPATIBLEDEVICES ); auto pAdapterCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); pAdapterCombo->RemoveAllItems(); // Add adapters for( auto it = pAdapterInfoList->cbegin(); it != pAdapterInfoList->cend(); ++it ) { AddAdapter( (*it)->szUniqueDescription, (*it)->AdapterOrdinal ); } pAdapterCombo->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.AdapterOrdinal ) ); // DXUTSETTINGSDLG_D3D11_RESOLUTION HRESULT hr = UpdateD3D11Resolutions(); if ( FAILED(hr) ) return hr; // DXUTSETTINGSDLG_D3D11_REFRESH_RATE hr = UpdateD3D11RefreshRates(); if ( FAILED(hr) ) return hr; // Windowed mode bool bWindowed = IsWindowed(); // Backbuffer Format/Driver Type auto pAdapterInfo = GetCurrentD3D11AdapterInfo(); if (pAdapterInfo) { auto pBackBufferFormatComboBox = m_Dialog.GetComboBox(DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT); pBackBufferFormatComboBox->RemoveAllItems(); for (size_t idc = 0; idc < pAdapterInfo->deviceSettingsComboList.size(); idc++) { auto pDeviceCombo = pAdapterInfo->deviceSettingsComboList[idc]; if ((pDeviceCombo->Windowed == TRUE) == bWindowed) { AddD3D11BackBufferFormat(pDeviceCombo->BackBufferFormat); } } pBackBufferFormatComboBox->SetSelectedByData( ULongToPtr(g_DeviceSettings.d3d11.sd.BufferDesc.Format) ); auto pDeviceTypeComboBox = m_Dialog.GetComboBox(DXUTSETTINGSDLG_DEVICE_TYPE); pDeviceTypeComboBox->RemoveAllItems(); for (size_t iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.size(); iDeviceInfo++) { auto pDeviceInfo = pAdapterInfo->deviceInfoList[iDeviceInfo]; AddD3D11DeviceType(pDeviceInfo->DeviceType); } pDeviceTypeComboBox->SetSelectedByData( ULongToPtr(g_DeviceSettings.d3d11.DriverType) ); } // MSAA settings auto pDeviceSettingsCombo = GetCurrentD3D11DeviceSettingsCombo(); if ( pDeviceSettingsCombo ) { auto pMultisampleCountCombo = m_Dialog.GetComboBox(DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT); pMultisampleCountCombo->RemoveAllItems(); for (auto it = pDeviceSettingsCombo->multiSampleCountList.cbegin(); it != pDeviceSettingsCombo->multiSampleCountList.cend(); ++it) AddD3D11MultisampleCount(*it); pMultisampleCountCombo->SetSelectedByData( ULongToPtr(g_DeviceSettings.d3d11.sd.SampleDesc.Count) ); UINT MaxQuality = 0; for (size_t iCount = 0; iCount < pDeviceSettingsCombo->multiSampleCountList.size(); iCount++) { UINT Count = pDeviceSettingsCombo->multiSampleCountList[iCount]; if ( Count == g_DeviceSettings.d3d11.sd.SampleDesc.Count ) { MaxQuality = pDeviceSettingsCombo->multiSampleQualityList[iCount]; break; } } auto pMultisampleQualityCombo = m_Dialog.GetComboBox(DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY); pMultisampleQualityCombo->RemoveAllItems(); for (UINT iQuality = 0; iQuality < MaxQuality; iQuality++) { AddD3D11MultisampleQuality(iQuality); } pMultisampleQualityCombo->SetSelectedByData(ULongToPtr(g_DeviceSettings.d3d11.sd.SampleDesc.Quality)); } // Misc settings auto pDebugCheckBox = m_Dialog.GetCheckBox(DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE); if ( pDebugCheckBox ) { pDebugCheckBox->SetChecked(0 != (g_DeviceSettings.d3d11.CreateFlags & D3D11_CREATE_DEVICE_DEBUG)); } auto pPresentIntervalComboBox = m_Dialog.GetComboBox(DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL); if ( pPresentIntervalComboBox ) { pPresentIntervalComboBox->SetSelectedByData(ULongToPtr(g_DeviceSettings.d3d11.SyncInterval) ); } CDXUTDialog::SetRefreshTime( ( float )DXUTGetTime() ); return S_OK; } //-------------------------------------------------------------------------------------- void CD3DSettingsDlg::SetSelectedD3D11RefreshRate( _In_ DXGI_RATIONAL RefreshRate ) { auto pRefreshRateComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); for( UINT i = 0; i < pRefreshRateComboBox->GetNumItems(); ++i ) { auto pRate = reinterpret_cast( pRefreshRateComboBox->GetItemData( i ) ); if( pRate && pRate->Numerator == RefreshRate.Numerator && pRate->Denominator == RefreshRate.Denominator ) { pRefreshRateComboBox->SetSelectedByIndex( i ); return; } } } //-------------------------------------------------------------------------------------- void CD3DSettingsDlg::OnRender( _In_ float fElapsedTime ) { // Render the scene m_pActiveDialog->OnRender( fElapsedTime ); } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ LRESULT CD3DSettingsDlg::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { m_pActiveDialog->MsgProc( hWnd, uMsg, wParam, lParam ); if( uMsg == WM_KEYDOWN && wParam == VK_F2 ) SetActive( false ); return 0; } //-------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnD3D11CreateDevice( _In_ ID3D11Device* pd3dDevice ) { if( !pd3dDevice ) return DXUT_ERR_MSGBOX( L"CD3DSettingsDlg::OnCreatedDevice", E_INVALIDARG ); // Create the fonts/textures m_Dialog.SetCallback( StaticOnEvent, ( void* )this ); m_RevertModeDialog.SetCallback( StaticOnEvent, ( void* )this ); return S_OK; } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT CD3DSettingsDlg::OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc ) { UNREFERENCED_PARAMETER(pd3dDevice); m_Dialog.SetLocation( 0, 0 ); m_Dialog.SetSize( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); m_Dialog.SetBackgroundColors( D3DCOLOR_ARGB( 255, 98, 138, 206 ), D3DCOLOR_ARGB( 255, 54, 105, 192 ), D3DCOLOR_ARGB( 255, 54, 105, 192 ), D3DCOLOR_ARGB( 255, 10, 73, 179 ) ); m_RevertModeDialog.SetLocation( 0, 0 ); m_RevertModeDialog.SetSize( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); m_RevertModeDialog.SetBackgroundColors( D3DCOLOR_ARGB( 255, 98, 138, 206 ), D3DCOLOR_ARGB( 255, 54, 105, 192 ), D3DCOLOR_ARGB( 255, 54, 105, 192 ), D3DCOLOR_ARGB( 255, 10, 73, 179 ) ); return S_OK; } //-------------------------------------------------------------------------------------- void CD3DSettingsDlg::OnD3D11DestroyDevice() { } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ void WINAPI CD3DSettingsDlg::StaticOnEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserData ) { auto pD3DSettings = reinterpret_cast( pUserData ); if( pD3DSettings ) pD3DSettings->OnEvent( nEvent, nControlID, pControl ); } //-------------------------------------------------------------------------------------- // Name: CD3DSettingsDlg::StaticOnModeChangeTimer() // Desc: Timer callback registered by a call to DXUTSetTimer. It is called each second // until mode change timeout limit. //-------------------------------------------------------------------------------------- _Use_decl_annotations_ void WINAPI CD3DSettingsDlg::StaticOnModeChangeTimer( UINT nIDEvent, void* pUserContext ) { UNREFERENCED_PARAMETER(nIDEvent); auto pD3DSettings = reinterpret_cast( pUserContext ); assert( pD3DSettings ); _Analysis_assume_( pD3DSettings ); assert( pD3DSettings->m_pActiveDialog == &pD3DSettings->m_RevertModeDialog ); assert( pD3DSettings->m_nIDEvent == nIDEvent ); if( 0 == --pD3DSettings->m_nRevertModeTimeout ) { auto pControl = pD3DSettings->m_RevertModeDialog.GetControl( DXUTSETTINGSDLG_MODE_CHANGE_REVERT ); assert( pControl ); _Analysis_assume_( pControl ); pD3DSettings->m_RevertModeDialog.SendEvent( EVENT_BUTTON_CLICKED, false, pControl ); } pD3DSettings->UpdateModeChangeTimeoutText( pD3DSettings->m_nRevertModeTimeout ); } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ void CD3DSettingsDlg::OnEvent( UINT nEvent, int nControlID, CDXUTControl* pControl ) { UNREFERENCED_PARAMETER(nEvent); UNREFERENCED_PARAMETER(pControl); switch( nControlID ) { case DXUTSETTINGSDLG_ADAPTER: OnAdapterChanged(); break; case DXUTSETTINGSDLG_DEVICE_TYPE: OnDeviceTypeChanged(); break; case DXUTSETTINGSDLG_WINDOWED: OnWindowedFullScreenChanged(); break; case DXUTSETTINGSDLG_FULLSCREEN: OnWindowedFullScreenChanged(); break; case DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL: OnBackBufferFormatChanged(); break; case DXUTSETTINGSDLG_D3D11_RESOLUTION: OnD3D11ResolutionChanged(); break; case DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL: OnFeatureLevelChanged(); break; case DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT: OnAdapterOutputChanged(); break; case DXUTSETTINGSDLG_D3D11_REFRESH_RATE: OnRefreshRateChanged(); break; case DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT: OnBackBufferFormatChanged(); break; case DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT: OnMultisampleTypeChanged(); break; case DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY: OnMultisampleQualityChanged(); break; case DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL: OnPresentIntervalChanged(); break; case DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE: OnDebugDeviceChanged(); break; case DXUTSETTINGSDLG_OK: { bool bFullScreenModeChange = false; auto currentSettings = DXUTGetDeviceSettings(); g_DeviceSettings.MinimumFeatureLevel = currentSettings.MinimumFeatureLevel; if( g_DeviceSettings.d3d11.sd.Windowed ) { g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator = g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator = 0; RECT rcClient; if( DXUTIsWindowed() ) GetClientRect( DXUTGetHWND(), &rcClient ); else rcClient = DXUTGetWindowClientRectAtModeChange(); DWORD dwWindowWidth = rcClient.right - rcClient.left; DWORD dwWindowHeight = rcClient.bottom - rcClient.top; g_DeviceSettings.d3d11.sd.BufferDesc.Width = dwWindowWidth; g_DeviceSettings.d3d11.sd.BufferDesc.Height = dwWindowHeight; } else { // Check for fullscreen mode change bFullScreenModeChange = g_DeviceSettings.d3d11.sd.BufferDesc.Width != currentSettings.d3d11.sd.BufferDesc.Width || g_DeviceSettings.d3d11.sd.BufferDesc.Height != currentSettings.d3d11.sd.BufferDesc.Height || g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator != currentSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator || g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator != currentSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator; } if( bFullScreenModeChange ) { // set appropriate global device settings to that of the current device // settings. These will get set to the user-defined settings once the // user accepts the mode change DXUTDeviceSettings tSettings = g_DeviceSettings; g_DeviceSettings.d3d11.sd.BufferDesc.Width = currentSettings.d3d11.sd.BufferDesc.Width; g_DeviceSettings.d3d11.sd.BufferDesc.Height = currentSettings.d3d11.sd.BufferDesc.Height; g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator = currentSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator; g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator = currentSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator; g_DeviceSettings.d3d11.sd.Windowed = currentSettings.d3d11.sd.Windowed; // apply the user-defined settings DXUTCreateDeviceFromSettings( &tSettings ); // create the mode change timeout dialog m_pActiveDialog = &m_RevertModeDialog; m_nRevertModeTimeout = 15; UpdateModeChangeTimeoutText( m_nRevertModeTimeout ); // activate a timer for 1-second updates DXUTSetTimer( StaticOnModeChangeTimer, 1.0f, &m_nIDEvent, ( void* )this ); } else { DXUTCreateDeviceFromSettings( &g_DeviceSettings ); SetActive( false ); } break; } case DXUTSETTINGSDLG_CANCEL: { SetActive( false ); break; } case DXUTSETTINGSDLG_MODE_CHANGE_ACCEPT: { DXUTKillTimer( m_nIDEvent ); g_DeviceSettings = DXUTGetDeviceSettings(); m_pActiveDialog = &m_Dialog; SetActive( false ); break; } case DXUTSETTINGSDLG_MODE_CHANGE_REVERT: { DXUTKillTimer( m_nIDEvent ); m_pActiveDialog = &m_Dialog; m_nIDEvent = 0; m_nRevertModeTimeout = 0; DXUTCreateDeviceFromSettings( &g_DeviceSettings ); Refresh(); break; } } } //------------------------------------------------------------------------------------- CD3D11EnumAdapterInfo* CD3DSettingsDlg::GetCurrentD3D11AdapterInfo() const { auto pD3DEnum = DXUTGetD3D11Enumeration(); return pD3DEnum->GetAdapterInfo( g_DeviceSettings.d3d11.AdapterOrdinal ); } //------------------------------------------------------------------------------------- CD3D11EnumDeviceInfo* CD3DSettingsDlg::GetCurrentD3D11DeviceInfo() const { auto pD3DEnum = DXUTGetD3D11Enumeration(); return pD3DEnum->GetDeviceInfo( g_DeviceSettings.d3d11.AdapterOrdinal, g_DeviceSettings.d3d11.DriverType ); } //------------------------------------------------------------------------------------- CD3D11EnumOutputInfo* CD3DSettingsDlg::GetCurrentD3D11OutputInfo() const { auto pD3DEnum = DXUTGetD3D11Enumeration(); return pD3DEnum->GetOutputInfo( g_DeviceSettings.d3d11.AdapterOrdinal, g_DeviceSettings.d3d11.Output ); } //------------------------------------------------------------------------------------- CD3D11EnumDeviceSettingsCombo* CD3DSettingsDlg::GetCurrentD3D11DeviceSettingsCombo() const { auto pD3DEnum = DXUTGetD3D11Enumeration(); return pD3DEnum->GetDeviceSettingsCombo( g_DeviceSettings.d3d11.AdapterOrdinal, g_DeviceSettings.d3d11.sd.BufferDesc.Format, ( g_DeviceSettings.d3d11.sd.Windowed == TRUE ) ); } HRESULT CD3DSettingsDlg::OnD3D11ResolutionChanged () { if ( g_DeviceSettings.d3d11.sd.Windowed ) return S_OK; DWORD dwWidth, dwHeight; GetSelectedD3D11Resolution( &dwWidth, &dwHeight ); g_DeviceSettings.d3d11.sd.BufferDesc.Width = dwWidth; g_DeviceSettings.d3d11.sd.BufferDesc.Height = dwHeight; // DXUTSETTINGSDLG_D3D11_REFRESH_RATE HRESULT hr = UpdateD3D11RefreshRates(); if ( FAILED(hr) ) return hr; return S_OK; } HRESULT CD3DSettingsDlg::OnFeatureLevelChanged () { HRESULT hr = E_FAIL; if (g_DeviceSettings.d3d11.DeviceFeatureLevel == GetSelectedFeatureLevel()) return S_OK; // Obtain a set of valid D3D11 device settings. UINT CreateFlags = g_DeviceSettings.d3d11.CreateFlags; DXGI_FORMAT BackBufferFormat = g_DeviceSettings.d3d11.sd.BufferDesc.Format; UINT Count = g_DeviceSettings.d3d11.sd.SampleDesc.Count; UINT Quality = g_DeviceSettings.d3d11.sd.SampleDesc.Quality; DXGI_RATIONAL RefreshRate = g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate; ZeroMemory(&g_DeviceSettings, sizeof(g_DeviceSettings)); DXUTApplyDefaultDeviceSettings(&g_DeviceSettings); g_DeviceSettings.d3d11.CreateFlags = CreateFlags; hr = DXUTSnapDeviceSettingsToEnumDevice(&g_DeviceSettings, true, GetSelectedFeatureLevel()); g_DeviceSettings.d3d11.sd.BufferDesc.Format = BackBufferFormat; g_DeviceSettings.d3d11.sd.SampleDesc.Count = Count; g_DeviceSettings.d3d11.sd.SampleDesc.Quality = Quality; g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate = RefreshRate; auto pD3DEnum = DXUTGetD3D11Enumeration(); auto pAdapterInfoList = pD3DEnum->GetAdapterInfoList(); // DXUTSETTINGSDLG_ADAPTER auto pAdapterComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); pAdapterComboBox->RemoveAllItems(); for( auto it = pAdapterInfoList->cbegin(); it != pAdapterInfoList->cend(); ++it ) { AddAdapter( (*it)->szUniqueDescription, (*it)->AdapterOrdinal ); } pAdapterComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.AdapterOrdinal ) ); // DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT auto pBackBufferFormatComboBox = m_Dialog.GetComboBox(DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT); pBackBufferFormatComboBox->RemoveAllItems(); auto pAdapterInfo = GetCurrentD3D11AdapterInfo(); if (!pAdapterInfo) return E_FAIL; bool bWindowed = IsWindowed(); for (size_t idc = 0; idc < pAdapterInfo->deviceSettingsComboList.size(); idc++) { auto pDeviceCombo = pAdapterInfo->deviceSettingsComboList[idc]; if ((pDeviceCombo->Windowed == TRUE) == bWindowed) { AddD3D11BackBufferFormat(pDeviceCombo->BackBufferFormat); } } pBackBufferFormatComboBox->SetSelectedByData( ULongToPtr(g_DeviceSettings.d3d11.sd.BufferDesc.Format) ); hr = OnBackBufferFormatChanged(); if (FAILED(hr)) return hr; auto pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE ); pCheckBox->SetChecked( 0 != ( g_DeviceSettings.d3d11.CreateFlags & D3D11_CREATE_DEVICE_DEBUG ) ); hr = OnAdapterChanged(); if( FAILED( hr ) ) return hr; return hr; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnAdapterChanged() { // Store the adapter index g_DeviceSettings.d3d11.AdapterOrdinal = GetSelectedAdapter(); // DXUTSETTINGSDLG_DEVICE_TYPE auto pDeviceTypeComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); pDeviceTypeComboBox->RemoveAllItems(); auto pAdapterInfo = GetCurrentD3D11AdapterInfo(); if( !pAdapterInfo ) return E_FAIL; for( size_t iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.size(); iDeviceInfo++ ) { auto pDeviceInfo = pAdapterInfo->deviceInfoList[ iDeviceInfo ]; AddD3D11DeviceType( pDeviceInfo->DeviceType ); } pDeviceTypeComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.DriverType ) ); HRESULT hr = OnDeviceTypeChanged(); if( FAILED( hr ) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnDeviceTypeChanged() { HRESULT hr = S_OK; g_DeviceSettings.d3d11.DriverType = GetSelectedD3D11DeviceType(); // DXUTSETTINGSDLG_WINDOWED, DXUTSETTINGSDLG_FULLSCREEN m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_WINDOWED, true ); if (g_DeviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_WARP ) { m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_FULLSCREEN, false ); g_DeviceSettings.d3d11.sd.Windowed = TRUE; } else { m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_FULLSCREEN, true ); } SetWindowed( g_DeviceSettings.d3d11.sd.Windowed != 0 ); auto pBestDeviceSettingsCombo = DXUTGetD3D11Enumeration()->GetDeviceSettingsCombo( g_DeviceSettings.d3d11.AdapterOrdinal, g_DeviceSettings.d3d11.sd.BufferDesc.Format, ( g_DeviceSettings.d3d11.sd.Windowed != 0 ) ); if( !pBestDeviceSettingsCombo ) return DXUT_ERR_MSGBOX( L"GetDeviceSettingsCombo", E_INVALIDARG ); D3D_FEATURE_LEVEL clampFL; if ( g_DeviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_WARP ) clampFL = DXUTGetD3D11Enumeration()->GetWARPFeaturevel(); else if ( g_DeviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE ) clampFL = DXUTGetD3D11Enumeration()->GetREFFeaturevel(); else clampFL = pBestDeviceSettingsCombo->pDeviceInfo->MaxLevel; if ( g_DeviceSettings.d3d11.DeviceFeatureLevel > clampFL || clampFL > pBestDeviceSettingsCombo->pDeviceInfo->MaxLevel ) { g_DeviceSettings.d3d11.DeviceFeatureLevel = std::min( g_DeviceSettings.d3d11.DeviceFeatureLevel, clampFL ); CDXUTComboBox *pFeatureLevelBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL ); pFeatureLevelBox->RemoveAllItems(); for (int fli = 0; fli < TOTAL_FEATURE_LEVELS; fli++) { if (m_Levels[fli] >= g_DeviceSettings.MinimumFeatureLevel && m_Levels[fli] <= clampFL) { AddD3D11FeatureLevel( m_Levels[fli] ); } } pFeatureLevelBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.DeviceFeatureLevel ) ); hr = OnFeatureLevelChanged(); if( FAILED( hr ) ) return hr; } hr = OnWindowedFullScreenChanged(); if( FAILED( hr ) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnWindowedFullScreenChanged() { HRESULT hr = S_OK; bool bWindowed = IsWindowed(); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL, !bWindowed ); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL, !bWindowed ); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL, !bWindowed ); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL, !bWindowed ); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT, !bWindowed ); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_RESOLUTION, !bWindowed ); m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_REFRESH_RATE, !bWindowed ); g_DeviceSettings.d3d11.sd.Windowed = bWindowed; // Get available adapter output auto pD3DEnum = DXUTGetD3D11Enumeration(); auto pOutputComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT ); pOutputComboBox->RemoveAllItems(); auto pAdapterInfo = pD3DEnum->GetAdapterInfo( g_DeviceSettings.d3d11.AdapterOrdinal ); for( size_t ioutput = 0; ioutput < pAdapterInfo->outputInfoList.size(); ++ioutput ) { auto pOutputInfo = pAdapterInfo->outputInfoList[ ioutput ]; AddD3D11AdapterOutput( pOutputInfo->Desc.DeviceName, pOutputInfo->Output ); } pOutputComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.Output ) ); hr = OnAdapterOutputChanged(); if( FAILED( hr ) ) return hr; hr = UpdateD3D11Resolutions(); if (FAILED(hr)) return hr; hr = UpdateD3D11RefreshRates(); if ( FAILED(hr) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnAdapterOutputChanged() { HRESULT hr; bool bWindowed = IsWindowed(); g_DeviceSettings.d3d11.sd.Windowed = bWindowed; // If windowed, get the appropriate adapter format from Direct3D if( g_DeviceSettings.d3d11.sd.Windowed ) { DXGI_MODE_DESC mode; hr = DXUTGetD3D11AdapterDisplayMode( g_DeviceSettings.d3d11.AdapterOrdinal, g_DeviceSettings.d3d11.Output, &mode ); if( FAILED( hr ) ) return DXTRACE_ERR( L"GetD3D11AdapterDisplayMode", hr ); // Default resolution to the fullscreen res that was last used RECT rc = DXUTGetFullsceenClientRectAtModeChange(); if( rc.right == 0 || rc.bottom == 0 ) { // If nothing last used, then default to the adapter desktop res g_DeviceSettings.d3d11.sd.BufferDesc.Width = mode.Width; g_DeviceSettings.d3d11.sd.BufferDesc.Height = mode.Height; } else { g_DeviceSettings.d3d11.sd.BufferDesc.Width = rc.right; g_DeviceSettings.d3d11.sd.BufferDesc.Height = rc.bottom; } g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator = g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator = 0; } auto pAdapterInfo = GetCurrentD3D11AdapterInfo(); if( !pAdapterInfo ) return E_FAIL; // DXUTSETTINGSDLG_D3D11_RESOLUTION hr = UpdateD3D11Resolutions(); if( FAILED( hr ) ) return hr; // DXUTSETTINGSDLG_D3D11_REFRESH_RATE hr = UpdateD3D11RefreshRates(); if ( FAILED(hr) ) return hr; // DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT auto pBackBufferFormatComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT ); pBackBufferFormatComboBox->RemoveAllItems(); for( size_t idc = 0; idc < pAdapterInfo->deviceSettingsComboList.size(); idc++ ) { auto pDeviceCombo = pAdapterInfo->deviceSettingsComboList[ idc ]; if( ( pDeviceCombo->Windowed == TRUE ) == bWindowed ) { AddD3D11BackBufferFormat( pDeviceCombo->BackBufferFormat ); } } pBackBufferFormatComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.sd.BufferDesc.Format ) ); hr = OnBackBufferFormatChanged(); if( FAILED( hr ) ) return hr; hr = OnRefreshRateChanged(); if( FAILED( hr ) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnRefreshRateChanged() { // Set refresh rate g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate = GetSelectedD3D11RefreshRate(); return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnBackBufferFormatChanged() { HRESULT hr = S_OK; g_DeviceSettings.d3d11.sd.BufferDesc.Format = GetSelectedD3D11BackBufferFormat(); DXGI_FORMAT backBufferFormat = g_DeviceSettings.d3d11.sd.BufferDesc.Format; auto pAdapterInfo = GetCurrentD3D11AdapterInfo(); if( !pAdapterInfo ) return E_FAIL; for( size_t idc = 0; idc < pAdapterInfo->deviceSettingsComboList.size(); idc++ ) { auto pDeviceCombo = pAdapterInfo->deviceSettingsComboList[ idc ]; if( pDeviceCombo->Windowed == ( g_DeviceSettings.d3d11.sd.Windowed == TRUE ) && pDeviceCombo->BackBufferFormat == backBufferFormat && pDeviceCombo->DeviceType == g_DeviceSettings.d3d11.DriverType ) { auto pMultisampleCountCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT ); pMultisampleCountCombo->RemoveAllItems(); for( auto it = pDeviceCombo->multiSampleCountList.cbegin(); it != pDeviceCombo->multiSampleCountList.cend(); ++it ) AddD3D11MultisampleCount( *it ); pMultisampleCountCombo->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.sd.SampleDesc.Count ) ); hr = OnMultisampleTypeChanged(); if( FAILED( hr ) ) return hr; auto pPresentIntervalComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL ); pPresentIntervalComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.SyncInterval ) ); hr = OnPresentIntervalChanged(); if( FAILED( hr ) ) return hr; hr = UpdateD3D11Resolutions(); if( FAILED( hr ) ) return hr; hr = UpdateD3D11RefreshRates(); if ( FAILED(hr) ) return hr; break; } } return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnMultisampleTypeChanged() { HRESULT hr = S_OK; UINT multisampleCount = GetSelectedD3D11MultisampleCount(); g_DeviceSettings.d3d11.sd.SampleDesc.Count = multisampleCount; auto pDeviceSettingsCombo = GetCurrentD3D11DeviceSettingsCombo(); if( !pDeviceSettingsCombo ) return E_FAIL; UINT MaxQuality = 0; for( size_t iCount = 0; iCount < pDeviceSettingsCombo->multiSampleCountList.size(); iCount++ ) { UINT Count = pDeviceSettingsCombo->multiSampleCountList[ iCount ]; if( Count == multisampleCount ) { MaxQuality = pDeviceSettingsCombo->multiSampleQualityList[ iCount ]; break; } } // DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY auto pMultisampleQualityCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY ); pMultisampleQualityCombo->RemoveAllItems(); for( UINT iQuality = 0; iQuality < MaxQuality; iQuality++ ) { AddD3D11MultisampleQuality( iQuality ); } pMultisampleQualityCombo->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.sd.SampleDesc.Quality ) ); hr = OnMultisampleQualityChanged(); if( FAILED( hr ) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnMultisampleQualityChanged() { g_DeviceSettings.d3d11.sd.SampleDesc.Quality = GetSelectedD3D11MultisampleQuality(); return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnPresentIntervalChanged() { g_DeviceSettings.d3d11.SyncInterval = GetSelectedD3D11PresentInterval(); return S_OK; } //------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::OnDebugDeviceChanged() { bool bDebugDevice = GetSelectedDebugDeviceValue(); if( bDebugDevice ) g_DeviceSettings.d3d11.CreateFlags |= D3D11_CREATE_DEVICE_DEBUG; else g_DeviceSettings.d3d11.CreateFlags &= ~D3D11_CREATE_DEVICE_DEBUG; return S_OK; } //------------------------------------------------------------------------------------- void CD3DSettingsDlg::AddAdapter( _In_z_ const WCHAR* strDescription, _In_ UINT iAdapter ) { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); if( !pComboBox->ContainsItem( strDescription ) ) pComboBox->AddItem( strDescription, ULongToPtr( iAdapter ) ); } //------------------------------------------------------------------------------------- UINT CD3DSettingsDlg::GetSelectedAdapter() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); return PtrToUlong( pComboBox->GetSelectedData() ); } //------------------------------------------------------------------------------------- void CD3DSettingsDlg::SetWindowed( _In_ bool bWindowed ) { auto pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED ); pRadioButton->SetChecked( bWindowed ); pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_FULLSCREEN ); pRadioButton->SetChecked( !bWindowed ); m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL, !bWindowed); m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL, !bWindowed); m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL, !bWindowed); m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL, !bWindowed); m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT, !bWindowed); m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_D3D11_RESOLUTION, !bWindowed); m_Dialog.SetControlEnabled(DXUTSETTINGSDLG_D3D11_REFRESH_RATE, !bWindowed); } //------------------------------------------------------------------------------------- bool CD3DSettingsDlg::IsWindowed() const { auto pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED ); return pRadioButton->GetChecked(); } //------------------------------------------------------------------------------------- void CD3DSettingsDlg::AddD3D11AdapterOutput( _In_z_ const WCHAR* strName, _In_ UINT Output ) { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT ); if( !pComboBox->ContainsItem( strName ) ) pComboBox->AddItem( strName, ULongToPtr( Output ) ); } //------------------------------------------------------------------------------------- UINT CD3DSettingsDlg::GetSelectedD3D11AdapterOutput() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT ); return PtrToUlong( pComboBox->GetSelectedData() ); } //------------------------------------------------------------------------------------- _Use_decl_annotations_ void CD3DSettingsDlg::AddD3D11Resolution( DWORD dwWidth, DWORD dwHeight ) { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION ); DWORD dwResolutionData; WCHAR strResolution[50]; dwResolutionData = MAKELONG( dwWidth, dwHeight ); swprintf_s( strResolution, 50, L"%u by %u", dwWidth, dwHeight ); if( !pComboBox->ContainsItem( strResolution ) ) pComboBox->AddItem( strResolution, ULongToPtr( dwResolutionData ) ); } //------------------------------------------------------------------------------------- _Use_decl_annotations_ void CD3DSettingsDlg::GetSelectedD3D11Resolution( DWORD* pdwWidth, DWORD* pdwHeight ) const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION ); DWORD dwResolution = PtrToUlong( pComboBox->GetSelectedData() ); *pdwWidth = LOWORD( dwResolution ); *pdwHeight = HIWORD( dwResolution ); } //------------------------------------------------------------------------------------- void CD3DSettingsDlg::AddD3D11FeatureLevel( _In_ D3D_FEATURE_LEVEL fl) { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL ); switch( fl ) { case D3D_FEATURE_LEVEL_9_1: { if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_9_1" ) ) pComboBox->AddItem( L"D3D_FEATURE_LEVEL_9_1", ULongToPtr( D3D_FEATURE_LEVEL_9_1 ) ); } break; case D3D_FEATURE_LEVEL_9_2: { if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_9_2" ) ) pComboBox->AddItem( L"D3D_FEATURE_LEVEL_9_2", ULongToPtr( D3D_FEATURE_LEVEL_9_2 ) ); } break; case D3D_FEATURE_LEVEL_9_3: { if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_9_3" ) ) pComboBox->AddItem( L"D3D_FEATURE_LEVEL_9_3", ULongToPtr( D3D_FEATURE_LEVEL_9_3 ) ); } break; case D3D_FEATURE_LEVEL_10_0: { if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_10_0" ) ) pComboBox->AddItem( L"D3D_FEATURE_LEVEL_10_0", ULongToPtr( D3D_FEATURE_LEVEL_10_0 ) ); } break; case D3D_FEATURE_LEVEL_10_1: { if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_10_1" ) ) pComboBox->AddItem( L"D3D_FEATURE_LEVEL_10_1", ULongToPtr( D3D_FEATURE_LEVEL_10_1 ) ); } break; case D3D_FEATURE_LEVEL_11_0: { if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_11_0" ) ) pComboBox->AddItem( L"D3D_FEATURE_LEVEL_11_0", ULongToPtr( D3D_FEATURE_LEVEL_11_0 ) ); } break; case D3D_FEATURE_LEVEL_11_1: { if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_11_1" ) ) pComboBox->AddItem( L"D3D_FEATURE_LEVEL_11_1", ULongToPtr( D3D_FEATURE_LEVEL_11_1 ) ); } break; #ifdef USE_DIRECT3D11_3 case D3D_FEATURE_LEVEL_12_0: { if (!pComboBox->ContainsItem(L"D3D_FEATURE_LEVEL_12_0")) pComboBox->AddItem(L"D3D_FEATURE_LEVEL_12_0", ULongToPtr(D3D_FEATURE_LEVEL_12_0)); } break; case D3D_FEATURE_LEVEL_12_1: { if (!pComboBox->ContainsItem(L"D3D_FEATURE_LEVEL_12_1")) pComboBox->AddItem(L"D3D_FEATURE_LEVEL_12_1", ULongToPtr(D3D_FEATURE_LEVEL_12_1)); } break; #endif } } D3D_FEATURE_LEVEL CD3DSettingsDlg::GetSelectedFeatureLevel() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL ); return (D3D_FEATURE_LEVEL)PtrToUlong( pComboBox->GetSelectedData() ); } //------------------------------------------------------------------------------------- void CD3DSettingsDlg::AddD3D11RefreshRate( _In_ DXGI_RATIONAL RefreshRate ) { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); WCHAR strRefreshRate[50]; if( RefreshRate.Numerator == 0 && RefreshRate.Denominator == 0 ) wcscpy_s( strRefreshRate, 50, L"Default Rate" ); else swprintf_s( strRefreshRate, 50, L"%u Hz", RefreshRate.Numerator / RefreshRate.Denominator ); if( !pComboBox->ContainsItem( strRefreshRate ) ) { auto pNewRate = new (std::nothrow) DXGI_RATIONAL; if( pNewRate ) { *pNewRate = RefreshRate; pComboBox->AddItem( strRefreshRate, pNewRate ); } } } //------------------------------------------------------------------------------------- DXGI_RATIONAL CD3DSettingsDlg::GetSelectedD3D11RefreshRate() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); return *reinterpret_cast( pComboBox->GetSelectedData() ); } //------------------------------------------------------------------------------------- void CD3DSettingsDlg::AddD3D11BackBufferFormat( _In_ DXGI_FORMAT format ) { if ( g_DeviceSettings.d3d11.DeviceFeatureLevel < D3D_FEATURE_LEVEL_10_0 ) { if ( (format == DXGI_FORMAT_R16G16B16A16_FLOAT) || (format == DXGI_FORMAT_R10G10B10A2_UNORM) ) return; } auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT ); if( !pComboBox->ContainsItem( DXUTDXGIFormatToString( format, TRUE ) ) ) pComboBox->AddItem( DXUTDXGIFormatToString( format, TRUE ), ULongToPtr( format ) ); } //------------------------------------------------------------------------------------- DXGI_FORMAT CD3DSettingsDlg::GetSelectedD3D11BackBufferFormat() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT ); return ( DXGI_FORMAT )PtrToUlong( pComboBox->GetSelectedData() ); } //------------------------------------------------------------------------------------- void CD3DSettingsDlg::AddD3D11MultisampleCount( _In_ UINT Count ) { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT ); WCHAR str[50]; swprintf_s( str, 50, L"%u", Count ); if( !pComboBox->ContainsItem( str ) ) pComboBox->AddItem( str, ULongToPtr( Count ) ); } //------------------------------------------------------------------------------------- UINT CD3DSettingsDlg::GetSelectedD3D11MultisampleCount() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT ); return ( UINT )PtrToUlong( pComboBox->GetSelectedData() ); } //------------------------------------------------------------------------------------- void CD3DSettingsDlg::AddD3D11MultisampleQuality( _In_ UINT Quality ) { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY ); WCHAR strQuality[50]; swprintf_s( strQuality, 50, L"%u", Quality ); if( !pComboBox->ContainsItem( strQuality ) ) pComboBox->AddItem( strQuality, ULongToPtr( Quality ) ); } //------------------------------------------------------------------------------------- UINT CD3DSettingsDlg::GetSelectedD3D11MultisampleQuality() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY ); return ( UINT )PtrToUlong( pComboBox->GetSelectedData() ); } //------------------------------------------------------------------------------------- DWORD CD3DSettingsDlg::GetSelectedD3D11PresentInterval() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL ); return PtrToUlong( pComboBox->GetSelectedData() ); } //------------------------------------------------------------------------------------- bool CD3DSettingsDlg::GetSelectedDebugDeviceValue() const { auto pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE ); return pCheckBox->GetChecked(); } //-------------------------------------------------------------------------------------- // Updates the resolution list for D3D11 //-------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::UpdateD3D11Resolutions() { const DWORD dwWidth = g_DeviceSettings.d3d11.sd.BufferDesc.Width; const DWORD dwHeight = g_DeviceSettings.d3d11.sd.BufferDesc.Height; // DXUTSETTINGSDLG_D3D11_RESOLUTION auto pResolutionComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION ); pResolutionComboBox->RemoveAllItems(); auto pOutputInfo = GetCurrentD3D11OutputInfo(); if( !pOutputInfo ) return E_FAIL; bool bWindowed = IsWindowed(); if ( !bWindowed ) { auto pShowAllCB = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL ); bool bShowAll = pShowAllCB->GetChecked(); // Get the desktop aspect ratio DXGI_MODE_DESC dmDesktop; DXUTGetDesktopResolution(g_DeviceSettings.d3d11.AdapterOrdinal, &dmDesktop.Width, &dmDesktop.Height); float fDesktopAspectRatio = dmDesktop.Width / (float) dmDesktop.Height; if ( !bShowAll && !DXUTIsWindowed() ) { float fAspect = (float) dwWidth / (float) dwHeight; if ( fabsf(fDesktopAspectRatio - fAspect) >= 0.05f ) { // Our current fullscren resolution should be listed in the combo box despite the aspect ratio pShowAllCB->SetChecked(true); bShowAll = true; } } for (size_t idm = 0; idm < pOutputInfo->displayModeList.size(); idm++) { auto DisplayMode = pOutputInfo->displayModeList[idm]; float fAspect = (float) DisplayMode.Width / (float) DisplayMode.Height; if (DisplayMode.Format == g_DeviceSettings.d3d11.sd.BufferDesc.Format) { // If "Show All" is not checked, then hide all resolutions // that don't match the aspect ratio of the desktop resolution if (bShowAll || (!bShowAll && fabsf(fDesktopAspectRatio - fAspect) < 0.05f)) { AddD3D11Resolution(DisplayMode.Width, DisplayMode.Height); } } } } else { pResolutionComboBox->RemoveAllItems(); AddD3D11Resolution( dwWidth, dwHeight ); } pResolutionComboBox->SetSelectedByData(ULongToPtr(MAKELONG(dwWidth, dwHeight))); OnD3D11ResolutionChanged(); return S_OK; } //-------------------------------------------------------------------------------------- // Updates the refresh list for D3D11 //-------------------------------------------------------------------------------------- HRESULT CD3DSettingsDlg::UpdateD3D11RefreshRates() { const DWORD dwWidth = g_DeviceSettings.d3d11.sd.BufferDesc.Width; const DWORD dwHeight = g_DeviceSettings.d3d11.sd.BufferDesc.Height; DXGI_FORMAT backBuffer = g_DeviceSettings.d3d11.sd.BufferDesc.Format; const DXGI_RATIONAL RefreshRate = g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate; auto pRefreshRateComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); for( UINT i = 0; i < pRefreshRateComboBox->GetNumItems(); ++i ) { auto pRefreshRate = reinterpret_cast( pRefreshRateComboBox->GetItemData( i ) ); delete pRefreshRate; } pRefreshRateComboBox->RemoveAllItems(); bool bWindowed = IsWindowed(); if( bWindowed ) { DXGI_RATIONAL def; def.Denominator = def.Numerator = 0; AddD3D11RefreshRate(def); } else { auto pD3DEnum = DXUTGetD3D11Enumeration(); if ( !pD3DEnum ) return E_POINTER; auto pOutputInfo = pD3DEnum->GetOutputInfo( g_DeviceSettings.d3d11.AdapterOrdinal, g_DeviceSettings.d3d11.Output ); if ( !pOutputInfo ) return E_POINTER; for( auto it = pOutputInfo->displayModeList.cbegin(); it != pOutputInfo->displayModeList.cend(); ++it ) { if ( it->Width == dwWidth && it->Height == dwHeight && it->Format == backBuffer ) AddD3D11RefreshRate( it->RefreshRate ); } SetSelectedD3D11RefreshRate( RefreshRate ); } return S_OK; } // //------------------------------------------------------------------------------------- void CD3DSettingsDlg::AddD3D11DeviceType( _In_ D3D_DRIVER_TYPE devType ) { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); if( !pComboBox->ContainsItem( DXUTDeviceTypeToString( devType ) ) ) pComboBox->AddItem( DXUTDeviceTypeToString( devType ), ULongToPtr( devType ) ); } //------------------------------------------------------------------------------------- D3D_DRIVER_TYPE CD3DSettingsDlg::GetSelectedD3D11DeviceType() const { auto pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); return ( D3D_DRIVER_TYPE )PtrToUlong( pComboBox->GetSelectedData() ); } void CD3DSettingsDlg::UpdateModeChangeTimeoutText( _In_ int nSecRemaining ) { const WCHAR StrTimeout[] = L"Reverting to previous display settings in %d seconds"; const DWORD CchBuf = sizeof( StrTimeout ) / sizeof( WCHAR ) + 16; WCHAR buf[CchBuf]; swprintf_s( buf, CchBuf, StrTimeout, nSecRemaining ); auto pStatic = m_RevertModeDialog.GetStatic( DXUTSETTINGSDLG_STATIC_MODE_CHANGE_TIMEOUT ); pStatic->SetText( buf ); } //-------------------------------------------------------------------------------------- // Returns the string for the given D3D_DRIVER_TYPE. //-------------------------------------------------------------------------------------- const WCHAR* DXUTDeviceTypeToString( _In_ D3D_DRIVER_TYPE devType ) { switch( devType ) { case D3D_DRIVER_TYPE_HARDWARE: return L"D3D_DRIVER_TYPE_HARDWARE"; case D3D_DRIVER_TYPE_REFERENCE: return L"D3D_DRIVER_TYPE_REFERENCE"; case D3D_DRIVER_TYPE_NULL: return L"D3D_DRIVER_TYPE_NULL"; case D3D_DRIVER_TYPE_WARP: return L"D3D_DRIVER_TYPE_WARP"; default: return L"Unknown devType"; } }