From eb59e53d03f032fe4e04a6e7843ac06e9dddbbdd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Fri, 27 Sep 2013 18:46:19 +0200
Subject: wined3d: Dirtify changed textures through the command stream.

This makes sure unsynchronized maps (NOOVERWRITE /DISCARD) are reflected
in the volume's location flags at the right time.
---
 dlls/wined3d/cs.c              | 31 ++++++++++++++++++++++++++++++-
 dlls/wined3d/resource.c        | 15 ++++++++++-----
 dlls/wined3d/surface.c         |  9 +++------
 dlls/wined3d/wined3d_private.h |  2 ++
 4 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 054c000..f5c10dd 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -65,6 +65,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_SET_LIGHT_ENABLE,
     WINED3D_CS_OP_BLT,
     WINED3D_CS_OP_CLEAR_RTV,
+    WINED3D_CS_OP_RESOURCE_CHANGED,
     WINED3D_CS_OP_RESOURCE_MAP,
     WINED3D_CS_OP_RESOURCE_UNMAP,
     WINED3D_CS_OP_QUERY_ISSUE,
@@ -365,6 +366,12 @@ struct wined3d_cs_resource_unmap
     struct wined3d_resource *resource;
 };
 
+struct wined3d_cs_resource_changed
+{
+    enum wined3d_cs_op opcode;
+    struct wined3d_resource *resource;
+};
+
 struct wined3d_cs_skip
 {
     enum wined3d_cs_op opcode;
@@ -1804,6 +1811,27 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge
     cs->ops->submit(cs, sizeof(*op));
 }
 
+static UINT wined3d_cs_exec_resource_changed(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_resource_changed *op = data;
+    struct wined3d_resource *resource = op->resource;
+
+    wined3d_resource_changed(resource);
+
+    return sizeof(*op);
+}
+
+void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource)
+{
+    struct wined3d_cs_resource_changed *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op));
+    op->opcode = WINED3D_CS_OP_RESOURCE_CHANGED;
+    op->resource = resource;
+
+    cs->ops->submit(cs, sizeof(*op));
+}
+
 static UINT wined3d_cs_exec_resource_map(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_resource_map *op = data;
@@ -2110,11 +2138,11 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_SET_INDEX_BUFFER           */ wined3d_cs_exec_set_index_buffer,
     /* WINED3D_CS_OP_SET_CONSTANT_BUFFER        */ wined3d_cs_exec_set_constant_buffer,
     /* WINED3D_CS_OP_SET_TEXTURE                */ wined3d_cs_exec_set_texture,
-    /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW   */ wined3d_cs_exec_set_shader_resource_view,
     /* WINED3D_CS_OP_SET_SAMPLER                */ wined3d_cs_exec_set_sampler,
     /* WINED3D_CS_OP_SET_SHADER                 */ wined3d_cs_exec_set_shader,
     /* WINED3D_CS_OP_SET_RENDER_STATE           */ wined3d_cs_exec_set_render_state,
     /* WINED3D_CS_OP_SET_TEXTURE_STATE          */ wined3d_cs_exec_set_texture_state,
+    /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW   */ wined3d_cs_exec_set_shader_resource_view,
     /* WINED3D_CS_OP_SET_SAMPLER_STATE          */ wined3d_cs_exec_set_sampler_state,
     /* WINED3D_CS_OP_SET_TRANSFORM              */ wined3d_cs_exec_set_transform,
     /* WINED3D_CS_OP_SET_CLIP_PLANE             */ wined3d_cs_exec_set_clip_plane,
@@ -2133,6 +2161,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_SET_LIGHT_ENABLE           */ wined3d_cs_exec_set_light_enable,
     /* WINED3D_CS_OP_BLT                        */ wined3d_cs_exec_blt,
     /* WINED3D_CS_OP_CLEAR_RTV                  */ wined3d_cs_exec_clear_rtv,
+    /* WINED3D_CS_OP_RESOURCE_CHANGED           */ wined3d_cs_exec_resource_changed,
     /* WINED3D_CS_OP_RESOURCE_MAP               */ wined3d_cs_exec_resource_map,
     /* WINED3D_CS_OP_RESOURCE_UNMAP             */ wined3d_cs_exec_resource_unmap,
     /* WINED3D_CS_OP_QUERY_ISSUE                */ wined3d_cs_exec_query_issue,
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index d2407a1..7cafdc6 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -830,11 +830,6 @@ void wined3d_resource_unmap_internal(struct wined3d_resource *resource)
     wined3d_resource_release_map_ptr(resource, context);
     if (context)
         context_release(context);
-
-    if (resource->unmap_dirtify)
-        wined3d_resource_invalidate_location(resource, ~resource->map_binding);
-    resource->unmap_dirtify = FALSE;
-
 }
 
 HRESULT wined3d_resource_unmap(struct wined3d_resource *resource)
@@ -849,7 +844,17 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource)
     }
 
     wined3d_cs_emit_resource_unmap(device->cs, resource);
+
+    if (resource->unmap_dirtify)
+        wined3d_cs_emit_resource_changed(device->cs, resource);
+    resource->unmap_dirtify = FALSE;
+
     resource->map_count--;
 
     return WINED3D_OK;
 }
+
+void wined3d_resource_changed(struct wined3d_resource *resource)
+{
+    wined3d_resource_invalidate_location(resource, ~resource->map_binding);
+}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index e661494..535e21a 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1093,6 +1093,9 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour
 
     if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
         wined3d_texture_set_dirty(surface->container);
+
+    if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer)
+        surface->surface_ops->surface_frontbuffer_updated(surface);
 }
 
 static const struct wined3d_surface_ops surface_ops =
@@ -2405,16 +2408,10 @@ HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface)
     HRESULT hr;
     TRACE("surface %p.\n", surface);
 
-    if (surface->resource.unmap_dirtify && surface->container)
-        wined3d_texture_set_dirty(surface->container);
-
-
     hr = wined3d_resource_unmap(&surface->resource);
     if (FAILED(hr))
         return hr;
 
-    if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer)
-        surface->surface_ops->surface_frontbuffer_updated(surface);
     memset(&surface->lockedRect, 0, sizeof(surface->lockedRect));
 
     return hr;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d670fe1..b9831fd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2146,6 +2146,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
 void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN;
 BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+void wined3d_resource_changed(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource,
         const struct wined3d_box *box) DECLSPEC_HIDDEN;
 void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
@@ -2662,6 +2663,7 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf
         enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view,
         const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource,
         DWORD flags) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
-- 
2.1.3

