ddraw: Keep an explicit reference to the wined3d device in surfaces.
Version 1 and version 2 surfaces don't keep references to the ddraw interface that created them, so such surfaces may get destroyed after the corresponding ddraw object was destroyed. Wined3d requires that the device is destroyed after all its resources are destroyed. In principle this issue always existed, but it was probably made worse by changes in the texture cleanup code. Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0190c50a8c
commit
c7c0415689
|
@ -206,6 +206,7 @@ struct ddraw_texture
|
|||
DDSURFACEDESC2 surface_desc;
|
||||
|
||||
struct ddraw_surface *root;
|
||||
struct wined3d_device *wined3d_device;
|
||||
};
|
||||
|
||||
HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc,
|
||||
|
|
|
@ -543,6 +543,8 @@ ULONG ddraw_surface_release_iface(struct ddraw_surface *This)
|
|||
|
||||
if (iface_count == 0)
|
||||
{
|
||||
struct ddraw_texture *texture = wined3d_texture_get_parent(This->wined3d_texture);
|
||||
struct wined3d_device *wined3d_device = texture->wined3d_device;
|
||||
IUnknown *release_iface = This->ifaceToRelease;
|
||||
|
||||
/* Complex attached surfaces are destroyed implicitly when the root is released */
|
||||
|
@ -558,6 +560,9 @@ ULONG ddraw_surface_release_iface(struct ddraw_surface *This)
|
|||
|
||||
if (release_iface)
|
||||
IUnknown_Release(release_iface);
|
||||
/* Release the device only after anything that may reference it (the
|
||||
* wined3d texture and rendertarget view in particular) is released. */
|
||||
wined3d_device_decref(wined3d_device);
|
||||
}
|
||||
|
||||
return iface_count;
|
||||
|
@ -6142,6 +6147,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
wined3d_texture_decref(wined3d_texture);
|
||||
root->is_complex_root = TRUE;
|
||||
texture->root = root;
|
||||
wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device);
|
||||
|
||||
if (desc->dwFlags & DDSD_CKDESTOVERLAY)
|
||||
wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTOVERLAY,
|
||||
|
@ -6260,6 +6266,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
last = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0);
|
||||
wined3d_texture_decref(wined3d_texture);
|
||||
texture->root = last;
|
||||
wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device);
|
||||
|
||||
if (desc->dwFlags & DDSD_CKDESTOVERLAY)
|
||||
wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTOVERLAY,
|
||||
|
|
|
@ -547,7 +547,7 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
|
|||
wined3d_cs_destroy(device->cs);
|
||||
|
||||
if (device->recording && wined3d_stateblock_decref(device->recording))
|
||||
FIXME("Something's still holding the recording stateblock.\n");
|
||||
ERR("Something's still holding the recording stateblock.\n");
|
||||
device->recording = NULL;
|
||||
|
||||
state_cleanup(&device->state);
|
||||
|
@ -562,11 +562,11 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
|
|||
{
|
||||
struct wined3d_resource *resource;
|
||||
|
||||
FIXME("Device released with resources still bound, acceptable but unexpected.\n");
|
||||
ERR("Device released with resources still bound.\n");
|
||||
|
||||
LIST_FOR_EACH_ENTRY(resource, &device->resources, struct wined3d_resource, resource_list_entry)
|
||||
{
|
||||
FIXME("Leftover resource %p with type %s (%#x).\n",
|
||||
ERR("Leftover resource %p with type %s (%#x).\n",
|
||||
resource, debug_d3dresourcetype(resource->type), resource->type);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue