Commit b1568535 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Explicitly create the implicit swapchain.

parent f485816d
......@@ -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)
......
......@@ -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,
......
......@@ -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();
......
......@@ -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,
......
......@@ -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,16 +549,35 @@ 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)
static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, HWND window,
BOOL windowed, struct wined3d_swapchain **wined3d_swapchain)
{
HWND window = swapchain_desc->device_window;
struct wined3d_swapchain_desc swapchain_desc;
struct wined3d_display_mode mode;
HRESULT hr;
TRACE("ddraw %p.\n", ddraw);
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
{
ERR("Failed to get display mode.\n");
return hr;
}
memset(&swapchain_desc, 0, sizeof(swapchain_desc));
swapchain_desc.backbuffer_width = mode.width;
swapchain_desc.backbuffer_height = mode.height;
swapchain_desc.backbuffer_format = mode.format_id;
swapchain_desc.backbuffer_bind_flags = 0;
swapchain_desc.backbuffer_count = 1;
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 | WINED3D_SWAPCHAIN_IMPLICIT;
if (ddraw->flags & DDRAW_NO3D)
return wined3d_device_init_3d(ddraw->wined3d_device, swapchain_desc);
return wined3d_swapchain_create(ddraw->wined3d_device, &swapchain_desc,
NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain);
if (!window || window == GetDesktopWindow())
{
......@@ -576,7 +593,7 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw,
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;
swapchain_desc.device_window = window;
}
else
{
......@@ -587,9 +604,12 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw,
/* 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)))
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;
}
......@@ -598,7 +618,9 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw,
{
ERR("Error allocating an array for the converted vertex decls.\n");
ddraw->declArraySize = 0;
hr = wined3d_device_uninit_3d(ddraw->wined3d_device);
wined3d_swapchain_decref(*wined3d_swapchain);
DestroyWindow(window);
ddraw->d3d_window = NULL;
return E_OUTOFMEMORY;
}
......@@ -609,40 +631,21 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw,
static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL windowed)
{
struct wined3d_swapchain_desc swapchain_desc;
struct wined3d_display_mode mode;
HRESULT hr = WINED3D_OK;
HRESULT hr;
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
if (ddraw->wined3d_swapchain)
{
ERR("Failed to get display mode.\n");
return hr;
ERR("Swapchain already created.\n");
return E_FAIL;
}
memset(&swapchain_desc, 0, sizeof(swapchain_desc));
swapchain_desc.backbuffer_width = mode.width;
swapchain_desc.backbuffer_height = mode.height;
swapchain_desc.backbuffer_format = mode.format_id;
swapchain_desc.backbuffer_bind_flags = 0;
swapchain_desc.backbuffer_count = 1;
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;
if (FAILED(hr = ddraw_attach_d3d_device(ddraw, &swapchain_desc)))
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)
......
......@@ -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))))
{
ERR("Failed to allocate swapchain memory.\n");
return E_OUTOFMEMORY;
}
if (FAILED(hr = d3d11_swapchain_init(object, device, &wined3d_desc, FALSE)))
{
WARN("Failed to create swapchain, hr %#x.\n", hr);
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;
......
......@@ -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;
};
......
......@@ -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)
{
wined3d_device_set_rendertarget_view(device, i, NULL, FALSE);
}
if (device->back_buffer_view)
if ((view = 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);
......
......@@ -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;
......
......@@ -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)
......
......@@ -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
{
......
......@@ -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);
......
......@@ -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
);
}
[
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment