Signed-off-by: Philip Rebohle philip.rebohle@tu-dortmund.de --- dlls/dxgi/swapchain.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 1c7cf5c537..1411ede376 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2618,9 +2618,41 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetSourceSize(IDXGISwapChain3 *
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetMaximumFrameLatency(IDXGISwapChain3 *iface, UINT max_latency) { - FIXME("iface %p, max_latency %u stub!\n", iface, max_latency); + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, max_latency %u.\n", iface, max_latency); + + if (!(swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) + { + FIXME("DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT not set for swap chain %p.\n", iface); + return DXGI_ERROR_INVALID_CALL; + } + + if (!max_latency || max_latency > DXGI_MAX_SWAP_CHAIN_BUFFERS) + { + FIXME("Invalid maximum frame latency %u.\n", max_latency); + return DXGI_ERROR_INVALID_CALL; + } + + if (WaitForSingleObject(swapchain->frame_latency_event, INFINITE)) + { + ERR("Failed to wait for frame latency event, error %u.\n", GetLastError()); + return E_FAIL; + } + + if (max_latency < swapchain->frame_latency) + ResetEvent(swapchain->frame_latency_event); + + if (FAILED(hr = ID3D12Fence_SetEventOnCompletion(swapchain->frame_latency_fence, + swapchain->frame_number - max_latency, swapchain->frame_latency_event))) + { + ERR("Failed to enqueue frame latency event, hr %#x.\n", hr); + return hr; + } + + swapchain->frame_latency = max_latency; + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetMaximumFrameLatency(IDXGISwapChain3 *iface, UINT *max_latency)