Commit 9d95bd5f authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ddraw: Support multiple devices per ddraw object.

parent 6fe8e64c
...@@ -420,6 +420,7 @@ static void ddraw_destroy_swapchain(struct ddraw *ddraw) ...@@ -420,6 +420,7 @@ static void ddraw_destroy_swapchain(struct ddraw *ddraw)
*****************************************************************************/ *****************************************************************************/
static void ddraw_destroy(struct ddraw *This) static void ddraw_destroy(struct ddraw *This)
{ {
struct d3d_device *device;
IDirectDraw7_SetCooperativeLevel(&This->IDirectDraw7_iface, NULL, DDSCL_NORMAL); IDirectDraw7_SetCooperativeLevel(&This->IDirectDraw7_iface, NULL, DDSCL_NORMAL);
IDirectDraw7_RestoreDisplayMode(&This->IDirectDraw7_iface); IDirectDraw7_RestoreDisplayMode(&This->IDirectDraw7_iface);
...@@ -440,8 +441,10 @@ static void ddraw_destroy(struct ddraw *This) ...@@ -440,8 +441,10 @@ static void ddraw_destroy(struct ddraw *This)
wined3d_device_decref(This->wined3d_device); wined3d_device_decref(This->wined3d_device);
wined3d_decref(This->wined3d); wined3d_decref(This->wined3d);
if (This->d3ddevice) LIST_FOR_EACH_ENTRY(device, &This->d3ddevice_list, struct d3d_device, ddraw_entry)
This->d3ddevice->ddraw = NULL; {
device->ddraw = NULL;
}
/* Now free the object */ /* Now free the object */
free(This); free(This);
...@@ -793,7 +796,6 @@ static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface) ...@@ -793,7 +796,6 @@ static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface)
static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
DWORD cooplevel, BOOL restore_mode_on_normal) DWORD cooplevel, BOOL restore_mode_on_normal)
{ {
struct wined3d_stateblock *stateblock;
BOOL restore_state = FALSE; BOOL restore_state = FALSE;
struct d3d_device *device; struct d3d_device *device;
RECT clip_rect; RECT clip_rect;
...@@ -923,18 +925,29 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ...@@ -923,18 +925,29 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED)) if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED))
wined3d_device_set_multithreaded(ddraw->wined3d_device); wined3d_device_set_multithreaded(ddraw->wined3d_device);
device = ddraw->d3ddevice;
if (ddraw->wined3d_swapchain) if (ddraw->wined3d_swapchain)
{ {
if (!(ddraw->flags & DDRAW_NO3D) && device) if (!(ddraw->flags & DDRAW_NO3D))
{ {
restore_state = TRUE; restore_state = TRUE;
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
device->state, WINED3D_SBT_ALL, &stateblock)))
{ {
ERR("Failed to create stateblock, hr %#lx.\n", hr); if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device,
goto done; device->state, WINED3D_SBT_ALL, &device->saved_state)))
{
struct list *entry;
ERR("Failed to create stateblock, hr %#lx.\n", hr);
entry = &device->ddraw_entry;
while ((entry = list_prev(&ddraw->d3ddevice_list, entry)))
{
device = LIST_ENTRY(entry, struct d3d_device, ddraw_entry);
wined3d_stateblock_decref(device->saved_state);
device->saved_state = NULL;
}
goto done;
}
} }
} }
...@@ -946,8 +959,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ...@@ -946,8 +959,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (restore_state) if (restore_state)
{ {
wined3d_stateblock_apply(stateblock, device->state); LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
wined3d_stateblock_decref(stateblock); {
wined3d_stateblock_apply(device->saved_state, device->state);
wined3d_stateblock_decref(device->saved_state);
device->saved_state = NULL;
}
} }
if (!(cooplevel & DDSCL_EXCLUSIVE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE)) if (!(cooplevel & DDSCL_EXCLUSIVE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE))
...@@ -5105,5 +5122,6 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de ...@@ -5105,5 +5122,6 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
ddraw->immediate_context = wined3d_device_get_immediate_context(ddraw->wined3d_device); ddraw->immediate_context = wined3d_device_get_immediate_context(ddraw->wined3d_device);
list_init(&ddraw->surface_list); list_init(&ddraw->surface_list);
list_init(&ddraw->d3ddevice_list);
return DD_OK; return DD_OK;
} }
...@@ -113,7 +113,7 @@ struct ddraw ...@@ -113,7 +113,7 @@ struct ddraw
/* D3D things */ /* D3D things */
HWND d3d_window; HWND d3d_window;
struct d3d_device *d3ddevice; struct list d3ddevice_list;
int d3dversion; int d3dversion;
/* Various HWNDs */ /* Various HWNDs */
...@@ -326,6 +326,7 @@ struct d3d_device ...@@ -326,6 +326,7 @@ struct d3d_device
struct wined3d_device *wined3d_device; struct wined3d_device *wined3d_device;
struct wined3d_device_context *immediate_context; struct wined3d_device_context *immediate_context;
struct ddraw *ddraw; struct ddraw *ddraw;
struct list ddraw_entry;
IUnknown *rt_iface; IUnknown *rt_iface;
struct ddraw_surface *target, *target_ds; struct ddraw_surface *target, *target_ds;
...@@ -362,6 +363,9 @@ struct d3d_device ...@@ -362,6 +363,9 @@ struct d3d_device
struct wined3d_stateblock *recording, *state, *update_state; struct wined3d_stateblock *recording, *state, *update_state;
const struct wined3d_stateblock_state *stateblock_state; const struct wined3d_stateblock_state *stateblock_state;
/* For temporary saving state during reset. */
struct wined3d_stateblock *saved_state;
}; };
HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface,
......
...@@ -329,7 +329,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) ...@@ -329,7 +329,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
* the device from it before so it doesn't try to save / restore state on the teared down device. */ * the device from it before so it doesn't try to save / restore state on the teared down device. */
if (This->ddraw) if (This->ddraw)
{ {
This->ddraw->d3ddevice = NULL; list_remove(&This->ddraw_entry);
This->ddraw = NULL; This->ddraw = NULL;
} }
...@@ -6907,7 +6907,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c ...@@ -6907,7 +6907,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c
if (version != 1) if (version != 1)
IUnknown_AddRef(device->rt_iface); IUnknown_AddRef(device->rt_iface);
ddraw->d3ddevice = device; list_add_head(&ddraw->d3ddevice_list, &device->ddraw_entry);
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE, wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
d3d_device_update_depth_stencil(device)); d3d_device_update_depth_stencil(device));
...@@ -6955,12 +6955,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su ...@@ -6955,12 +6955,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su
return DDERR_OUTOFMEMORY; return DDERR_OUTOFMEMORY;
} }
if (ddraw->d3ddevice)
{
FIXME("Only one Direct3D device per DirectDraw object supported.\n");
return DDERR_INVALIDPARAMS;
}
if (!(object = calloc(1, sizeof(*object)))) if (!(object = calloc(1, sizeof(*object))))
{ {
ERR("Failed to allocate device memory.\n"); ERR("Failed to allocate device memory.\n");
......
...@@ -892,8 +892,8 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) ...@@ -892,8 +892,8 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
WARN("DirectDraw object %p has reference counts {%lu, %lu, %lu, %lu, %lu}.\n", WARN("DirectDraw object %p has reference counts {%lu, %lu, %lu, %lu, %lu}.\n",
ddraw, ddraw->ref7, ddraw->ref4, ddraw->ref3, ddraw->ref2, ddraw->ref1); ddraw, ddraw->ref7, ddraw->ref4, ddraw->ref3, ddraw->ref2, ddraw->ref1);
if (ddraw->d3ddevice) if (!list_empty(&ddraw->d3ddevice_list))
WARN("DirectDraw object %p has Direct3D device %p attached.\n", ddraw, ddraw->d3ddevice); WARN("DirectDraw object %p has Direct3D device(s) attached.\n", ddraw);
LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry) LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry)
{ {
......
...@@ -2013,6 +2013,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Blt(IDirectDrawSurface2 * ...@@ -2013,6 +2013,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Blt(IDirectDrawSurface2 *
*****************************************************************************/ *****************************************************************************/
static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct ddraw_surface *Surf) static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct ddraw_surface *Surf)
{ {
struct d3d_device *device;
TRACE("surface %p, attachment %p.\n", This, Surf); TRACE("surface %p, attachment %p.\n", This, Surf);
if(Surf == This) if(Surf == This)
...@@ -2039,8 +2041,10 @@ static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct d ...@@ -2039,8 +2041,10 @@ static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct d
This->next_attached = Surf; This->next_attached = Surf;
/* Check if the WineD3D depth stencil needs updating */ /* Check if the WineD3D depth stencil needs updating */
if (This->ddraw->d3ddevice) LIST_FOR_EACH_ENTRY(device, &This->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
d3d_device_update_depth_stencil(This->ddraw->d3ddevice); {
d3d_device_update_depth_stencil(device);
}
wined3d_mutex_unlock(); wined3d_mutex_unlock();
...@@ -4361,7 +4365,7 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma ...@@ -4361,7 +4365,7 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma
if (surface->draw_texture) if (surface->draw_texture)
wined3d_texture_set_lod(surface->draw_texture, MaxLOD); wined3d_texture_set_lod(surface->draw_texture, MaxLOD);
if ((device = surface->ddraw->d3ddevice)) LIST_FOR_EACH_ENTRY(device, &surface->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
{ {
wined3d_stateblock_texture_changed(device->state, surface->wined3d_texture); wined3d_stateblock_texture_changed(device->state, surface->wined3d_texture);
if (surface->draw_texture) if (surface->draw_texture)
...@@ -6774,7 +6778,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ ...@@ -6774,7 +6778,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
swapchain_desc.backbuffer_height = mode.height; swapchain_desc.backbuffer_height = mode.height;
swapchain_desc.backbuffer_format = mode.format_id; swapchain_desc.backbuffer_format = mode.format_id;
if ((device = ddraw->d3ddevice)) LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
{ {
if (device->recording) if (device->recording)
wined3d_stateblock_decref(device->recording); wined3d_stateblock_decref(device->recording);
...@@ -6791,9 +6795,11 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ ...@@ -6791,9 +6795,11 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
return hr_ddraw_from_wined3d(hr); return hr_ddraw_from_wined3d(hr);
} }
if (device) LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
{
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE, wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
!!swapchain_desc.enable_auto_depth_stencil); !!swapchain_desc.enable_auto_depth_stencil);
}
} }
} }
......
...@@ -1523,13 +1523,8 @@ static void BackBuffer3DCreateSurfaceTest(void) ...@@ -1523,13 +1523,8 @@ static void BackBuffer3DCreateSurfaceTest(void)
"GetSurfaceDesc returned caps %#lx.\n", created_ddsd.ddsCaps.dwCaps); "GetSurfaceDesc returned caps %#lx.\n", created_ddsd.ddsCaps.dwCaps);
hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal); hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
/* Currently Wine only supports the creation of one Direct3D device ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
for a given DirectDraw instance. It has been created already IDirect3DDevice_Release(d3dhal);
in D3D1_createObjects() - IID_IDirect3DRGBDevice */
todo_wine ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
if (SUCCEEDED(hr))
IDirect3DDevice_Release(d3dhal);
IDirectDrawSurface_Release(surf); IDirectDrawSurface_Release(surf);
} }
......
...@@ -87,7 +87,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface) ...@@ -87,7 +87,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
* they are destroyed. */ * they are destroyed. */
wined3d_mutex_lock(); wined3d_mutex_lock();
if ((device = buffer->ddraw->d3ddevice)) LIST_FOR_EACH_ENTRY(device, &buffer->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
{ {
if (device->stateblock_state->streams[0].buffer == buffer->wined3d_buffer) if (device->stateblock_state->streams[0].buffer == buffer->wined3d_buffer)
wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0); wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0);
......
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