From: Giovanni Mascellani gmascellani@codeweavers.com
The client is expected to wait on the frame latency semaphore when the swapchain is created with DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT. But when it is not, we're supposed to do it ourselves. --- dlls/dxgi/swapchain.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 67b637fbeaf..57783972a9c 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2290,13 +2290,10 @@ static HRESULT d3d12_swapchain_op_present_execute(struct d3d12_swapchain *swapch return hresult_from_vk_result(vr); }
- if (swapchain->frame_latency_semaphore) + if (!ReleaseSemaphore(swapchain->frame_latency_semaphore, 1, NULL)) { - if (!ReleaseSemaphore(swapchain->frame_latency_semaphore, 1, NULL)) - { - ERR("Failed to release frame latency semaphore, last error %ld.\n", GetLastError()); - return HRESULT_FROM_WIN32(GetLastError()); - } + ERR("Failed to release frame latency semaphore, last error %ld.\n", GetLastError()); + return HRESULT_FROM_WIN32(GetLastError()); }
return S_OK; @@ -2348,6 +2345,14 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain, }
swapchain->current_buffer_index = (swapchain->current_buffer_index + 1) % swapchain->desc.BufferCount; + + if (!(swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) + && WaitForSingleObject(swapchain->frame_latency_semaphore, INFINITE) != WAIT_OBJECT_0) + { + ERR("Failed to wait for frame latency semaphore, last error %ld.\n", GetLastError()); + return HRESULT_FROM_WIN32(GetLastError()); + } + return S_OK; }
@@ -2900,8 +2905,11 @@ static HANDLE STDMETHODCALLTYPE d3d12_swapchain_GetFrameLatencyWaitableObject(ID
TRACE("iface %p.\n", iface);
- if (!swapchain->frame_latency_semaphore) + if (!(swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) + { + WARN("DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT not set for swap chain %p.\n", iface); return NULL; + }
ret = DuplicateHandle(GetCurrentProcess(), swapchain->frame_latency_semaphore, GetCurrentProcess(), &dup, 0, FALSE, DUPLICATE_SAME_ACCESS); @@ -3341,16 +3349,16 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI swapchain->current_buffer_index = 0;
if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) - { swapchain->frame_latency = 1; + else + swapchain->frame_latency = 3;
- if (!(swapchain->frame_latency_semaphore = CreateSemaphoreW(NULL, 1, LONG_MAX, NULL))) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - WARN("Failed to create frame latency semaphore, hr %#lx.\n", hr); - d3d12_swapchain_destroy(swapchain); - return hr; - } + if (!(swapchain->frame_latency_semaphore = CreateSemaphoreW(NULL, 1, LONG_MAX, NULL))) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + WARN("Failed to create frame latency semaphore, hr %#lx.\n", hr); + d3d12_swapchain_destroy(swapchain); + return hr; }
if (FAILED(hr = ID3D12Device_CreateFence(device, 0, 0,