From: Yuxuan Shui yshui@codeweavers.com
ddraw surfaces also hold references to their ddraw objects, but that's not cleared in ddraw_destroy. --- dlls/ddraw/ddraw.c | 6 ++++++ dlls/ddraw/surface.c | 18 +++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index ed342bfd708..5097bf72975 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -421,6 +421,7 @@ static void ddraw_destroy_swapchain(struct ddraw *ddraw) static void ddraw_destroy(struct ddraw *This) { struct d3d_device *device; + struct ddraw_surface *surface; IDirectDraw7_SetCooperativeLevel(&This->IDirectDraw7_iface, NULL, DDSCL_NORMAL); IDirectDraw7_RestoreDisplayMode(&This->IDirectDraw7_iface);
@@ -446,6 +447,11 @@ static void ddraw_destroy(struct ddraw *This) device->ddraw = NULL; }
+ LIST_FOR_EACH_ENTRY(surface, &This->surface_list, struct ddraw_surface, surface_list_entry) + { + surface->ddraw = NULL; + } + /* Now free the object */ free(This); } diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 545c76738cd..ba0af882959 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -2218,12 +2218,15 @@ static HRESULT ddraw_surface_delete_attached_surface(struct ddraw_surface *surfa * QueryInterface(). Some applications, SCP - Containment Breach in * particular, modify the QueryInterface() pointer in the surface vtbl * but don't cleanup properly after the relevant dll is unloaded. */ - dsv = wined3d_device_context_get_depth_stencil_view(surface->ddraw->immediate_context); - if (attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER && dsv == attachment->wined3d_rtv) + if (surface->ddraw) { - wined3d_device_context_set_depth_stencil_view(surface->ddraw->immediate_context, NULL); - LIST_FOR_EACH_ENTRY(device, &surface->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) - wined3d_stateblock_depth_buffer_changed(device->state); + dsv = wined3d_device_context_get_depth_stencil_view(surface->ddraw->immediate_context); + if (attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER && dsv == attachment->wined3d_rtv) + { + wined3d_device_context_set_depth_stencil_view(surface->ddraw->immediate_context, NULL); + LIST_FOR_EACH_ENTRY(device, &surface->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) + wined3d_stateblock_depth_buffer_changed(device->state); + } } wined3d_mutex_unlock();
@@ -6062,12 +6065,13 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren ddraw_free_handle(NULL, surface->Handle - 1, DDRAW_HANDLE_SURFACE);
/* Reduce the ddraw surface count. */ - list_remove(&surface->surface_list_entry); + if (surface->ddraw) + list_remove(&surface->surface_list_entry);
if (surface->clipper && ddraw_clipper_is_valid(surface->clipper)) IDirectDrawClipper_Release(&surface->clipper->IDirectDrawClipper_iface);
- if (surface == surface->ddraw->primary) + if (surface->ddraw && surface == surface->ddraw->primary) { surface->ddraw->primary = NULL; surface->ddraw->gdi_surface = NULL;