ddraw: Support multiple devices per ddraw object.
This commit is contained in:
parent
6fe8e64c1a
commit
9d95bd5f4b
7 changed files with 52 additions and 35 deletions
|
@ -420,6 +420,7 @@ static void ddraw_destroy_swapchain(struct ddraw *ddraw)
|
|||
*****************************************************************************/
|
||||
static void ddraw_destroy(struct ddraw *This)
|
||||
{
|
||||
struct d3d_device *device;
|
||||
IDirectDraw7_SetCooperativeLevel(&This->IDirectDraw7_iface, NULL, DDSCL_NORMAL);
|
||||
IDirectDraw7_RestoreDisplayMode(&This->IDirectDraw7_iface);
|
||||
|
||||
|
@ -440,8 +441,10 @@ static void ddraw_destroy(struct ddraw *This)
|
|||
wined3d_device_decref(This->wined3d_device);
|
||||
wined3d_decref(This->wined3d);
|
||||
|
||||
if (This->d3ddevice)
|
||||
This->d3ddevice->ddraw = NULL;
|
||||
LIST_FOR_EACH_ENTRY(device, &This->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
device->ddraw = NULL;
|
||||
}
|
||||
|
||||
/* Now free the object */
|
||||
free(This);
|
||||
|
@ -793,7 +796,6 @@ static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface)
|
|||
static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
|
||||
DWORD cooplevel, BOOL restore_mode_on_normal)
|
||||
{
|
||||
struct wined3d_stateblock *stateblock;
|
||||
BOOL restore_state = FALSE;
|
||||
struct d3d_device *device;
|
||||
RECT clip_rect;
|
||||
|
@ -923,18 +925,29 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
|
|||
if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED))
|
||||
wined3d_device_set_multithreaded(ddraw->wined3d_device);
|
||||
|
||||
device = ddraw->d3ddevice;
|
||||
if (ddraw->wined3d_swapchain)
|
||||
{
|
||||
if (!(ddraw->flags & DDRAW_NO3D) && device)
|
||||
if (!(ddraw->flags & DDRAW_NO3D))
|
||||
{
|
||||
restore_state = TRUE;
|
||||
|
||||
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device,
|
||||
device->state, WINED3D_SBT_ALL, &stateblock)))
|
||||
LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
ERR("Failed to create stateblock, hr %#lx.\n", hr);
|
||||
goto done;
|
||||
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device,
|
||||
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,
|
|||
|
||||
if (restore_state)
|
||||
{
|
||||
wined3d_stateblock_apply(stateblock, device->state);
|
||||
wined3d_stateblock_decref(stateblock);
|
||||
LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
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))
|
||||
|
@ -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);
|
||||
|
||||
list_init(&ddraw->surface_list);
|
||||
list_init(&ddraw->d3ddevice_list);
|
||||
return DD_OK;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ struct ddraw
|
|||
|
||||
/* D3D things */
|
||||
HWND d3d_window;
|
||||
struct d3d_device *d3ddevice;
|
||||
struct list d3ddevice_list;
|
||||
int d3dversion;
|
||||
|
||||
/* Various HWNDs */
|
||||
|
@ -326,6 +326,7 @@ struct d3d_device
|
|||
struct wined3d_device *wined3d_device;
|
||||
struct wined3d_device_context *immediate_context;
|
||||
struct ddraw *ddraw;
|
||||
struct list ddraw_entry;
|
||||
IUnknown *rt_iface;
|
||||
struct ddraw_surface *target, *target_ds;
|
||||
|
||||
|
@ -362,6 +363,9 @@ struct d3d_device
|
|||
|
||||
struct wined3d_stateblock *recording, *state, *update_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,
|
||||
|
|
|
@ -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. */
|
||||
if (This->ddraw)
|
||||
{
|
||||
This->ddraw->d3ddevice = NULL;
|
||||
list_remove(&This->ddraw_entry);
|
||||
This->ddraw = NULL;
|
||||
}
|
||||
|
||||
|
@ -6907,7 +6907,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c
|
|||
if (version != 1)
|
||||
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,
|
||||
d3d_device_update_depth_stencil(device));
|
||||
|
@ -6955,12 +6955,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su
|
|||
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))))
|
||||
{
|
||||
ERR("Failed to allocate device memory.\n");
|
||||
|
|
|
@ -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",
|
||||
ddraw, ddraw->ref7, ddraw->ref4, ddraw->ref3, ddraw->ref2, ddraw->ref1);
|
||||
|
||||
if (ddraw->d3ddevice)
|
||||
WARN("DirectDraw object %p has Direct3D device %p attached.\n", ddraw, ddraw->d3ddevice);
|
||||
if (!list_empty(&ddraw->d3ddevice_list))
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
struct d3d_device *device;
|
||||
|
||||
TRACE("surface %p, attachment %p.\n", This, Surf);
|
||||
|
||||
if(Surf == This)
|
||||
|
@ -2039,8 +2041,10 @@ static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct d
|
|||
This->next_attached = Surf;
|
||||
|
||||
/* Check if the WineD3D depth stencil needs updating */
|
||||
if (This->ddraw->d3ddevice)
|
||||
d3d_device_update_depth_stencil(This->ddraw->d3ddevice);
|
||||
LIST_FOR_EACH_ENTRY(device, &This->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
d3d_device_update_depth_stencil(device);
|
||||
}
|
||||
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
|
@ -4361,7 +4365,7 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma
|
|||
if (surface->draw_texture)
|
||||
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);
|
||||
if (surface->draw_texture)
|
||||
|
@ -6774,7 +6778,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
swapchain_desc.backbuffer_height = mode.height;
|
||||
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)
|
||||
wined3d_stateblock_decref(device->recording);
|
||||
|
@ -6791,9 +6795,11 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
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,
|
||||
!!swapchain_desc.enable_auto_depth_stencil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1523,13 +1523,8 @@ static void BackBuffer3DCreateSurfaceTest(void)
|
|||
"GetSurfaceDesc returned caps %#lx.\n", created_ddsd.ddsCaps.dwCaps);
|
||||
|
||||
hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
|
||||
/* Currently Wine only supports the creation of one Direct3D device
|
||||
for a given DirectDraw instance. It has been created already
|
||||
in D3D1_createObjects() - IID_IDirect3DRGBDevice */
|
||||
todo_wine ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
IDirect3DDevice_Release(d3dhal);
|
||||
ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
|
||||
IDirect3DDevice_Release(d3dhal);
|
||||
|
||||
IDirectDrawSurface_Release(surf);
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
|
|||
* they are destroyed. */
|
||||
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)
|
||||
wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue