Module: wine Branch: master Commit: cc9c18a46d1ce7e2834bae0fa65a6ed7904820dd URL: http://source.winehq.org/git/wine.git/?a=commit;h=cc9c18a46d1ce7e2834bae0fa6...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Fri Jul 8 10:59:05 2016 +0200
wined3d: Synchronise resource destruction with the command stream.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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,