diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp index ead6ca9c3..c5cb7c472 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp @@ -265,6 +265,19 @@ bool GPUDeviceDX11::Init() return true; } UpdateOutputs(adapter); + { + ComPtr factory5; + _factoryDXGI->QueryInterface(IID_PPV_ARGS(&factory5)); + if (factory5) + { + BOOL allowTearing; + if (SUCCEEDED(factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing))) && allowTearing) + { + AllowTearing = true; + } + } + } + // Get flags and device type base on current configuration uint32 flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h index de0132ea3..ec2ba0177 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h @@ -50,6 +50,10 @@ public: GPUDeviceDX11(IDXGIFactory* dxgiFactory, GPUAdapterDX* adapter); ~GPUDeviceDX11(); +public: + + bool AllowTearing = false; + public: // Gets DX11 device diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp index 56fcfcc77..79e76a2a5 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp @@ -17,6 +17,8 @@ GPUSwapChainDX11::GPUSwapChainDX11(GPUDeviceDX11* device, Window* window) #endif , _swapChain(nullptr) , _backBuffer(nullptr) + , _allowTearing(false) + , _isFullscreen(false) { ASSERT(_windowHandle); _window = window; @@ -108,6 +110,8 @@ void GPUSwapChainDX11::SetFullscreen(bool isFullscreen) { LOG(Warning, "Cannot change fullscreen mode for '{0}' to {1}.", ToString(), isFullscreen); } + + _isFullscreen = isFullscreen; } #else LOG(Info, "Cannot change fullscreen mode on this platform"); @@ -123,7 +127,12 @@ void GPUSwapChainDX11::Present(bool vsync) { // Present frame ASSERT(_swapChain); - const HRESULT result = _swapChain->Present(vsync ? 1 : 0, 0); + UINT presentFlags = 0; + if (!vsync && !_isFullscreen && _allowTearing) + { + presentFlags |= DXGI_PRESENT_ALLOW_TEARING; + } + const HRESULT result = _swapChain->Present(vsync ? 1 : 0, presentFlags); LOG_DIRECTX_RESULT(result); // Base @@ -140,6 +149,7 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height) _device->WaitForGPU(); GPUDeviceLock lock(_device); + _allowTearing = _device->AllowTearing; _format = GPU_BACK_BUFFER_PIXEL_FORMAT; #if PLATFORM_WINDOWS @@ -177,6 +187,12 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height) swapChainDesc.Windowed = TRUE; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + if (_allowTearing) + { + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; + } #else swapChainDesc.Width = width; swapChainDesc.Height = height; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.h index f0a785930..35688affc 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.h @@ -23,6 +23,7 @@ private: #if PLATFORM_WINDOWS HWND _windowHandle; IDXGISwapChain* _swapChain; + bool _allowTearing, _isFullscreen; #else IUnknown* _windowHandle; IDXGISwapChain1* _swapChain; diff --git a/Source/Engine/GraphicsDevice/DirectX/IncludeDirectXHeaders.h b/Source/Engine/GraphicsDevice/DirectX/IncludeDirectXHeaders.h index ca4dae608..7cf4be599 100644 --- a/Source/Engine/GraphicsDevice/DirectX/IncludeDirectXHeaders.h +++ b/Source/Engine/GraphicsDevice/DirectX/IncludeDirectXHeaders.h @@ -39,6 +39,7 @@ typedef IGraphicsUnknown IDXGISwapChain3; #include #include #include +#include #endif #if GRAPHICS_API_DIRECTX12 #include