diff --git a/src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp b/src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp index 56e38fe7705..9af51d606d3 100644 --- a/src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp +++ b/src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp @@ -54,6 +54,7 @@ struct d3d12_wgl_framebuffer { enum pipe_format pformat; HWND window; ComPtr 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 *