From a0164715382370f9c695094e906a242d96c504f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Wed, 3 Apr 2013 18:01:34 +0200
Subject: wined3d: Wait for the cs before destroying objects

This is to avoid destroying objects that are still referenced in
commands in the cs. Later patches will migrate resource destruction to
the CS.
---
 dlls/wined3d/buffer.c            | 6 ++++++
 dlls/wined3d/cs.c                | 2 ++
 dlls/wined3d/shader.c            | 5 +++++
 dlls/wined3d/surface.c           | 6 ++++++
 dlls/wined3d/texture.c           | 6 ++++++
 dlls/wined3d/vertexdeclaration.c | 5 +++++
 dlls/wined3d/wined3d_private.h   | 1 +
 7 files changed, 31 insertions(+)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index bd01aca..6271307 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -552,6 +552,12 @@ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
 
     if (!refcount)
     {
+        if (wined3d_settings.cs_multithreaded)
+        {
+            FIXME("Waiting for cs.\n");
+            buffer->resource.device->cs->ops->finish(buffer->resource.device->cs);
+        }
+
         if (buffer->buffer_object)
         {
             context = context_acquire(buffer->resource.device, NULL);
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 680e2bc..f192006 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -1303,12 +1303,14 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops =
 {
     wined3d_cs_st_require_space,
     wined3d_cs_st_submit,
+    wined3d_cs_st_submit,
 };
 
 static const struct wined3d_cs_ops wined3d_cs_mt_ops =
 {
     wined3d_cs_mt_require_space,
     wined3d_cs_flush_and_wait,
+    wined3d_cs_flush_and_wait,
 };
 
 /* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index da51493..e9a7cc1 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -2379,6 +2379,11 @@ ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader)
 
     if (!refcount)
     {
+        if (wined3d_settings.cs_multithreaded)
+        {
+            FIXME("Waiting for cs.\n");
+            shader->device->cs->ops->finish(shader->device->cs);
+        }
         shader_cleanup(shader);
         shader->parent_ops->wined3d_object_destroyed(shader->parent);
         HeapFree(GetProcessHeap(), 0, shader);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 5bdfdc3..9d40ba9 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -42,6 +42,12 @@ static void surface_cleanup(struct wined3d_surface *surface)
 
     TRACE("surface %p.\n", surface);
 
+    if (wined3d_settings.cs_multithreaded)
+    {
+        FIXME("Waiting for cs.\n");
+        surface->resource.device->cs->ops->finish(surface->resource.device->cs);
+    }
+
     if (surface->resource.buffer_object || surface->rb_multisample
             || surface->rb_resolved || !list_empty(&surface->renderbuffers))
     {
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 42ed30e..5dc9ac5 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -111,6 +111,12 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture)
 
     TRACE("texture %p.\n", texture);
 
+    if (wined3d_settings.cs_multithreaded)
+    {
+        FIXME("Waiting for cs.\n");
+        texture->resource.device->cs->ops->finish(texture->resource.device->cs);
+    }
+
     for (i = 0; i < sub_count; ++i)
     {
         struct wined3d_resource *sub_resource = texture->sub_resources[i].resource;
diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c
index 9eb5907..601a5f5 100644
--- a/dlls/wined3d/vertexdeclaration.c
+++ b/dlls/wined3d/vertexdeclaration.c
@@ -58,6 +58,11 @@ ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration
 
     if (!refcount)
     {
+        if (wined3d_settings.cs_multithreaded)
+        {
+            FIXME("Waiting for cs.\n");
+            declaration->device->cs->ops->finish(declaration->device->cs);
+        }
         HeapFree(GetProcessHeap(), 0, declaration->elements);
         declaration->parent_ops->wined3d_object_destroyed(declaration->parent);
         HeapFree(GetProcessHeap(), 0, declaration);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7f7bf5f..c14a3a7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2761,6 +2761,7 @@ struct wined3d_cs_ops
 {
     void *(*require_space)(struct wined3d_cs *cs, size_t size);
     void (*submit)(struct wined3d_cs *cs);
+    void (*finish)(struct wined3d_cs *cs);
 };
 
 struct wined3d_cs
-- 
2.7.1

