winsys/d3d12: Use the waitable object to decrease latency

Reviewed-By: Sil Vilerino <sivileri@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31157>
This commit is contained in:
Jesse Natalie
2024-09-12 14:30:05 -07:00
committed by Marge Bot
parent 2b8a980240
commit 64885821c2
@@ -54,6 +54,7 @@ struct d3d12_wgl_framebuffer {
enum pipe_format pformat;
HWND window;
ComPtr<IDXGISwapChain3> swapchain;
HANDLE waitable_object;
struct pipe_resource *buffers[num_buffers];
bool single_buffered;
struct pipe_resource *offscreen_buffer;
@@ -92,6 +93,9 @@ d3d12_wgl_framebuffer_destroy(struct stw_winsys_framebuffer *fb,
pipe_resource_reference(&framebuffer->offscreen_buffer, NULL);
}
if (framebuffer->waitable_object)
CloseHandle(framebuffer->waitable_object);
delete framebuffer;
}
@@ -106,7 +110,7 @@ d3d12_wgl_framebuffer_resize(stw_winsys_framebuffer *fb,
DXGI_SWAP_CHAIN_DESC1 desc = {};
desc.BufferCount = num_buffers;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
desc.Format = d3d12_get_format(templ->format);
desc.Width = templ->width0;
desc.Height = templ->height0;
@@ -132,6 +136,9 @@ d3d12_wgl_framebuffer_resize(stw_winsys_framebuffer *fb,
screen->factory->MakeWindowAssociation(framebuffer->window,
DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_PRINT_SCREEN);
framebuffer->waitable_object = framebuffer->swapchain->GetFrameLatencyWaitableObject();
WaitForSingleObject(framebuffer->waitable_object, INFINITE);
}
else {
struct pipe_fence_handle *fence = NULL;
@@ -206,10 +213,15 @@ d3d12_wgl_framebuffer_present(stw_winsys_framebuffer *fb, int interval)
return false;
}
HRESULT hr;
if (interval < 1)
return S_OK == framebuffer->swapchain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
hr = framebuffer->swapchain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
else
return S_OK == framebuffer->swapchain->Present(interval, 0);
hr = framebuffer->swapchain->Present(interval, 0);
if (hr == S_OK)
return WaitForSingleObject(framebuffer->waitable_object, 2000) == WAIT_OBJECT_0;
return false;
}
static struct pipe_resource *