From 6aeb444e4ca7f8e60c503858bc52e4a75b150f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 22 Mar 2018 08:48:31 +0100 Subject: [PATCH] wined3d: Implement updating swap interval through wined3d_swapchain_present(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on a patch by Michael Müller. Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/d3d8/d3d8_private.h | 1 + dlls/d3d8/device.c | 4 ++++ dlls/d3d8/swapchain.c | 3 ++- dlls/d3d9/d3d9_private.h | 1 + dlls/d3d9/device.c | 23 +++++++++++++++++------ dlls/d3d9/swapchain.c | 3 ++- dlls/dxgi/swapchain.c | 10 +++++++--- dlls/wined3d/cs.c | 11 ++++++++++- dlls/wined3d/surface.c | 3 ++- dlls/wined3d/swapchain.c | 7 ++++--- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 ++-- include/wine/wined3d.h | 4 ++-- 13 files changed, 55 insertions(+), 21 deletions(-) diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index cba5dd647b4..2510d58c454 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -166,6 +166,7 @@ struct d3d8_swapchain LONG refcount; struct wined3d_swapchain *wined3d_swapchain; IDirect3DDevice8 *parent_device; + unsigned int swap_interval; }; HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc, diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 4fcad71451e..6dc58cb43b2 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -913,6 +913,8 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, NULL, reset_enum_callback, TRUE))) { present_parameters->BackBufferCount = swapchain_desc.backbuffer_count; + device->implicit_swapchain->swap_interval + = wined3dswapinterval_from_d3dpresentationinterval(present_parameters->FullScreen_PresentationInterval); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); @@ -3476,6 +3478,8 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0); device->implicit_swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); + device->implicit_swapchain->swap_interval + = wined3dswapinterval_from_d3dpresentationinterval(parameters->FullScreen_PresentationInterval); device->d3d_parent = &parent->IDirect3D8_iface; IDirect3D8_AddRef(device->d3d_parent); diff --git a/dlls/d3d8/swapchain.c b/dlls/d3d8/swapchain.c index 7003aa32dbc..b9350084a50 100644 --- a/dlls/d3d8/swapchain.c +++ b/dlls/d3d8/swapchain.c @@ -105,7 +105,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai wined3d_mutex_lock(); hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, 0); + src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0); wined3d_mutex_unlock(); return hr; @@ -173,6 +173,7 @@ static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_devi swapchain->refcount = 1; swapchain->IDirect3DSwapChain8_iface.lpVtbl = &d3d8_swapchain_vtbl; + swapchain->swap_interval = desc->swap_interval; wined3d_mutex_lock(); hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index ba19e5fb08f..4d783eb9a1a 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -151,6 +151,7 @@ struct d3d9_swapchain LONG refcount; struct wined3d_swapchain *wined3d_swapchain; IDirect3DDevice9Ex *parent_device; + unsigned int swap_interval; }; HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc, diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 457a0cdca9c..7c84257c220 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -991,6 +991,8 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, } else { + device->implicit_swapchains[0]->swap_interval + = wined3dswapinterval_from_d3dpresentationinterval(present_parameters->PresentationInterval); wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc); present_parameters->BackBufferWidth = swapchain_desc.backbuffer_width; present_parameters->BackBufferHeight = swapchain_desc.backbuffer_height; @@ -1033,7 +1035,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex * const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - UINT i; + struct d3d9_swapchain *swapchain; + unsigned int i; HRESULT hr; TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n", @@ -1048,8 +1051,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex * wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, 0))) + swapchain = device->implicit_swapchains[i]; + if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0))) { wined3d_mutex_unlock(); return hr; @@ -3724,7 +3728,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex const RGNDATA *dirty_region, DWORD flags) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - UINT i; + struct d3d9_swapchain *swapchain; + unsigned int i; HRESULT hr; TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n", @@ -3740,8 +3745,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, flags))) + swapchain = device->implicit_swapchains[i]; + if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags))) { wined3d_mutex_unlock(); return hr; @@ -4328,6 +4334,11 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine wined3d_mutex_unlock(); return E_OUTOFMEMORY; } + for (i = 0; i < device->implicit_swapchain_count; ++i) + { + device->implicit_swapchains[i]->swap_interval + = wined3dswapinterval_from_d3dpresentationinterval(parameters[i].PresentationInterval); + } for (i = 0; i < count; ++i) { diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c index 411040ad66d..6a182d4012d 100644 --- a/dlls/d3d9/swapchain.c +++ b/dlls/d3d9/swapchain.c @@ -137,7 +137,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai wined3d_mutex_lock(); hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, flags); + src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags); wined3d_mutex_unlock(); return hr; @@ -350,6 +350,7 @@ static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_devi swapchain->refcount = 1; swapchain->IDirect3DSwapChain9Ex_iface.lpVtbl = &d3d9_swapchain_vtbl; + swapchain->swap_interval = desc->swap_interval; wined3d_mutex_lock(); hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 1f88d71b77a..6f9d0338aee 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -533,6 +533,12 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_Present1(IDXGISwapChain1 *iface, TRACE("iface %p, sync_interval %u, flags %#x, present_parameters %p.\n", iface, sync_interval, flags, present_parameters); + if (sync_interval > 4) + { + WARN("Invalid sync interval %u.\n", sync_interval); + return DXGI_ERROR_INVALID_CALL; + } + if (flags & ~DXGI_PRESENT_TEST) FIXME("Unimplemented flags %#x.\n", flags); if (flags & DXGI_PRESENT_TEST) @@ -541,13 +547,11 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_Present1(IDXGISwapChain1 *iface, return S_OK; } - if (sync_interval) - FIXME("Unimplemented sync interval %u.\n", sync_interval); if (present_parameters) FIXME("Ignored present parameters %p.\n", present_parameters); wined3d_mutex_lock(); - hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, NULL, NULL, NULL, 0); + hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, NULL, NULL, NULL, sync_interval, 0); wined3d_mutex_unlock(); return hr; diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index f7ae3be184f..015b4c537ff 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -94,6 +94,7 @@ struct wined3d_cs_present struct wined3d_swapchain *swapchain; RECT src_rect; RECT dst_rect; + unsigned int swap_interval; DWORD flags; }; @@ -453,6 +454,12 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) swapchain = op->swapchain; wined3d_swapchain_set_window(swapchain, op->dst_window_override); + if (swapchain->desc.swap_interval != op->swap_interval) + { + swapchain->desc.swap_interval = op->swap_interval; + swapchain_update_swap_interval(swapchain); + } + swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags); wined3d_resource_release(&swapchain->front_buffer->resource); @@ -465,7 +472,8 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) } void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags) + const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, + unsigned int swap_interval, DWORD flags) { struct wined3d_cs_present *op; unsigned int i; @@ -477,6 +485,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw op->swapchain = swapchain; op->src_rect = *src_rect; op->dst_rect = *dst_rect; + op->swap_interval = swap_interval; op->flags = flags; pending = InterlockedIncrement(&cs->pending_presents); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index ea6a9848535..b9f2f630076 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -3685,7 +3685,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ /* Set the swap effect to COPY, we don't want the backbuffer to become * undefined. */ dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; - wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, 0); + wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, + dst_swapchain->desc.swap_interval, 0); dst_swapchain->desc.swap_effect = swap_effect; return WINED3D_OK; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 4903445a0f0..6bbba4d8f53 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -146,7 +146,8 @@ void CDECL wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWN } HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags) + const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, + unsigned int swap_interval, DWORD flags) { RECT s, d; @@ -159,7 +160,7 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, if (!swapchain->back_buffers) { - WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n"); + WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL.\n"); return WINED3DERR_INVALIDCALL; } @@ -177,7 +178,7 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, } wined3d_cs_emit_present(swapchain->device->cs, swapchain, src_rect, - dst_rect, dst_window_override, flags); + dst_rect, dst_window_override, swap_interval, flags); return WINED3D_OK; } diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index d2b6bef3634..16d22f5263a 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -281,7 +281,7 @@ @ cdecl wined3d_swapchain_get_desc(ptr ptr) @ cdecl wined3d_swapchain_get_raster_status(ptr ptr) @ cdecl wined3d_swapchain_incref(ptr) -@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr long) +@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr long long) @ cdecl wined3d_swapchain_resize_buffers(ptr long long long long long long) @ cdecl wined3d_swapchain_resize_target(ptr ptr) @ cdecl wined3d_swapchain_set_fullscreen(ptr ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 506f7dbf308..259ba85de42 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3546,8 +3546,8 @@ void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, GLenum primitive_type, void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags) DECLSPEC_HIDDEN; +void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect, + const RECT *dst_rect, HWND dst_window_override, unsigned int swap_interval, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state) DECLSPEC_HIDDEN; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index a4b939c4e2c..28afb013f42 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2654,8 +2654,8 @@ void __cdecl wined3d_swapchain_get_desc(const struct wined3d_swapchain *swapchai HRESULT __cdecl wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain, struct wined3d_raster_status *raster_status); ULONG __cdecl wined3d_swapchain_incref(struct wined3d_swapchain *swapchain); -HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags); +HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, + const RECT *dst_rect, HWND dst_window_override, unsigned int swap_interval, DWORD flags); HRESULT __cdecl wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count, unsigned int width, unsigned int height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality);