=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Avoid destroying active contexts.

Alexandre Julliard julliard at winehq.org
Thu Oct 6 14:46:53 CDT 2016


Module: wine
Branch: master
Commit: 13e464d0fbd70309f47a6d8cca5a7e4b3ae84161
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=13e464d0fbd70309f47a6d8cca5a7e4b3ae84161

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Wed Oct  5 11:17:07 2016 +0200

wined3d: Avoid destroying active contexts.

This commit fixes a problem which can be observed in d3d10core and d3d11
tests while a device is destroyed in test_swapchain_flip().

When a swapchain is destroyed all contexts associated with this
swapchain are destroyed. A context is destroyed even if it is active.
This might lead to using a destroyed context. In order to fix this the
destruction of context is delayed until leaving the last level.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/context.c         | 17 +++++++++++++++++
 dlls/wined3d/device.c          |  6 +-----
 dlls/wined3d/wined3d_private.h |  3 ++-
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 89cc9ce..394a2dc 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1354,6 +1354,12 @@ void context_release(struct wined3d_context *context)
             context->restore_ctx = NULL;
             context->restore_dc = NULL;
         }
+
+        if (context->destroy_delayed)
+        {
+            TRACE("Destroying context %p.\n", context);
+            context_destroy(context->device, context);
+        }
     }
 }
 
@@ -2012,6 +2018,17 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont
 
     TRACE("Destroying ctx %p\n", context);
 
+    /* We delay destroying a context when it is active. The context_release()
+     * function invokes context_destroy() again while leaving the last level. */
+    if (context->level)
+    {
+        TRACE("Delaying destruction of context %p.\n", context);
+        context->destroy_delayed = 1;
+        /* FIXME: Get rid of a pointer to swapchain from wined3d_context. */
+        context->swapchain = NULL;
+        return;
+    }
+
     if (context->tid == GetCurrentThreadId() || !context->current)
     {
         context_destroy_gl_resources(context);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 90d0008..1c8cb90 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1185,13 +1185,9 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
     destroy_dummy_textures(device, gl_info);
     destroy_default_samplers(device);
 
-    /* Release the context again as soon as possible. In particular,
-     * releasing the render target views below may release the last reference
-     * to the swapchain associated with this context, which in turn will
-     * destroy the context. */
     context_release(context);
 
-    /* Release the buffers (with sanity checks)*/
+    /* Release the buffers (with sanity checks) */
     if (device->onscreen_depth_stencil)
     {
         surface = device->onscreen_depth_stencil;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 08e9120..3887f91 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1497,7 +1497,8 @@ struct wined3d_context
     DWORD hdc_is_private : 1;
     DWORD hdc_has_format : 1;           /* only meaningful if hdc_is_private */
     DWORD update_shader_resource_bindings : 1;
-    DWORD padding : 14;
+    DWORD destroy_delayed : 1;
+    DWORD padding : 13;
     DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */
     DWORD shader_update_mask;
     DWORD constant_update_mask;




More information about the wine-cvs mailing list