[PATCH 5/5] wined3d: Synchronise resource destruction with the command stream.

Henri Verbeet hverbeet at codeweavers.com
Fri Jul 8 03:59:05 CDT 2016


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/buffer.c          |  2 ++
 dlls/wined3d/resource.c        |  2 ++
 dlls/wined3d/texture.c         |  1 +
 dlls/wined3d/wined3d_private.h | 16 ++++++++++++++++
 4 files changed, 21 insertions(+)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index a15613d..674daec 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1342,6 +1342,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
         ERR("Out of memory.\n");
         buffer_unload(&buffer->resource);
         resource_cleanup(&buffer->resource);
+        wined3d_resource_wait_idle(&buffer->resource);
         return E_OUTOFMEMORY;
     }
     buffer->maps_size = 1;
@@ -1351,6 +1352,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
         ERR("Failed to upload data, hr %#x.\n", hr);
         buffer_unload(&buffer->resource);
         resource_cleanup(&buffer->resource);
+        wined3d_resource_wait_idle(&buffer->resource);
         HeapFree(GetProcessHeap(), 0, buffer->maps);
         return hr;
     }
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index a475dc0..a17203d 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -239,6 +239,7 @@ static void wined3d_resource_destroy_object(void *object)
 
     wined3d_resource_free_sysmem(resource);
     context_resource_released(resource->device, resource, resource->type);
+    wined3d_resource_release(resource);
 }
 
 void resource_cleanup(struct wined3d_resource *resource)
@@ -254,6 +255,7 @@ void resource_cleanup(struct wined3d_resource *resource)
     }
 
     device_resource_released(resource->device, resource);
+    wined3d_resource_acquire(resource);
     wined3d_cs_emit_destroy_object(resource->device->cs, wined3d_resource_destroy_object, resource);
 }
 
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 1283b0b..d8e6b86 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -816,6 +816,7 @@ static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture)
 {
     wined3d_texture_sub_resources_destroyed(texture);
     resource_cleanup(&texture->resource);
+    wined3d_resource_wait_idle(&texture->resource);
     wined3d_texture_cleanup(texture);
 }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8d97d2e..3de14e8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2498,6 +2498,7 @@ struct wined3d_resource
     DWORD priority;
     void *heap_memory;
     struct list resource_list_entry;
+    LONG access_count;
 
     void *parent;
     const struct wined3d_parent_ops *parent_ops;
@@ -2514,6 +2515,21 @@ static inline ULONG wined3d_resource_decref(struct wined3d_resource *resource)
     return resource->resource_ops->resource_decref(resource);
 }
 
+static inline void wined3d_resource_acquire(struct wined3d_resource *resource)
+{
+    InterlockedIncrement(&resource->access_count);
+}
+
+static inline void wined3d_resource_release(struct wined3d_resource *resource)
+{
+    InterlockedDecrement(&resource->access_count);
+}
+
+static inline void wined3d_resource_wait_idle(struct wined3d_resource *resource)
+{
+    while (InterlockedCompareExchange(&resource->access_count, 0, 0));
+}
+
 void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
         enum wined3d_resource_type type, const struct wined3d_format *format,
-- 
2.1.4




More information about the wine-patches mailing list