diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-03-30 16:52:13 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-03-30 16:52:13 +0000 |
| commit | 5677bdafc48e6231a67c01e5d894ed657aa0ecf6 (patch) | |
| tree | a847157bc1d7f8811bcae2d37e9ebe1f8f9b4c6b /Graphics | |
| parent | Implemented option to specify hardware adapter when initializing the engine i... (diff) | |
| download | DiligentCore-5677bdafc48e6231a67c01e5d894ed657aa0ecf6.tar.gz DiligentCore-5677bdafc48e6231a67c01e5d894ed657aa0ecf6.zip | |
Implemented initialization in fullscreen mode on Win32
Diffstat (limited to 'Graphics')
10 files changed, 109 insertions, 17 deletions
diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 574e4c12..59bd356c 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -986,8 +986,11 @@ namespace Diligent /// Display format TEXTURE_FORMAT Format = TEX_FORMAT_UNKNOWN; - /// Display refresh rate - double RefreshRate = 0.0; + /// Refresh rate numerator + Uint32 RefreshRateNumerator = 0; + + /// Refresh rate denominator + Uint32 RefreshRateDenominator = 0; /// The scanline drawing mode. SCALING Scaling = SCALING_UNSPECIFIED; @@ -1036,6 +1039,26 @@ namespace Diligent {} }; + /// Full screen mode description + /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/hh404531(v=vs.85).aspx">DXGI_SWAP_CHAIN_FULLSCREEN_DESC structure on MSDN</a>, + struct FullScreenModeDesc + { + /// A Boolean value that specifies whether the swap chain is in fullscreen mode. + Bool Fullscreen = False; + + /// Refresh rate numerator + Uint32 RefreshRateNumerator = 0; + + /// Refresh rate denominator + Uint32 RefreshRateDenominator = 0; + + /// The scanline drawing mode. + DisplayModeAttribs::SCALING Scaling = DisplayModeAttribs::SCALING_UNSPECIFIED; + + /// The scaling mode. + DisplayModeAttribs::SCANLINE_ORDER ScanlineOrder = DisplayModeAttribs::SCANLINE_ORDER_UNSPECIFIED; + }; + /// Engine creation attibutes struct EngineCreationAttribs { diff --git a/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h index e9bd6899..2289f20d 100644 --- a/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h @@ -39,7 +39,8 @@ class SwapChainD3D11Impl : public SwapChainBase<ISwapChainD3D11> public: typedef SwapChainBase<ISwapChainD3D11> TSwapChainBase; SwapChainD3D11Impl(IReferenceCounters *pRefCounters, - const SwapChainDesc& SwapChainDesc, + const SwapChainDesc& SCDesc, + const FullScreenModeDesc& FSDesc, class RenderDeviceD3D11Impl* pRenderDeviceD3D11, class DeviceContextD3D11Impl* pDeviceContextD3D11, void* pNativeWndHandle); diff --git a/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h index 84154472..69029ce9 100644 --- a/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h @@ -52,6 +52,7 @@ public: virtual void CreateSwapChainD3D11( IRenderDevice *pDevice, IDeviceContext *pImmediateContext, const SwapChainDesc& SCDesc, + const FullScreenModeDesc& FSDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain ) = 0; diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp index fc33ddb7..3084b881 100644 --- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp @@ -56,6 +56,7 @@ public: void CreateSwapChainD3D11( IRenderDevice *pDevice, IDeviceContext *pImmediateContext, const SwapChainDesc& SCDesc, + const FullScreenModeDesc& FSDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain )override final; @@ -166,7 +167,7 @@ void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11( const EngineD3D11Attr D3D_FEATURE_LEVEL d3dFeatureLevel = D3D_FEATURE_LEVEL_11_0; HRESULT hr = D3D11CreateDevice( hardwareAdapter, // Specify nullptr to use the default adapter. - hardwareAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, // Create a device using the hardware graphics driver. + hardwareAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, // If no adapter specified, request hardware graphics driver. 0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE. creationFlags, // Set debug and Direct2D compatibility flags. featureLevels, // List of feature levels this app can support. @@ -289,6 +290,7 @@ void EngineFactoryD3D11Impl::AttachToD3D11Device(void *pd3d11NativeDevice, /// \param [in] pDevice - Pointer to the render device /// \param [in] pImmediateContext - Pointer to the immediate device context /// \param [in] SCDesc - Swap chain description +/// \param [in] FSDesc - Fullscreen mode description /// \param [in] pNativeWndHandle - Platform-specific native handle of the window /// the swap chain will be associated with: /// * On Win32 platform, this should be window handle (HWND) @@ -297,7 +299,12 @@ void EngineFactoryD3D11Impl::AttachToD3D11Device(void *pd3d11NativeDevice, /// /// \param [out] ppSwapChain - Address of the memory location where pointer to the new /// swap chain will be written -void EngineFactoryD3D11Impl::CreateSwapChainD3D11( IRenderDevice *pDevice, Diligent::IDeviceContext *pImmediateContext, const SwapChainDesc& SCDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain ) +void EngineFactoryD3D11Impl::CreateSwapChainD3D11( IRenderDevice *pDevice, + IDeviceContext *pImmediateContext, + const SwapChainDesc& SCDesc, + const FullScreenModeDesc& FSDesc, + void* pNativeWndHandle, + ISwapChain **ppSwapChain ) { VERIFY( ppSwapChain, "Null pointer provided" ); if( !ppSwapChain ) @@ -312,7 +319,7 @@ void EngineFactoryD3D11Impl::CreateSwapChainD3D11( IRenderDevice *pDevice, Dilig auto &RawMemAllocator = GetRawAllocator(); auto *pSwapChainD3D11 = NEW_RC_OBJ(RawMemAllocator, "SwapChainD3D11Impl instance", SwapChainD3D11Impl) - (SCDesc, pDeviceD3D11, pDeviceContextD3D11, pNativeWndHandle); + (SCDesc, FSDesc, pDeviceD3D11, pDeviceContextD3D11, pNativeWndHandle); pSwapChainD3D11->QueryInterface( IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); pDeviceContextD3D11->SetSwapChain(pSwapChainD3D11); diff --git a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp index 01f4623d..34bb54d0 100644 --- a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp @@ -34,6 +34,7 @@ namespace Diligent SwapChainD3D11Impl::SwapChainD3D11Impl(IReferenceCounters *pRefCounters, const SwapChainDesc& SCDesc, + const FullScreenModeDesc& FSDesc, RenderDeviceD3D11Impl* pRenderDeviceD3D11, DeviceContextD3D11Impl* pDeviceContextD3D11, void* pNativeWndHandle) : @@ -46,7 +47,15 @@ SwapChainD3D11Impl::SwapChainD3D11Impl(IReferenceCounters *pRefCounters, if( m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0 ) { RECT rc; - GetClientRect( hWnd, &rc ); + if(FSDesc.Fullscreen) + { + const HWND hDesktop = GetDesktopWindow(); + GetWindowRect(hDesktop, &rc); + } + else + { + GetClientRect(hWnd, &rc); + } m_SwapChainDesc.Width = rc.right - rc.left; m_SwapChainDesc.Height = rc.bottom - rc.top; } @@ -73,13 +82,15 @@ SwapChainD3D11Impl::SwapChainD3D11Impl(IReferenceCounters *pRefCounters, swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = m_SwapChainDesc.BufferCount; swapChainDesc.Scaling = DXGI_SCALING_NONE; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + // Windows Store apps must use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL or DXGI_SWAP_EFFECT_FLIP_DISCARD. + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used - swapChainDesc.Flags = 0; + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; CComPtr<IDXGISwapChain1> pSwapChain1; #if PLATFORM_WIN32 + // This sequence obtains the DXGI factory that was used to create the Direct3D device above. CComPtr<IDXGIDevice> pDXGIDevice; pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>( static_cast<IDXGIDevice**>(&pDXGIDevice) ) ); @@ -88,11 +99,20 @@ SwapChainD3D11Impl::SwapChainD3D11Impl(IReferenceCounters *pRefCounters, CComPtr<IDXGIFactory2> pDXGIFactory; pDXGIAdapter->GetParent(__uuidof(pDXGIFactory), reinterpret_cast<void**>( static_cast<IDXGIFactory2**>(&pDXGIFactory) )); - CHECK_D3D_RESULT_THROW( pDXGIFactory->CreateSwapChainForHwnd(pDevice, hWnd, &swapChainDesc, nullptr, nullptr, &pSwapChain1), + DXGI_SWAP_CHAIN_FULLSCREEN_DESC FullScreenDesc = {}; + FullScreenDesc.Windowed = FSDesc.Fullscreen ? FALSE : TRUE; + FullScreenDesc.RefreshRate.Numerator = FSDesc.RefreshRateNumerator; + FullScreenDesc.RefreshRate.Denominator = FSDesc.RefreshRateDenominator; + FullScreenDesc.Scaling = static_cast<DXGI_MODE_SCALING>(FSDesc.Scaling); + FullScreenDesc.ScanlineOrdering = static_cast<DXGI_MODE_SCANLINE_ORDER>(FSDesc.ScanlineOrder); + CHECK_D3D_RESULT_THROW( pDXGIFactory->CreateSwapChainForHwnd(pDevice, hWnd, &swapChainDesc, &FullScreenDesc, nullptr, &pSwapChain1), "Failed to create DXGI swap chain" ); #elif PLATFORM_UNIVERSAL_WINDOWS + if (FSDesc.Fullscreen) + LOG_WARNING_MESSAGE("UWP applications do not support fullscreen mode"); + CComPtr<IDXGIDevice3> pDXGIDevice; pDevice->QueryInterface(__uuidof(IDXGIDevice3), reinterpret_cast<void**>(static_cast<IDXGIDevice3**>(&pDXGIDevice))); CComPtr<IDXGIAdapter> pDXGIAdapter; @@ -121,7 +141,14 @@ SwapChainD3D11Impl::SwapChainD3D11Impl(IReferenceCounters *pRefCounters, SwapChainD3D11Impl::~SwapChainD3D11Impl() { - + // Swap chain must be in windowed mode when terminating the app + if(m_pSwapChain) + { + BOOL IsFullScreen = FALSE; + m_pSwapChain->GetFullscreenState(&IsFullScreen, nullptr); + if(IsFullScreen) + m_pSwapChain->SetFullscreenState(FALSE, nullptr); + } } void SwapChainD3D11Impl::CreateRTVandDSV() diff --git a/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h index 0e73a6b8..3b75be44 100644 --- a/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h @@ -42,6 +42,7 @@ public: typedef SwapChainBase<ISwapChainD3D12> TSwapChainBase; SwapChainD3D12Impl(IReferenceCounters *pRefCounters, const SwapChainDesc& SwapChainDesc, + const FullScreenModeDesc& FSDesc, class RenderDeviceD3D12Impl* pRenderDeviceD3D12, class DeviceContextD3D12Impl* pDeviceContextD3D12, void* pNativeWndHandle); diff --git a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceFactoryD3D12.h b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceFactoryD3D12.h index 6a8c7e6e..e8b7cdb4 100644 --- a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceFactoryD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceFactoryD3D12.h @@ -57,6 +57,7 @@ public: virtual void CreateSwapChainD3D12( IRenderDevice *pDevice, IDeviceContext *pImmediateContext, const SwapChainDesc& SwapChainDesc, + const FullScreenModeDesc& FSDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain ) = 0; diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp index fb7cb83b..2fdbe59b 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp @@ -65,6 +65,7 @@ public: void CreateSwapChainD3D12( IRenderDevice *pDevice, IDeviceContext *pImmediateContext, const SwapChainDesc& SwapChainDesc, + const FullScreenModeDesc& FSDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain )override final; }; @@ -343,6 +344,7 @@ void EngineFactoryD3D12Impl::AttachToD3D12Device(void *pd3d12NativeDevice, /// \param [in] pDevice - Pointer to the render device /// \param [in] pImmediateContext - Pointer to the immediate device context /// \param [in] SCDesc - Swap chain description +/// \param [in] FSDesc - Fullscreen mode description /// \param [in] pNativeWndHandle - Platform-specific native handle of the window /// the swap chain will be associated with: /// * On Win32 platform, this should be window handle (HWND) @@ -354,6 +356,7 @@ void EngineFactoryD3D12Impl::AttachToD3D12Device(void *pd3d12NativeDevice, void EngineFactoryD3D12Impl::CreateSwapChainD3D12( IRenderDevice *pDevice, IDeviceContext *pImmediateContext, const SwapChainDesc& SCDesc, + const FullScreenModeDesc& FSDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain ) { @@ -368,7 +371,7 @@ void EngineFactoryD3D12Impl::CreateSwapChainD3D12( IRenderDevice *pDevice, auto *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( pDevice ); auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pImmediateContext); auto &RawMemAllocator = GetRawAllocator(); - auto *pSwapChainD3D12 = NEW_RC_OBJ(RawMemAllocator, "SwapChainD3D12Impl instance", SwapChainD3D12Impl)(SCDesc, pDeviceD3D12, pDeviceContextD3D12, pNativeWndHandle); + auto *pSwapChainD3D12 = NEW_RC_OBJ(RawMemAllocator, "SwapChainD3D12Impl instance", SwapChainD3D12Impl)(SCDesc, FSDesc, pDeviceD3D12, pDeviceContextD3D12, pNativeWndHandle); pSwapChainD3D12->QueryInterface( IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); pDeviceContextD3D12->SetSwapChain(pSwapChainD3D12); diff --git a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp index f45a7c09..6add53b8 100644 --- a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp @@ -34,6 +34,7 @@ namespace Diligent SwapChainD3D12Impl::SwapChainD3D12Impl(IReferenceCounters *pRefCounters, const SwapChainDesc& SCDesc, + const FullScreenModeDesc& FSDesc, RenderDeviceD3D12Impl* pRenderDeviceD3D12, DeviceContextD3D12Impl* pDeviceContextD3D12, void* pNativeWndHandle) : @@ -47,7 +48,15 @@ SwapChainD3D12Impl::SwapChainD3D12Impl(IReferenceCounters *pRefCounters, if( m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0 ) { RECT rc; - GetClientRect( hWnd, &rc ); + if (FSDesc.Fullscreen) + { + const HWND hDesktop = GetDesktopWindow(); + GetWindowRect(hDesktop, &rc); + } + else + { + GetClientRect(hWnd, &rc); + } m_SwapChainDesc.Width = rc.right - rc.left; m_SwapChainDesc.Height = rc.bottom - rc.top; } @@ -72,9 +81,10 @@ SwapChainD3D12Impl::SwapChainD3D12Impl(IReferenceCounters *pRefCounters, swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = m_SwapChainDesc.BufferCount; swapChainDesc.Scaling = DXGI_SCALING_NONE; + // Windows Store apps must use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL or DXGI_SWAP_EFFECT_FLIP_DISCARD. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used - swapChainDesc.Flags = 0; + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; CComPtr<IDXGISwapChain1> pSwapChain1; CComPtr<IDXGIFactory4> factory; @@ -82,8 +92,16 @@ SwapChainD3D12Impl::SwapChainD3D12Impl(IReferenceCounters *pRefCounters, CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory") auto *pd3d12CmdQueue = pRenderDeviceD3D12->GetCmdQueue()->GetD3D12CommandQueue(); + #if PLATFORM_WIN32 - hr = factory->CreateSwapChainForHwnd(pd3d12CmdQueue, hWnd, &swapChainDesc, nullptr, nullptr, &pSwapChain1); + + DXGI_SWAP_CHAIN_FULLSCREEN_DESC FullScreenDesc = {}; + FullScreenDesc.Windowed = FSDesc.Fullscreen ? FALSE : TRUE; + FullScreenDesc.RefreshRate.Numerator = FSDesc.RefreshRateNumerator; + FullScreenDesc.RefreshRate.Denominator = FSDesc.RefreshRateDenominator; + FullScreenDesc.Scaling = static_cast<DXGI_MODE_SCALING>(FSDesc.Scaling); + FullScreenDesc.ScanlineOrdering = static_cast<DXGI_MODE_SCANLINE_ORDER>(FSDesc.ScanlineOrder); + hr = factory->CreateSwapChainForHwnd(pd3d12CmdQueue, hWnd, &swapChainDesc, &FullScreenDesc, nullptr, &pSwapChain1); CHECK_D3D_RESULT_THROW( hr, "Failed to create Swap Chain" ); // This sample does not support fullscreen transitions. @@ -91,6 +109,9 @@ SwapChainD3D12Impl::SwapChainD3D12Impl(IReferenceCounters *pRefCounters, #elif PLATFORM_UNIVERSAL_WINDOWS + if (FSDesc.Fullscreen) + LOG_WARNING_MESSAGE("UWP applications do not support fullscreen mode"); + hr = factory->CreateSwapChainForCoreWindow( pd3d12CmdQueue, reinterpret_cast<IUnknown*>(pNativeWndHandle), @@ -112,7 +133,13 @@ SwapChainD3D12Impl::SwapChainD3D12Impl(IReferenceCounters *pRefCounters, SwapChainD3D12Impl::~SwapChainD3D12Impl() { - + if (m_pSwapChain) + { + BOOL IsFullScreen = FALSE; + m_pSwapChain->GetFullscreenState(&IsFullScreen, nullptr); + if (IsFullScreen) + m_pSwapChain->SetFullscreenState(FALSE, nullptr); + } } void SwapChainD3D12Impl::InitBuffersAndViews() diff --git a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h index 86142c8c..934b8974 100644 --- a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h +++ b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h @@ -135,7 +135,8 @@ public: DstMode.Width = SrcMode.Width; DstMode.Height = SrcMode.Height; DstMode.Format = DXGI_FormatToTexFormat(SrcMode.Format); - DstMode.RefreshRate = static_cast<double>(SrcMode.RefreshRate.Numerator) / static_cast<double>(SrcMode.RefreshRate.Denominator); + DstMode.RefreshRateNumerator = SrcMode.RefreshRate.Numerator; + DstMode.RefreshRateDenominator = SrcMode.RefreshRate.Denominator; DstMode.Scaling = static_cast<DisplayModeAttribs::SCALING>(SrcMode.Scaling); DstMode.ScanlineOrder = static_cast<DisplayModeAttribs::SCANLINE_ORDER>(SrcMode.ScanlineOrdering); } |
