[PATCH 1/4] ddraw: Keep an explicit reference to the wined3d device in surfaces.

Henri Verbeet hverbeet at codeweavers.com
Tue Jan 3 17:04:47 CST 2017


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 at codeweavers.com>
---
 dlls/ddraw/ddraw_private.h | 1 +
 dlls/ddraw/surface.c       | 7 +++++++
 dlls/wined3d/device.c      | 6 +++---
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 731d441..1133bbd 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -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,
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 2989988..4b53ac3 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -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,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a8de282..785ea6b 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -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);
             }
         }
-- 
2.1.4




More information about the wine-patches mailing list