diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index ec9951c9..59f78c42 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -108,6 +108,11 @@ namespace dxvk { } + UINT STDMETHODCALLTYPE D3D11SwapChain::GetFrameLatency() { + return m_frameLatency; + } + + HRESULT STDMETHODCALLTYPE D3D11SwapChain::ChangeProperties( const DXGI_SWAP_CHAIN_DESC1* pDesc) { @@ -164,6 +169,16 @@ namespace dxvk { } + HRESULT STDMETHODCALLTYPE D3D11SwapChain::SetFrameLatency( + UINT MaxLatency) { + if (MaxLatency == 0 || MaxLatency > DXGI_MAX_SWAP_CHAIN_BUFFERS) + return DXGI_ERROR_INVALID_CALL; + + m_frameLatency = MaxLatency; + return S_OK; + } + + HRESULT STDMETHODCALLTYPE D3D11SwapChain::Present( UINT SyncInterval, UINT PresentFlags, @@ -718,8 +733,10 @@ namespace dxvk { uint32_t D3D11SwapChain::GetActualFrameLatency() { - uint32_t maxFrameLatency = DefaultFrameLatency; - m_dxgiDevice->GetMaximumFrameLatency(&maxFrameLatency); + uint32_t maxFrameLatency = m_frameLatency; + + if (!(m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) + m_dxgiDevice->GetMaximumFrameLatency(&maxFrameLatency); if (m_frameLatencyCap) maxFrameLatency = std::min(maxFrameLatency, m_frameLatencyCap); diff --git a/src/d3d11/d3d11_swapchain.h b/src/d3d11/d3d11_swapchain.h index 78a97baf..cba25a4a 100644 --- a/src/d3d11/d3d11_swapchain.h +++ b/src/d3d11/d3d11_swapchain.h @@ -54,6 +54,8 @@ namespace dxvk { UINT STDMETHODCALLTYPE GetImageIndex(); + UINT STDMETHODCALLTYPE GetFrameLatency(); + HRESULT STDMETHODCALLTYPE ChangeProperties( const DXGI_SWAP_CHAIN_DESC1* pDesc); @@ -64,6 +66,9 @@ namespace dxvk { UINT NumControlPoints, const DXGI_RGB* pControlPoints); + HRESULT STDMETHODCALLTYPE SetFrameLatency( + UINT MaxLatency); + HRESULT STDMETHODCALLTYPE Present( UINT SyncInterval, UINT PresentFlags, @@ -117,7 +122,8 @@ namespace dxvk { std::vector> m_imageViews; - uint64_t m_frameId = DXGI_MAX_SWAP_CHAIN_BUFFERS; + uint64_t m_frameId = DXGI_MAX_SWAP_CHAIN_BUFFERS; + uint32_t m_frameLatency = DefaultFrameLatency; uint32_t m_frameLatencyCap = 0; Rc m_frameLatencySignal; diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 9d298d7f..376b0688 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -56,6 +56,8 @@ IDXGIVkSwapChain : public IUnknown { virtual UINT STDMETHODCALLTYPE GetImageIndex() = 0; + virtual UINT STDMETHODCALLTYPE GetFrameLatency() = 0; + virtual HRESULT STDMETHODCALLTYPE ChangeProperties( const DXGI_SWAP_CHAIN_DESC1* pDesc) = 0; @@ -66,6 +68,9 @@ IDXGIVkSwapChain : public IUnknown { UINT NumControlPoints, const DXGI_RGB* pControlPoints) = 0; + virtual HRESULT STDMETHODCALLTYPE SetFrameLatency( + UINT MaxLatency) = 0; + virtual HRESULT STDMETHODCALLTYPE Present( UINT SyncInterval, UINT PresentFlags, diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 389920a7..5b8d2510 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -421,8 +421,12 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetMaximumFrameLatency( UINT* pMaxLatency) { - Logger::err("DxgiSwapChain::GetMaximumFrameLatency: Not implemented"); - return DXGI_ERROR_INVALID_CALL; + if (!(m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) + return DXGI_ERROR_INVALID_CALL; + + std::lock_guard lock(m_lockWindow); + *pMaxLatency = m_presenter->GetFrameLatency(); + return S_OK; } @@ -446,8 +450,11 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::SetMaximumFrameLatency( UINT MaxLatency) { - Logger::err("DxgiSwapChain::SetMaximumFrameLatency: Not implemented"); - return DXGI_ERROR_INVALID_CALL; + if (!(m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) + return DXGI_ERROR_INVALID_CALL; + + std::lock_guard lock(m_lockWindow); + return m_presenter->SetFrameLatency(MaxLatency); }