[PATCH 3/6] wined3d: Don't lock the dst volume in device_update_volume

Stefan Dösinger stefan at codeweavers.com
Thu Aug 22 16:22:47 CDT 2013


---
 dlls/wined3d/device.c          | 27 +++++++++++++--------------
 dlls/wined3d/volume.c          | 36 +++++++++++++++++++++++++++---------
 dlls/wined3d/wined3d_private.h |  3 +++
 3 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a4a06a9..f08b616 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4070,29 +4070,28 @@ static HRESULT device_update_volume(struct wined3d_device *device,
         struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume)
 {
     struct wined3d_map_desc src;
-    struct wined3d_map_desc dst;
     HRESULT hr;
+    struct wined3d_bo_address data;
+    struct wined3d_context *context;
 
     TRACE("device %p, src_volume %p, dst_volume %p.\n",
             device, src_volume, dst_volume);
 
-    /* TODO: Implement direct loading into the gl volume instead of using
-     * memcpy and dirtification to improve loading performance. */
     if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY)))
         return hr;
-    if (FAILED(hr = wined3d_volume_map(dst_volume, &dst, NULL, WINED3D_MAP_DISCARD)))
-    {
-        wined3d_volume_unmap(src_volume);
-        return hr;
-    }
 
-    memcpy(dst.data, src.data, dst_volume->resource.size);
+    context = context_acquire(device, NULL);
 
-    hr = wined3d_volume_unmap(dst_volume);
-    if (FAILED(hr))
-        wined3d_volume_unmap(src_volume);
-    else
-        hr = wined3d_volume_unmap(src_volume);
+    wined3d_volume_load(dst_volume, context, FALSE);
+
+    data.buffer_object = 0;
+    data.addr = src.data;
+    wined3d_volume_upload_data(dst_volume, context, &data);
+    wined3d_volume_invalidate_location(dst_volume, ~WINED3D_LOCATION_TEXTURE_RGB);
+
+    context_release(context);
+
+    hr = wined3d_volume_unmap(src_volume);
 
     return hr;
 }
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index d95fd91..71b2937 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -69,7 +69,7 @@ static void wined3d_volume_allocate_texture(const struct wined3d_volume *volume,
 }
 
 /* Context activation is done by the caller. */
-static void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
+void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
         const struct wined3d_bo_address *data)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -105,7 +105,7 @@ static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWOR
     TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations));
 }
 
-static void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location)
+void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location)
 {
     TRACE("Volume %p, clearing %s.\n", volume, wined3d_debug_location(location));
     volume->locations &= ~location;
@@ -132,10 +132,31 @@ static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume)
     wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM);
 }
 
+static DWORD volume_access_from_location(DWORD location)
+{
+    switch (location)
+    {
+        case WINED3D_LOCATION_DISCARDED:
+            return 0;
+
+        case WINED3D_LOCATION_SYSMEM:
+            return WINED3D_RESOURCE_ACCESS_CPU;
+
+        case WINED3D_LOCATION_TEXTURE_RGB:
+            return WINED3D_RESOURCE_ACCESS_GPU;
+
+        default:
+            FIXME("Unhandled location %#x.\n", location);
+            return 0;
+    }
+}
+
 /* Context activation is done by the caller. */
 static void wined3d_volume_load_location(struct wined3d_volume *volume,
         struct wined3d_context *context, DWORD location)
 {
+    DWORD required_access = volume_access_from_location(location);
+
     TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location),
         wined3d_debug_location(volume->locations));
 
@@ -145,14 +166,11 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
         return;
     }
 
-    if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_GPU))
+    if ((volume->resource.access_flags & required_access) != required_access)
     {
-        if (location & ~WINED3D_LOCATION_SYSMEM)
-        {
-            ERR("Trying to load a cpu-only access volume into %s.\n",
-                    wined3d_debug_location(location));
-            return;
-        }
+        ERR("Operation requires %#x access, but volume only has %#x.\n",
+                required_access, volume->resource.access_flags);
+        return;
     }
 
     switch (location)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 74739c1..477d75b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2073,6 +2073,9 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc
 
 void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) DECLSPEC_HIDDEN;
 void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container) DECLSPEC_HIDDEN;
+void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN;
+void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
+        const struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
 
 struct wined3d_surface_dib
 {
-- 
1.8.1.5




More information about the wine-patches mailing list