From c1bf11e5e355915f1ac6e1e9cdfaf3b5a7309167 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Thu, 24 Oct 2013 22:38:26 +0200
Subject: wined3d: Fence preload operations.

Otherwise texture data might get lost, thanks to surface/volume_evict_sysmem:

1) preload(texture)
2) map(texture)
    -> Loads sysmem / sets it with discard map.
3) unmap(texture)
    -> enqueues a resource_changed operation
4) preload is executed.
    -> Uploads data written in 3. Discards sysmem. Questionable if
       DISCARD was passed, but without it, no harm done.
    -> texture is only up to date location.
5) resource_changed executed.
    -> Discards texture.

And data is lost. This patch prevents that by stalling the map until the
PreLoad is done.

What's left open is finding out why anyone (I'm looking at you EVE
online) preloads a texture right before mapping it...
---
 dlls/wined3d/cs.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index a542270..0318315 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -2252,6 +2252,8 @@ static UINT wined3d_cs_exec_texture_preload(struct wined3d_cs *cs, const void *d
     wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB);
     context_release(context);
 
+    wined3d_resource_dec_fence(&texture->resource);
+
     return sizeof(*op);
 }
 
@@ -2263,6 +2265,8 @@ void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_textu
     op->opcode = WINED3D_CS_OP_TEXTURE_PRELOAD;
     op->texture = texture;
 
+    wined3d_resource_inc_fence(&texture->resource);
+
     cs->ops->submit(cs, sizeof(*op));
 }
 
@@ -2384,6 +2388,8 @@ static UINT wined3d_cs_exec_buffer_preload(struct wined3d_cs *cs, const void *da
     buffer_internal_preload(op->buffer, context, NULL);
     context_release(context);
 
+    wined3d_resource_dec_fence(&op->buffer->resource);
+
     return sizeof(*op);
 }
 
@@ -2395,6 +2401,8 @@ void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer
     op->opcode = WINED3D_CS_OP_BUFFER_PRELOAD;
     op->buffer = buffer;
 
+    wined3d_resource_inc_fence(&buffer->resource);
+
     cs->ops->submit(cs, sizeof(*op));
 }
 
-- 
2.7.0

