From 94db69addfe7d9049300393410664dee39f695f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Thu, 27 Aug 2015 23:43:08 +0200
Subject: wined3d: Destroy samplers through the command stream.

---
 dlls/wined3d/cs.c              | 28 ++++++++++++++++++++++++++++
 dlls/wined3d/sampler.c         | 21 +++++++++++++--------
 dlls/wined3d/wined3d_private.h |  3 +++
 3 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index e89e053..01c4ba3 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -93,6 +93,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_DELETE_GL_CONTEXTS,
     WINED3D_CS_OP_GETDC,
     WINED3D_CS_OP_RELEASEDC,
+    WINED3D_CS_OP_SAMPLER_DESTROY,
     WINED3D_CS_OP_STOP,
 };
 
@@ -557,6 +558,12 @@ struct wined3d_cs_releasedc
     struct wined3d_surface *surface;
 };
 
+struct wined3d_cs_sampler_destroy
+{
+    enum wined3d_cs_op opcode;
+    struct wined3d_sampler *sampler;
+};
+
 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);
@@ -2758,6 +2765,26 @@ void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *su
     cs->ops->finish(cs);
 }
 
+static UINT wined3d_cs_exec_sampler_destroy(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_sampler_destroy *op = data;
+
+    wined3d_sampler_destroy(op->sampler);
+
+    return sizeof(*op);
+}
+
+void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler)
+{
+    struct wined3d_cs_sampler_destroy *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op));
+    op->opcode = WINED3D_CS_OP_SAMPLER_DESTROY;
+    op->sampler = sampler;
+
+    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,
@@ -2829,6 +2856,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_DELETE_GL_CONTEXTS         */ wined3d_cs_exec_delete_gl_contexts,
     /* WINED3D_CS_OP_GETDC                      */ wined3d_cs_exec_getdc,
     /* WINED3D_CS_OP_RELEASEDC                  */ wined3d_cs_exec_releasedc,
+    /* WINED3D_CS_OP_SAMPLER_DESTROY            */ wined3d_cs_exec_sampler_destroy,
 };
 
 static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio)
diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c
index ffa1155..81bdb51 100644
--- a/dlls/wined3d/sampler.c
+++ b/dlls/wined3d/sampler.c
@@ -33,22 +33,27 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler)
     return refcount;
 }
 
+void wined3d_sampler_destroy(struct wined3d_sampler *sampler)
+{
+    struct wined3d_context *context = context_acquire(sampler->device, NULL);
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    GL_EXTCALL(glDeleteSamplers(1, &sampler->name));
+    context_release(context);
+
+    HeapFree(GetProcessHeap(), 0, sampler);
+}
+
 ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
 {
     ULONG refcount = InterlockedDecrement(&sampler->refcount);
-    const struct wined3d_gl_info *gl_info;
-    struct wined3d_context *context;
 
     TRACE("%p decreasing refcount to %u.\n", sampler, refcount);
 
     if (!refcount)
     {
-        context = context_acquire(sampler->device, NULL);
-        gl_info = context->gl_info;
-        GL_EXTCALL(glDeleteSamplers(1, &sampler->name));
-        context_release(context);
-
-        HeapFree(GetProcessHeap(), 0, sampler);
+        struct wined3d_device *device = sampler->device;
+        wined3d_cs_emit_sampler_destroy(device->cs, sampler);
     }
 
     return refcount;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0adce02..9f4c9e1 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2566,6 +2566,8 @@ struct wined3d_sampler
     GLuint name;
 };
 
+void wined3d_sampler_destroy(struct wined3d_sampler *sampler) DECLSPEC_HIDDEN;
+
 struct wined3d_vertex_declaration_element
 {
     const struct wined3d_format *format;
@@ -2821,6 +2823,7 @@ void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs,
         struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) 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.5.1

