Andrew Wesie : wined3d: Add fast-path for texture download blit.

Alexandre Julliard julliard at winehq.org
Thu Oct 4 17:14:43 CDT 2018


Module: wine
Branch: master
Commit: 54a9e84952ce8f566f79ab92930faf84bad0cfc1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=54a9e84952ce8f566f79ab92930faf84bad0cfc1

Author: Andrew Wesie <awesie at gmail.com>
Date:   Thu Oct  4 01:16:44 2018 -0500

wined3d: Add fast-path for texture download blit.

Signed-off-by: Andrew Wesie <awesie at gmail.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/surface.c         | 28 +++++++++++++++++++++++++---
 dlls/wined3d/texture.c         | 22 ++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |  2 ++
 3 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 4942177..71693ad 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3257,6 +3257,29 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
             return WINED3D_OK;
         }
     }
+    else if (!(src_sub_resource->locations & surface_simple_locations)
+            && (dst_sub_resource->locations & dst_texture->resource.map_binding))
+    {
+        /* Download */
+        if (scale)
+            TRACE("Not doing download because of scaling.\n");
+        else if (convert)
+            TRACE("Not doing download because of format conversion.\n");
+        else if (src_texture->resource.format->conv_byte_count)
+            TRACE("Not doing download because the source format needs conversion.\n");
+        else if (is_multisample_location(src_texture, WINED3D_LOCATION_TEXTURE_RGB))
+            TRACE("Not doing download because of multisample source.\n");
+        else if (!texture2d_is_full_rect(src_texture, src_sub_resource_idx % src_texture->level_count, &src_rect))
+            TRACE("Not doing download because of partial download (src).\n");
+        else if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, &dst_rect))
+            TRACE("Not doing download because of partial download (dst).\n");
+        else
+        {
+            wined3d_texture_download_from_texture(dst_texture, dst_sub_resource_idx, src_texture,
+                    src_sub_resource_idx);
+            return WINED3D_OK;
+        }
+    }
     else if (dst_swapchain && dst_swapchain->back_buffers
             && dst_texture == dst_swapchain->front_buffer
             && src_texture == dst_swapchain->back_buffers[0])
@@ -3280,10 +3303,9 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
 
         return WINED3D_OK;
     }
-    else if ((flags & WINED3D_BLT_RAW) || (!scale && !convert && !resolve))
-    {
+
+    if ((flags & WINED3D_BLT_RAW) || (blit_op == WINED3D_BLIT_OP_COLOR_BLIT && !scale && !convert && !resolve))
         blit_op = WINED3D_BLIT_OP_RAW_BLIT;
-    }
 
     if (dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)
         dst_location = dst_texture->resource.draw_binding;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 0b11c94..400d367 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -3806,3 +3806,25 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un
     wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
 }
+
+/* Partial downloads are not supported. */
+void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
+        struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx)
+{
+    struct wined3d_context *context;
+    struct wined3d_bo_address data;
+    DWORD dst_location = dst_texture->resource.map_binding;
+
+    context = context_acquire(src_texture->resource.device, NULL, 0);
+
+    wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location);
+    wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &data, dst_location);
+    wined3d_texture_bind_and_dirtify(src_texture, context,
+            !(src_texture->sub_resources[src_sub_resource_idx].locations & WINED3D_LOCATION_TEXTURE_RGB));
+    wined3d_texture_download_data(src_texture, src_sub_resource_idx, context, &data);
+
+    context_release(context);
+
+    wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location);
+    wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location);
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index fadb607..9baefa6 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3349,6 +3349,8 @@ HRESULT wined3d_texture_check_box_dimensions(const struct wined3d_texture *textu
         unsigned int level, const struct wined3d_box *box) DECLSPEC_HIDDEN;
 void wined3d_texture_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
         struct wined3d_context *context, const struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
+void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
+        struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx) DECLSPEC_HIDDEN;
 GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) DECLSPEC_HIDDEN;
 void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx,
         struct wined3d_bo_address *data, DWORD locations) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list