[PATCH 2/6] dxgi: Signal frame latency event on present as necessary.

Philip Rebohle philip.rebohle at tu-dortmund.de
Wed Apr 15 10:22:57 CDT 2020


Signed-off-by: Philip Rebohle <philip.rebohle at tu-dortmund.de>
---
 dlls/dxgi/swapchain.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 54563a208b..f55a94e7cd 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -1097,6 +1097,9 @@ struct d3d12_swapchain
 
     ID3D12Fence *frame_latency_fence;
     HANDLE *frame_latency_event;
+
+    uint64_t frame_number;
+    uint32_t frame_latency;
 };
 
 static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format)
@@ -2125,6 +2128,17 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain,
     if (FAILED(hr = d3d12_swapchain_set_sync_interval(swapchain, sync_interval)))
         return hr;
 
+    if (swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)
+    {
+        if (WaitForSingleObject(swapchain->frame_latency_event, INFINITE))
+        {
+            ERR("Failed to wait for frame latency event, error %u.\n", GetLastError());
+            return E_FAIL;
+        }
+
+        ResetEvent(swapchain->frame_latency_event);
+    }
+
     if (!(vk_queue = vkd3d_acquire_vk_queue(swapchain->command_queue)))
     {
         ERR("Failed to acquire Vulkan queue.\n");
@@ -2166,6 +2180,25 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain,
         return hresult_from_vk_result(vr);
     }
 
+    if (swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)
+    {
+        ++swapchain->frame_number;
+
+        if (FAILED(hr = ID3D12CommandQueue_Signal(swapchain->command_queue,
+                swapchain->frame_latency_fence, swapchain->frame_number)))
+        {
+            ERR("Failed to signal frame latency fence, hr %#x.\n", hr);
+            return hr;
+        }
+
+        if (FAILED(hr = ID3D12Fence_SetEventOnCompletion(swapchain->frame_latency_fence,
+                swapchain->frame_number - swapchain->frame_latency, swapchain->frame_latency_event)))
+        {
+            FIXME("Failed to enqueue frame latency event, hr %#x.\n", hr);
+            return hr;
+        }
+    }
+
     swapchain->current_buffer_index = (swapchain->current_buffer_index + 1) % swapchain->desc.BufferCount;
     vr = d3d12_swapchain_acquire_next_back_buffer(swapchain);
     if (vr == VK_ERROR_OUT_OF_DATE_KHR)
@@ -2994,6 +3027,9 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
 
     if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)
     {
+        swapchain->frame_number = DXGI_MAX_SWAP_CHAIN_BUFFERS;
+        swapchain->frame_latency = 1;
+
         if (FAILED(hr = ID3D12Device_CreateFence(device, DXGI_MAX_SWAP_CHAIN_BUFFERS,
                 0, &IID_ID3D12Fence, (void **)&swapchain->frame_latency_fence)))
         {
-- 
2.26.0




More information about the wine-devel mailing list