From b15685355c45c0fffb4f0dc5518c8c6ee0f595c6 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 12 Apr 2019 17:20:47 +0430 Subject: [PATCH] wined3d: Explicitly create the implicit swapchain. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/d3d11/device.c | 28 ------ dlls/d3d8/d3d8_private.h | 2 +- dlls/d3d8/device.c | 59 +++++------- dlls/d3d9/d3d9_private.h | 2 +- dlls/d3d9/device.c | 75 ++++++--------- dlls/ddraw/ddraw.c | 167 +++++++++++++++------------------ dlls/dxgi/device.c | 74 +++++++-------- dlls/dxgi/dxgi_private.h | 1 + dlls/wined3d/device.c | 103 ++++++++++---------- dlls/wined3d/swapchain.c | 21 ++++- dlls/wined3d/wined3d.spec | 2 - dlls/wined3d/wined3d_private.h | 3 + include/wine/wined3d.h | 5 +- include/wine/winedxgi.idl | 5 - 14 files changed, 236 insertions(+), 311 deletions(-) diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 877775fdd3a..588395b4b6a 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -6106,33 +6106,6 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic return S_OK; } -static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) -{ - struct d3d_device *device = device_from_wined3d_device_parent(device_parent); - IWineDXGIDevice *wine_device; - HRESULT hr; - - TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain); - - if (FAILED(hr = d3d11_device_QueryInterface(&device->ID3D11Device2_iface, - &IID_IWineDXGIDevice, (void **)&wine_device))) - { - ERR("Device should implement IWineDXGIDevice.\n"); - return E_FAIL; - } - - hr = IWineDXGIDevice_create_swapchain(wine_device, desc, TRUE, swapchain); - IWineDXGIDevice_Release(wine_device); - if (FAILED(hr)) - { - ERR("Failed to create DXGI swapchain, returning %#x\n", hr); - return hr; - } - - return S_OK; -} - static const struct wined3d_device_parent_ops d3d_wined3d_device_parent_ops = { device_parent_wined3d_device_created, @@ -6140,7 +6113,6 @@ static const struct wined3d_device_parent_ops d3d_wined3d_device_parent_ops = device_parent_activate, device_parent_texture_sub_resource_created, device_parent_create_swapchain_texture, - device_parent_create_swapchain, }; static int d3d_sampler_state_compare(const void *key, const struct wine_rb_entry *entry) diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index 0f861658cf4..1669ff74315 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -131,7 +131,7 @@ struct d3d8_device /* The d3d8 API supports only one implicit swapchain (no D3DCREATE_ADAPTERGROUP_DEVICE, * no GetSwapchain, GetBackBuffer doesn't accept a swapchain number). */ - struct d3d8_swapchain *implicit_swapchain; + struct wined3d_swapchain *implicit_swapchain; }; HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter, diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 3dce0f60462..974764cdf51 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -594,7 +594,7 @@ static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface) if (device->index_buffer) wined3d_buffer_decref(device->index_buffer); - wined3d_device_uninit_3d(device->wined3d_device); + wined3d_swapchain_decref(device->implicit_swapchain); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); heap_free(device->handle_table.entries); @@ -877,6 +877,7 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct wined3d_swapchain_desc swapchain_desc; + struct d3d8_swapchain *implicit_swapchain; HRESULT hr; TRACE("iface %p, present_parameters %p.\n", iface, present_parameters); @@ -888,6 +889,7 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, } if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters)) return D3DERR_INVALIDCALL; + swapchain_desc.flags |= WINED3D_SWAPCHAIN_IMPLICIT; wined3d_mutex_lock(); @@ -909,7 +911,8 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, { device->recording = FALSE; present_parameters->BackBufferCount = swapchain_desc.backbuffer_count; - device->implicit_swapchain->swap_interval + implicit_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchain); + implicit_swapchain->swap_interval = wined3dswapinterval_from_d3d(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, @@ -929,6 +932,7 @@ static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *s const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + struct d3d8_swapchain *implicit_swapchain; TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n", iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region); @@ -938,7 +942,8 @@ static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *s * shows a framerate on Windows in applications that only call the device * method, like e.g. the dx8 sdk samples. The conclusion is that native * calls the swapchain's public method from the device. */ - return IDirect3DSwapChain8_Present(&device->implicit_swapchain->IDirect3DSwapChain8_iface, + implicit_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchain); + return IDirect3DSwapChain8_Present(&implicit_swapchain->IDirect3DSwapChain8_iface, src_rect, dst_rect, dst_window_override, dirty_region); } @@ -946,7 +951,6 @@ static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface, UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); - struct wined3d_swapchain *wined3d_swapchain; struct wined3d_texture *wined3d_texture; struct d3d8_surface *surface_impl; @@ -958,8 +962,7 @@ static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface, /* No need to check for backbuffer == NULL, Windows crashes in that case. */ wined3d_mutex_lock(); - wined3d_swapchain = device->implicit_swapchain->wined3d_swapchain; - if (!(wined3d_texture = wined3d_swapchain_get_back_buffer(wined3d_swapchain, backbuffer_idx))) + if (!(wined3d_texture = wined3d_swapchain_get_back_buffer(device->implicit_swapchain, backbuffer_idx))) { wined3d_mutex_unlock(); *backbuffer = NULL; @@ -1387,7 +1390,7 @@ static HRESULT WINAPI d3d8_device_GetFrontBuffer(IDirect3DDevice8 *iface, IDirec } wined3d_mutex_lock(); - hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchain->wined3d_swapchain, + hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchain, dst_impl->wined3d_texture, dst_impl->sub_resource_idx); wined3d_mutex_unlock(); @@ -3532,29 +3535,6 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic return hr; } -static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) -{ - struct d3d8_device *device = device_from_device_parent(device_parent); - struct d3d8_swapchain *d3d_swapchain; - HRESULT hr; - - TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain); - - if (FAILED(hr = d3d8_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT, &d3d_swapchain))) - { - WARN("Failed to create swapchain, hr %#x.\n", hr); - *swapchain = NULL; - return hr; - } - - *swapchain = d3d_swapchain->wined3d_swapchain; - wined3d_swapchain_incref(*swapchain); - IDirect3DSwapChain8_Release(&d3d_swapchain->IDirect3DSwapChain8_iface); - - return hr; -} - static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops = { device_parent_wined3d_device_created, @@ -3562,7 +3542,6 @@ static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops = device_parent_activate, device_parent_texture_sub_resource_created, device_parent_create_swapchain_texture, - device_parent_create_swapchain, }; static void setup_fpu(void) @@ -3587,6 +3566,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine { struct wined3d_swapchain_desc swapchain_desc; struct wined3d_swapchain *wined3d_swapchain; + struct d3d8_swapchain *d3d_swapchain; HRESULT hr; static const enum wined3d_feature_level feature_levels[] = @@ -3654,10 +3634,12 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine heap_free(device->handle_table.entries); return D3DERR_INVALIDCALL; } + swapchain_desc.flags |= WINED3D_SWAPCHAIN_IMPLICIT; - if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc))) + if (FAILED(hr = d3d8_swapchain_create(device, &swapchain_desc, + wined3dswapinterval_from_d3d(parameters->FullScreen_PresentationInterval), &d3d_swapchain))) { - WARN("Failed to initialize 3D, hr %#x.\n", hr); + WARN("Failed to create implicit swapchain, hr %#x.\n", hr); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); @@ -3665,6 +3647,10 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine return hr; } + wined3d_swapchain = d3d_swapchain->wined3d_swapchain; + wined3d_swapchain_incref(wined3d_swapchain); + IDirect3DSwapChain8_Release(&d3d_swapchain->IDirect3DSwapChain8_iface); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); @@ -3681,10 +3667,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine goto err; } - 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_d3d(parameters->FullScreen_PresentationInterval); + device->implicit_swapchain = wined3d_swapchain; device->d3d_parent = &parent->IDirect3D8_iface; IDirect3D8_AddRef(device->d3d_parent); @@ -3693,7 +3676,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine err: wined3d_mutex_lock(); - wined3d_device_uninit_3d(device->wined3d_device); + wined3d_swapchain_decref(wined3d_swapchain); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index b07d72a0662..8ee521b14b0 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -116,7 +116,7 @@ struct d3d9_device unsigned int max_user_clip_planes; UINT implicit_swapchain_count; - struct d3d9_swapchain **implicit_swapchains; + struct wined3d_swapchain **implicit_swapchains; }; HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wined3d *wined3d, diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index f7f9358913d..999969119e3 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -599,9 +599,12 @@ static ULONG WINAPI DECLSPEC_HOTPATCH d3d9_device_Release(IDirect3DDevice9Ex *if if (device->index_buffer) wined3d_buffer_decref(device->index_buffer); + for (i = 0; i < device->implicit_swapchain_count; ++i) + { + wined3d_swapchain_decref(device->implicit_swapchains[i]); + } heap_free(device->implicit_swapchains); - wined3d_device_uninit_3d(device->wined3d_device); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); @@ -838,6 +841,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_GetSwapChain(IDirect3DDevice UINT swapchain_idx, IDirect3DSwapChain9 **swapchain) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct d3d9_swapchain *d3d9_swapchain; HRESULT hr; TRACE("iface %p, swapchain_idx %u, swapchain %p.\n", iface, swapchain_idx, swapchain); @@ -845,7 +849,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_GetSwapChain(IDirect3DDevice wined3d_mutex_lock(); if (swapchain_idx < device->implicit_swapchain_count) { - *swapchain = (IDirect3DSwapChain9 *)&device->implicit_swapchains[swapchain_idx]->IDirect3DSwapChain9Ex_iface; + d3d9_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[swapchain_idx]); + *swapchain = (IDirect3DSwapChain9 *)&d3d9_swapchain->IDirect3DSwapChain9Ex_iface; IDirect3DSwapChain9Ex_AddRef(*swapchain); hr = D3D_OK; } @@ -924,15 +929,13 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) static HRESULT d3d9_device_get_swapchains(struct d3d9_device *device) { UINT i, new_swapchain_count = wined3d_device_get_swapchain_count(device->wined3d_device); - struct wined3d_swapchain *wined3d_swapchain; if (!(device->implicit_swapchains = heap_alloc(new_swapchain_count * sizeof(*device->implicit_swapchains)))) return E_OUTOFMEMORY; for (i = 0; i < new_swapchain_count; ++i) { - wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i); - device->implicit_swapchains[i] = wined3d_swapchain_get_parent(wined3d_swapchain); + device->implicit_swapchains[i] = wined3d_device_get_swapchain(device->wined3d_device, i); } device->implicit_swapchain_count = new_swapchain_count; @@ -946,6 +949,7 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, struct wined3d_swapchain_desc swapchain_desc; struct wined3d_display_mode wined3d_mode; struct wined3d_rendertarget_view *rtv; + struct d3d9_swapchain *d3d9_swapchain; unsigned int i; HRESULT hr; @@ -966,6 +970,7 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters, extended)) return D3DERR_INVALIDCALL; + swapchain_desc.flags |= WINED3D_SWAPCHAIN_IMPLICIT; wined3d_mutex_lock(); @@ -1002,9 +1007,10 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, } else { - device->implicit_swapchains[0]->swap_interval + d3d9_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[0]); + d3d9_swapchain->swap_interval = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval); - wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc); + wined3d_swapchain_get_desc(d3d9_swapchain->wined3d_swapchain, &swapchain_desc); present_parameters->BackBufferWidth = swapchain_desc.backbuffer_width; present_parameters->BackBufferHeight = swapchain_desc.backbuffer_height; present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc.backbuffer_format); @@ -1058,7 +1064,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex * wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - swapchain = device->implicit_swapchains[i]; + swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[i]); if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0))) { @@ -1075,6 +1081,7 @@ static HRESULT WINAPI d3d9_device_GetBackBuffer(IDirect3DDevice9Ex *iface, UINT UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct d3d9_swapchain *d3d9_swapchain; HRESULT hr; TRACE("iface %p, swapchain %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", @@ -1093,7 +1100,8 @@ static HRESULT WINAPI d3d9_device_GetBackBuffer(IDirect3DDevice9Ex *iface, UINT return D3DERR_INVALIDCALL; } - hr = IDirect3DSwapChain9Ex_GetBackBuffer(&device->implicit_swapchains[swapchain]->IDirect3DSwapChain9Ex_iface, + d3d9_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[swapchain]); + hr = IDirect3DSwapChain9Ex_GetBackBuffer(&d3d9_swapchain->IDirect3DSwapChain9Ex_iface, backbuffer_idx, backbuffer_type, backbuffer); wined3d_mutex_unlock(); @@ -1645,7 +1653,7 @@ static HRESULT WINAPI d3d9_device_GetFrontBufferData(IDirect3DDevice9Ex *iface, wined3d_mutex_lock(); if (swapchain < device->implicit_swapchain_count) - hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchains[swapchain]->wined3d_swapchain, + hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchains[swapchain], dst_impl->wined3d_texture, dst_impl->sub_resource_idx); wined3d_mutex_unlock(); @@ -3953,7 +3961,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - swapchain = device->implicit_swapchains[i]; + swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[i]); if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags))) { @@ -4033,7 +4041,7 @@ static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HW TRACE("iface %p, dst_window %p.\n", iface, dst_window); wined3d_mutex_lock(); - wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc); + wined3d_swapchain_get_desc(device->implicit_swapchains[0], &swapchain_desc); wined3d_mutex_unlock(); if (swapchain_desc.windowed) @@ -4397,29 +4405,6 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic return hr; } -static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) -{ - struct d3d9_device *device = device_from_device_parent(device_parent); - struct d3d9_swapchain *d3d_swapchain; - HRESULT hr; - - TRACE("device_parent %p, desc %p, swapchain %p\n", device_parent, desc, swapchain); - - if (FAILED(hr = d3d9_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT, &d3d_swapchain))) - { - WARN("Failed to create swapchain, hr %#x.\n", hr); - *swapchain = NULL; - return hr; - } - - *swapchain = d3d_swapchain->wined3d_swapchain; - wined3d_swapchain_incref(*swapchain); - IDirect3DSwapChain9Ex_Release(&d3d_swapchain->IDirect3DSwapChain9Ex_iface); - - return hr; -} - static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops = { device_parent_wined3d_device_created, @@ -4427,7 +4412,6 @@ static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops = device_parent_activate, device_parent_texture_sub_resource_created, device_parent_create_swapchain_texture, - device_parent_create_swapchain, }; static void setup_fpu(void) @@ -4452,6 +4436,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode) { struct wined3d_swapchain_desc *swapchain_desc; + struct d3d9_swapchain *d3d_swapchain; struct wined3d_caps caps; unsigned i, count = 1; HRESULT hr; @@ -4537,11 +4522,13 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } + swapchain_desc[i].flags |= WINED3D_SWAPCHAIN_IMPLICIT; } - if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc))) + if (FAILED(hr = d3d9_swapchain_create(device, swapchain_desc, + wined3dswapinterval_from_d3d(parameters->PresentationInterval), &d3d_swapchain))) { - WARN("Failed to initialize 3D, hr %#x.\n", hr); + WARN("Failed to create swapchain, hr %#x.\n", hr); wined3d_device_release_focus_window(device->wined3d_device); heap_free(swapchain_desc); wined3d_device_decref(device->wined3d_device); @@ -4549,22 +4536,20 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine return hr; } + wined3d_swapchain_incref(d3d_swapchain->wined3d_swapchain); + IDirect3DSwapChain9Ex_Release(&d3d_swapchain->IDirect3DSwapChain9Ex_iface); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc->enable_auto_depth_stencil); if (FAILED(hr = d3d9_device_get_swapchains(device))) { - wined3d_device_uninit_3d(device->wined3d_device); + wined3d_swapchain_decref(d3d_swapchain->wined3d_swapchain); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); return E_OUTOFMEMORY; } - for (i = 0; i < device->implicit_swapchain_count; ++i) - { - device->implicit_swapchains[i]->swap_interval - = wined3dswapinterval_from_d3d(parameters[i].PresentationInterval); - } for (i = 0; i < count; ++i) { @@ -4583,7 +4568,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine ERR("Failed to allocate FVF vertex declaration map memory.\n"); wined3d_mutex_lock(); heap_free(device->implicit_swapchains); - wined3d_device_uninit_3d(device->wined3d_device); + wined3d_swapchain_decref(d3d_swapchain->wined3d_swapchain); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index b2097726076..b005f10826d 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -366,12 +366,10 @@ static ULONG WINAPI d3d1_AddRef(IDirect3D *iface) static void ddraw_destroy_swapchain(struct ddraw *ddraw) { unsigned int i; - HRESULT hr; TRACE("Destroying the swapchain.\n"); wined3d_swapchain_decref(ddraw->wined3d_swapchain); - ddraw->wined3d_swapchain = NULL; for (i = 0; i < ddraw->numConvertedDecls; ++i) { @@ -380,8 +378,8 @@ static void ddraw_destroy_swapchain(struct ddraw *ddraw) heap_free(ddraw->decls); ddraw->numConvertedDecls = 0; - if (FAILED(hr = wined3d_device_uninit_3d(ddraw->wined3d_device))) - ERR("Failed to uninit 3D, hr %#x.\n", hr); + wined3d_swapchain_decref(ddraw->wined3d_swapchain); + ddraw->wined3d_swapchain = NULL; /* Free the d3d window if one was created. */ if (ddraw->d3d_window && ddraw->d3d_window != ddraw->dest_window) @@ -551,67 +549,14 @@ static HRESULT ddraw_set_focus_window(struct ddraw *ddraw, HWND window) return DD_OK; } -static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, - struct wined3d_swapchain_desc *swapchain_desc) -{ - HWND window = swapchain_desc->device_window; - HRESULT hr; - - TRACE("ddraw %p.\n", ddraw); - - if (ddraw->flags & DDRAW_NO3D) - return wined3d_device_init_3d(ddraw->wined3d_device, swapchain_desc); - - if (!window || window == GetDesktopWindow()) - { - window = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "Hidden D3D Window", - WS_DISABLED, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), - NULL, NULL, NULL, NULL); - if (!window) - { - ERR("Failed to create window, last error %#x.\n", GetLastError()); - return E_FAIL; - } - - ShowWindow(window, SW_HIDE); /* Just to be sure */ - WARN("No window for the Direct3DDevice, created hidden window %p.\n", window); - - swapchain_desc->device_window = window; - } - else - { - TRACE("Using existing window %p for Direct3D rendering.\n", window); - } - ddraw->d3d_window = window; - - /* Set this NOW, otherwise creating the depth stencil surface will cause a - * recursive loop until ram or emulated video memory is full. */ - ddraw->flags |= DDRAW_D3D_INITIALIZED; - if (FAILED(hr = wined3d_device_init_3d(ddraw->wined3d_device, swapchain_desc))) - { - ddraw->flags &= ~DDRAW_D3D_INITIALIZED; - return hr; - } - - ddraw->declArraySize = 2; - if (!(ddraw->decls = heap_alloc_zero(ddraw->declArraySize * sizeof(*ddraw->decls)))) - { - ERR("Error allocating an array for the converted vertex decls.\n"); - ddraw->declArraySize = 0; - hr = wined3d_device_uninit_3d(ddraw->wined3d_device); - return E_OUTOFMEMORY; - } - - TRACE("Successfully initialized 3D.\n"); - - return DD_OK; -} - -static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL windowed) +static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, HWND window, + BOOL windowed, struct wined3d_swapchain **wined3d_swapchain) { struct wined3d_swapchain_desc swapchain_desc; struct wined3d_display_mode mode; - HRESULT hr = WINED3D_OK; + HRESULT hr; + + TRACE("ddraw %p.\n", ddraw); if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL))) { @@ -628,21 +573,79 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; swapchain_desc.device_window = window; swapchain_desc.windowed = windowed; - swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; + swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH | WINED3D_SWAPCHAIN_IMPLICIT; - if (FAILED(hr = ddraw_attach_d3d_device(ddraw, &swapchain_desc))) + if (ddraw->flags & DDRAW_NO3D) + return wined3d_swapchain_create(ddraw->wined3d_device, &swapchain_desc, + NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain); + + if (!window || window == GetDesktopWindow()) + { + window = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "Hidden D3D Window", + WS_DISABLED, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), + NULL, NULL, NULL, NULL); + if (!window) + { + ERR("Failed to create window, last error %#x.\n", GetLastError()); + return E_FAIL; + } + + ShowWindow(window, SW_HIDE); /* Just to be sure */ + WARN("No window for the Direct3DDevice, created hidden window %p.\n", window); + + swapchain_desc.device_window = window; + } + else + { + TRACE("Using existing window %p for Direct3D rendering.\n", window); + } + ddraw->d3d_window = window; + + /* Set this NOW, otherwise creating the depth stencil surface will cause a + * recursive loop until ram or emulated video memory is full. */ + ddraw->flags |= DDRAW_D3D_INITIALIZED; + if (FAILED(hr = wined3d_swapchain_create(ddraw->wined3d_device, &swapchain_desc, + NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain))) + { + ddraw->flags &= ~DDRAW_D3D_INITIALIZED; + DestroyWindow(window); + ddraw->d3d_window = NULL; + return hr; + } + + ddraw->declArraySize = 2; + if (!(ddraw->decls = heap_alloc_zero(ddraw->declArraySize * sizeof(*ddraw->decls)))) + { + ERR("Error allocating an array for the converted vertex decls.\n"); + ddraw->declArraySize = 0; + wined3d_swapchain_decref(*wined3d_swapchain); + DestroyWindow(window); + ddraw->d3d_window = NULL; + return E_OUTOFMEMORY; + } + + TRACE("Successfully initialized 3D.\n"); + + return DD_OK; +} + +static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL windowed) +{ + HRESULT hr; + + if (ddraw->wined3d_swapchain) + { + ERR("Swapchain already created.\n"); + return E_FAIL; + } + + if (FAILED(hr = ddraw_attach_d3d_device(ddraw, window, windowed, &ddraw->wined3d_swapchain))) { ERR("Failed to create swapchain, hr %#x.\n", hr); return hr; } - - if (!(ddraw->wined3d_swapchain = wined3d_device_get_swapchain(ddraw->wined3d_device, 0))) - { - ERR("Failed to get swapchain.\n"); - return DDERR_INVALIDPARAMS; - } - wined3d_swapchain_incref(ddraw->wined3d_swapchain); + ddraw_set_swapchain_window(ddraw, window); if (ddraw->primary && ddraw->primary->palette) @@ -4967,27 +4970,6 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic return hr; } -static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) -{ - struct ddraw *ddraw = ddraw_from_device_parent(device_parent); - HRESULT hr; - - TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain); - - if (ddraw->wined3d_swapchain) - { - ERR("Swapchain already created.\n"); - return E_FAIL; - } - - if (FAILED(hr = wined3d_swapchain_create(ddraw->wined3d_device, desc, NULL, - &ddraw_null_wined3d_parent_ops, swapchain))) - WARN("Failed to create swapchain, hr %#x.\n", hr); - - return hr; -} - static const struct wined3d_device_parent_ops ddraw_wined3d_device_parent_ops = { device_parent_wined3d_device_created, @@ -4995,7 +4977,6 @@ static const struct wined3d_device_parent_ops ddraw_wined3d_device_parent_ops = device_parent_activate, device_parent_texture_sub_resource_created, device_parent_create_swapchain_texture, - device_parent_create_swapchain, }; HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type device_type) diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index c7d663f953b..d6dd0418c47 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -90,7 +90,7 @@ static ULONG STDMETHODCALLTYPE dxgi_device_Release(IWineDXGIDevice *iface) if (device->child_layer) IUnknown_Release(device->child_layer); wined3d_mutex_lock(); - wined3d_device_uninit_3d(device->wined3d_device); + wined3d_swapchain_decref(device->implicit_swapchain); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); IWineDXGIAdapter_Release(device->adapter); @@ -352,35 +352,6 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *ifa return S_OK; } -static HRESULT STDMETHODCALLTYPE dxgi_device_create_swapchain(IWineDXGIDevice *iface, - struct wined3d_swapchain_desc *desc, BOOL implicit, struct wined3d_swapchain **wined3d_swapchain) -{ - struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); - struct d3d11_swapchain *object; - HRESULT hr; - - TRACE("iface %p, desc %p, wined3d_swapchain %p.\n", - iface, desc, wined3d_swapchain); - - if (!(object = heap_alloc_zero(sizeof(*object)))) - { - ERR("Failed to allocate DXGI swapchain object memory\n"); - return E_OUTOFMEMORY; - } - - if (FAILED(hr = d3d11_swapchain_init(object, device, desc, implicit))) - { - WARN("Failed to initialize swapchain, hr %#x.\n", hr); - heap_free(object); - return hr; - } - - TRACE("Created IDXGISwapChain %p.\n", object); - *wined3d_swapchain = object->wined3d_swapchain; - - return S_OK; -} - static const struct IWineDXGIDeviceVtbl dxgi_device_vtbl = { /* IUnknown methods */ @@ -407,7 +378,6 @@ static const struct IWineDXGIDeviceVtbl dxgi_device_vtbl = dxgi_device_EnqueueSetEvent, /* IWineDXGIDevice methods */ dxgi_device_create_surface, - dxgi_device_create_swapchain, }; static inline struct dxgi_device *impl_from_IWineDXGISwapChainFactory(IWineDXGISwapChainFactory *iface) @@ -448,8 +418,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_create_swapchain(IWineDX const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, IDXGIOutput *output, IDXGISwapChain1 **swapchain) { struct dxgi_device *device = impl_from_IWineDXGISwapChainFactory(iface); - struct wined3d_swapchain *wined3d_swapchain; struct wined3d_swapchain_desc wined3d_desc; + struct d3d11_swapchain *object; HRESULT hr; TRACE("iface %p, factory %p, window %p, desc %p, fullscreen_desc %p, output %p, swapchain %p.\n", @@ -498,16 +468,22 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_create_swapchain(IWineDX wined3d_desc.refresh_rate = fullscreen_desc ? dxgi_rational_to_uint(&fullscreen_desc->RefreshRate) : 0; wined3d_desc.auto_restore_display_mode = TRUE; - if (FAILED(hr = dxgi_device_create_swapchain(&device->IWineDXGIDevice_iface, - &wined3d_desc, FALSE, &wined3d_swapchain))) + if (!(object = heap_alloc_zero(sizeof(*object)))) { - WARN("Failed to create swapchain, hr %#x.\n", hr); + ERR("Failed to allocate swapchain memory.\n"); + return E_OUTOFMEMORY; + } + + if (FAILED(hr = d3d11_swapchain_init(object, device, &wined3d_desc, FALSE))) + { + WARN("Failed to initialise swapchain, hr %#x.\n", hr); + heap_free(object); return hr; } - wined3d_mutex_lock(); - *swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); - wined3d_mutex_unlock(); + TRACE("Created swapchain %p.\n", object); + + *swapchain = &object->IDXGISwapChain1_iface; return S_OK; } @@ -527,6 +503,7 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l struct wined3d_device_parent *wined3d_device_parent; struct wined3d_swapchain_desc swapchain_desc; IWineDXGIDeviceParent *dxgi_device_parent; + struct d3d11_swapchain *swapchain; struct dxgi_adapter *dxgi_adapter; struct dxgi_factory *dxgi_factory; void *layer_base; @@ -589,15 +566,32 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; swapchain_desc.device_window = dxgi_factory_get_device_window(dxgi_factory); swapchain_desc.windowed = TRUE; - if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc))) + swapchain_desc.flags = WINED3D_SWAPCHAIN_IMPLICIT; + + if (!(swapchain = heap_alloc_zero(sizeof(*swapchain)))) { - ERR("Failed to initialize 3D, hr %#x.\n", hr); + ERR("Failed to allocate swapchain memory.\n"); + wined3d_device_decref(device->wined3d_device); + IUnknown_Release(device->child_layer); + wined3d_private_store_cleanup(&device->private_store); + wined3d_mutex_unlock(); + return E_OUTOFMEMORY; + } + + if (FAILED(hr = d3d11_swapchain_init(swapchain, device, &swapchain_desc, TRUE))) + { + WARN("Failed to initialize swapchain, hr %#x.\n", hr); + heap_free(swapchain); wined3d_device_decref(device->wined3d_device); IUnknown_Release(device->child_layer); wined3d_private_store_cleanup(&device->private_store); wined3d_mutex_unlock(); return hr; } + device->implicit_swapchain = swapchain->wined3d_swapchain; + + TRACE("Created swapchain %p.\n", swapchain); + wined3d_mutex_unlock(); device->adapter = &dxgi_adapter->IWineDXGIAdapter_iface; diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index 1461e3c3af7..5c5775ca377 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -130,6 +130,7 @@ struct dxgi_device LONG refcount; struct wined3d_private_store private_store; struct wined3d_device *wined3d_device; + struct wined3d_swapchain *implicit_swapchain; IWineDXGIAdapter *adapter; }; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index a0c44b5d41c..361ac6b1e36 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -486,6 +486,9 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device) { UINT i; + if (device->swapchain_count) + wined3d_device_uninit_3d(device); + wined3d_stateblock_state_cleanup(&device->stateblock_state); wined3d_cs_destroy(device->cs); @@ -1067,30 +1070,19 @@ static HRESULT wined3d_device_create_primary_opengl_context(struct wined3d_devic return WINED3D_OK; } -HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - struct wined3d_swapchain_desc *swapchain_desc) +HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device, struct wined3d_swapchain *swapchain) { static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; - struct wined3d_swapchain *swapchain = NULL; + const struct wined3d_swapchain_desc *swapchain_desc; DWORD clear_flags = 0; HRESULT hr; - TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc); + TRACE("device %p, swapchain %p.\n", device, swapchain); if (device->d3d_initialized) return WINED3DERR_INVALIDCALL; - memset(device->fb.render_targets, 0, sizeof(device->fb.render_targets)); - - /* Setup the implicit swapchain. This also initializes a context. */ - TRACE("Creating implicit swapchain.\n"); - if (FAILED(hr = device->device_parent->ops->create_swapchain(device->device_parent, - swapchain_desc, &swapchain))) - { - WARN("Failed to create implicit swapchain.\n"); - goto err_out; - } - + swapchain_desc = &swapchain->desc; if (swapchain_desc->backbuffer_count && swapchain_desc->backbuffer_bind_flags & WINED3D_BIND_RENDER_TARGET) { struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource; @@ -1106,18 +1098,20 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr); - goto err_out; + return hr; } } device->swapchain_count = 1; if (!(device->swapchains = heap_calloc(device->swapchain_count, sizeof(*device->swapchains)))) { - ERR("Out of memory!\n"); + ERR("Failed to allocate swapchain array.\n"); + hr = E_OUTOFMEMORY; goto err_out; } device->swapchains[0] = swapchain; + memset(device->fb.render_targets, 0, sizeof(device->fb.render_targets)); if (device->wined3d->flags & WINED3D_NO3D) { if (!(device->blitter = wined3d_cpu_blitter_create())) @@ -1125,6 +1119,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, ERR("Failed to create CPU blitter.\n"); heap_free(device->swapchains); device->swapchain_count = 0; + hr = E_FAIL; goto err_out; } } @@ -1156,11 +1151,13 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, err_out: heap_free(device->swapchains); + device->swapchains = NULL; device->swapchain_count = 0; if (device->back_buffer_view) + { wined3d_rendertarget_view_decref(device->back_buffer_view); - if (swapchain) - wined3d_swapchain_decref(swapchain); + device->back_buffer_view = NULL; + } return hr; } @@ -1172,24 +1169,42 @@ static void device_free_sampler(struct wine_rb_entry *entry, void *context) wined3d_sampler_decref(sampler); } -HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) +void wined3d_device_uninit_3d(struct wined3d_device *device) { BOOL no3d = device->wined3d->flags & WINED3D_NO3D; + struct wined3d_rendertarget_view *view; + struct wined3d_texture *texture; unsigned int i; TRACE("device %p.\n", device); if (!device->d3d_initialized && !no3d) - return WINED3DERR_INVALIDCALL; + { + ERR("Called while 3D support was not initialised.\n"); + return; + } wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (device->logo_texture) - wined3d_texture_decref(device->logo_texture); - if (device->cursor_texture) - wined3d_texture_decref(device->cursor_texture); + device->swapchain_count = 0; + + if ((texture = device->logo_texture)) + { + device->logo_texture = NULL; + wined3d_texture_decref(texture); + } + + if ((texture = device->cursor_texture)) + { + device->cursor_texture = NULL; + wined3d_texture_decref(texture); + } state_unbind_resources(&device->state); + for (i = 0; i < device->adapter->d3d_info.limits.max_rt_count; ++i) + { + wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); + } wine_rb_clear(&device->samplers, device_free_sampler, NULL); @@ -1198,49 +1213,31 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) else wined3d_device_delete_opengl_contexts(device); - if (device->fb.depth_stencil) + if ((view = device->fb.depth_stencil)) { - struct wined3d_rendertarget_view *view = device->fb.depth_stencil; - TRACE("Releasing depth/stencil view %p.\n", view); device->fb.depth_stencil = NULL; wined3d_rendertarget_view_decref(view); } - if (device->auto_depth_stencil_view) + if ((view = device->auto_depth_stencil_view)) { - struct wined3d_rendertarget_view *view = device->auto_depth_stencil_view; - device->auto_depth_stencil_view = NULL; if (wined3d_rendertarget_view_decref(view)) ERR("Something's still holding the auto depth/stencil view (%p).\n", view); } - for (i = 0; i < device->adapter->d3d_info.limits.max_rt_count; ++i) + if ((view = device->back_buffer_view)) { - wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); - } - if (device->back_buffer_view) - { - wined3d_rendertarget_view_decref(device->back_buffer_view); device->back_buffer_view = NULL; - } - - for (i = 0; i < device->swapchain_count; ++i) - { - TRACE("Releasing the implicit swapchain %u.\n", i); - if (wined3d_swapchain_decref(device->swapchains[i])) - FIXME("Something's still holding the implicit swapchain.\n"); + wined3d_rendertarget_view_decref(view); } heap_free(device->swapchains); device->swapchains = NULL; - device->swapchain_count = 0; device->d3d_initialized = FALSE; - - return WINED3D_OK; } /* Enables thread safety in the wined3d device and its resources. Called by DirectDraw @@ -4825,6 +4822,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct wined3d_resource *resource, *cursor; + struct wined3d_rendertarget_view *view; struct wined3d_swapchain *swapchain; struct wined3d_view_desc view_desc; BOOL backbuffer_resized; @@ -4959,10 +4957,10 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, } } - if (device->auto_depth_stencil_view) + if ((view = device->auto_depth_stencil_view)) { - wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); device->auto_depth_stencil_view = NULL; + wined3d_rendertarget_view_decref(view); } if (swapchain->desc.enable_auto_depth_stencil) { @@ -5008,10 +5006,10 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view); } - if (device->back_buffer_view) + if ((view = device->back_buffer_view)) { - wined3d_rendertarget_view_decref(device->back_buffer_view); device->back_buffer_view = NULL; + wined3d_rendertarget_view_decref(view); } if (swapchain->desc.backbuffer_count && swapchain->desc.backbuffer_bind_flags & WINED3D_BIND_RENDER_TARGET) { @@ -5057,9 +5055,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, if (wined3d_settings.logo) device_load_logo(device, wined3d_settings.logo); } - else if (device->back_buffer_view) + else if ((view = device->back_buffer_view)) { - struct wined3d_rendertarget_view *view = device->back_buffer_view; struct wined3d_state *state = &device->state; wined3d_device_set_rendertarget_view(device, 0, view, FALSE); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index c5060f93fc3..c1429de91b1 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -114,9 +114,14 @@ ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain) if (!refcount) { + struct wined3d_device *device; + wined3d_mutex_lock(); - wined3d_cs_finish(swapchain->device->cs, WINED3D_CS_QUEUE_DEFAULT); + device = swapchain->device; + if (device->swapchain_count && device->swapchains[0] == swapchain) + wined3d_device_uninit_3d(device); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); swapchain_cleanup(swapchain); swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent); @@ -1053,6 +1058,20 @@ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct win return hr; } + if (desc->flags & WINED3D_SWAPCHAIN_IMPLICIT) + { + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_device_set_implicit_swapchain(device, object))) + { + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + swapchain_cleanup(object); + wined3d_mutex_unlock(); + heap_free(swapchain); + return hr; + } + wined3d_mutex_unlock(); + } + TRACE("Created swapchain %p.\n", object); *swapchain = object; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 704e19db46b..040b9fc4ac1 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -120,7 +120,6 @@ @ cdecl wined3d_device_get_vs_sampler(ptr long) @ cdecl wined3d_device_get_wined3d(ptr) @ cdecl wined3d_device_incref(ptr) -@ cdecl wined3d_device_init_3d(ptr ptr) @ cdecl wined3d_device_multiply_transform(ptr long ptr) @ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long) @ cdecl wined3d_device_release_focus_window(ptr) @@ -188,7 +187,6 @@ @ cdecl wined3d_device_set_vs_sampler(ptr long ptr) @ cdecl wined3d_device_setup_fullscreen_window(ptr ptr long long) @ cdecl wined3d_device_show_cursor(ptr long) -@ cdecl wined3d_device_uninit_3d(ptr) @ cdecl wined3d_device_update_sub_resource(ptr ptr long ptr ptr long long long) @ cdecl wined3d_device_update_texture(ptr ptr ptr) @ cdecl wined3d_device_validate_device(ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bfc911ef473..9f63f3d8d62 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3177,6 +3177,9 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; +HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +void wined3d_device_uninit_3d(struct wined3d_device *device) DECLSPEC_HIDDEN; struct wined3d_device_gl { diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 8a29ef63999..958ade166c0 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -902,6 +902,7 @@ enum wined3d_shader_type #define WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE 0x00002000u #define WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT 0x00004000u #define WINED3D_SWAPCHAIN_GDI_COMPATIBLE 0x00008000u +#define WINED3D_SWAPCHAIN_IMPLICIT 0x00010000u #define WINED3DDP_MAXTEXCOORD 8 @@ -2145,8 +2146,6 @@ struct wined3d_device_parent_ops void **parent, const struct wined3d_parent_ops **parent_ops); HRESULT (__cdecl *create_swapchain_texture)(struct wined3d_device_parent *device_parent, void *parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, struct wined3d_texture **texture); - HRESULT (__cdecl *create_swapchain)(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain); }; struct wined3d_private_store @@ -2363,7 +2362,6 @@ struct wined3d_shader_resource_view * __cdecl wined3d_device_get_vs_resource_vie struct wined3d_sampler * __cdecl wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx); struct wined3d * __cdecl wined3d_device_get_wined3d(const struct wined3d_device *device); ULONG __cdecl wined3d_device_incref(struct wined3d_device *device); -HRESULT __cdecl wined3d_device_init_3d(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc); void __cdecl wined3d_device_multiply_transform(struct wined3d_device *device, enum wined3d_transform_state state, const struct wined3d_matrix *matrix); HRESULT __cdecl wined3d_device_process_vertices(struct wined3d_device *device, @@ -2480,7 +2478,6 @@ void __cdecl wined3d_device_set_vs_resource_view(struct wined3d_device *device, void __cdecl wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler); void __cdecl wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, UINT w, UINT h); BOOL __cdecl wined3d_device_show_cursor(struct wined3d_device *device, BOOL show); -HRESULT __cdecl wined3d_device_uninit_3d(struct wined3d_device *device); void __cdecl wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, unsigned int depth_pitch, unsigned int flags); diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl index 84440901a9e..610b7c0485c 100644 --- a/include/wine/winedxgi.idl +++ b/include/wine/winedxgi.idl @@ -51,11 +51,6 @@ interface IWineDXGIDevice : IDXGIDevice2 [in] IUnknown *outer, [out] void **surface ); - HRESULT create_swapchain( - [in] struct wined3d_swapchain_desc *desc, - [in] BOOL implicit, - [out] struct wined3d_swapchain **wined3d_swapchain - ); } [