From 40087b5024636170ee3bc5c4ed3436898a97e21c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Wed, 2 Oct 2013 22:54:57 +0200
Subject: wined3d: Clean up volume resource data through the CS.

---
 dlls/wined3d/cs.c              | 28 ++++++++++++++++++++++++++++
 dlls/wined3d/volume.c          |  9 ++++++---
 dlls/wined3d/wined3d_private.h |  2 ++
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 54b6d1a..18b556d 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -85,6 +85,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_CREATE_VBO,
     WINED3D_CS_OP_RESOURCE_CLEANUP,
     WINED3D_CS_OP_BUFFER_CLEANUP,
+    WINED3D_CS_OP_VOLUME_CLEANUP,
     WINED3D_CS_OP_STOP,
 };
 
@@ -501,6 +502,12 @@ struct wined3d_cs_buffer_cleanup
     struct wined3d_buffer *buffer;
 };
 
+struct wined3d_cs_volume_cleanup
+{
+    enum wined3d_cs_op opcode;
+    struct wined3d_volume *volume;
+};
+
 static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size)
 {
     LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1);
@@ -2506,6 +2513,26 @@ void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer
     cs->ops->submit(cs, sizeof(*op));
 }
 
+static UINT wined3d_cs_exec_volume_cleanup(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_volume_cleanup *op = data;
+
+    wined3d_volume_cleanup_cs(op->volume);
+
+    return sizeof(*op);
+}
+
+void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume)
+{
+    struct wined3d_cs_volume_cleanup *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op));
+    op->opcode = WINED3D_CS_OP_VOLUME_CLEANUP;
+    op->volume = volume;
+
+    cs->ops->submit(cs, sizeof(*op));
+}
+
 static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
 {
     /* WINED3D_CS_OP_NOP                        */ wined3d_cs_exec_nop,
@@ -2569,6 +2596,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_CREATE_VBO                 */ wined3d_cs_exec_create_vbo,
     /* WINED3D_CS_OP_RESOURCE_CLEANUP           */ wined3d_cs_exec_resource_cleanup,
     /* WINED3D_CS_OP_BUFFER_CLEANUP             */ wined3d_cs_exec_buffer_cleanup,
+    /* WINED3D_CS_OP_VOLUME_CLEANUP             */ wined3d_cs_exec_volume_cleanup,
 };
 
 static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio)
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 15c80ce..eb0341a 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -313,10 +313,8 @@ void wined3d_volume_destroy(struct wined3d_volume *volume)
     TRACE("volume %p.\n", volume);
 
     resource_cleanup(&volume->resource);
-    if (wined3d_settings.cs_multithreaded)
-        device->cs->ops->finish(device->cs);
     volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent);
-    HeapFree(GetProcessHeap(), 0, volume);
+    wined3d_cs_emit_volume_cleanup(device->cs, volume);
 }
 
 static void volume_unload(struct wined3d_resource *resource)
@@ -425,6 +423,11 @@ static ULONG volume_resource_incref(struct wined3d_resource *resource)
     return wined3d_texture_incref(volume->container);
 }
 
+void wined3d_volume_cleanup_cs(struct wined3d_volume *volume)
+{
+    HeapFree(GetProcessHeap(), 0, volume);
+}
+
 static ULONG volume_resource_decref(struct wined3d_resource *resource)
 {
     struct wined3d_volume *volume = volume_from_resource(resource);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f4cc159..04a403a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2435,6 +2435,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
 HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
 void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
         const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
+void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
 
 struct wined3d_surface_dib
 {
@@ -2809,6 +2810,7 @@ void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *bu
 void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs,
         struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN;
 
 /* Direct3D terminology with little modifications. We do not have an issued state
  * because only the driver knows about it, but we have a created state because d3d
-- 
2.6.0

