[PATCH 1/6] wined3d: Introduce "copy sub-resource" command stream operation.

Józef Kucia jkucia at codeweavers.com
Fri Mar 17 06:57:52 CDT 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---

This patch series fixes copying resource data between d3d10+ typeless
formats.

The idea behind the patch series is to split blit and memcpy-like copy
operations. A few arguments in favor of this idea:
* memcpy-like is simpler operation (doesn't support conversion or
  stretching),
* we shouldn't need to extend blitter to handle other resource types
  (it's fine to support just 2D textures),
* blit and copy operations should produce different results between
  different formats (blitter performs conversions),
* copy operation should be allowed between various formats of the same
  size (including compressed and non-compressed formats),
* it should be possible to implement wined3d_device_update_texture()
  on top of wined3d_cs_emit_copy_sub_resource().

---
 dlls/wined3d/cs.c              | 82 +++++++++++++++++++++++++++++++++++++-----
 dlls/wined3d/device.c          | 12 +++----
 dlls/wined3d/wined3d_private.h |  3 ++
 3 files changed, 82 insertions(+), 15 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index dd6feab..b1d9bc4 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -64,6 +64,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_MAP,
     WINED3D_CS_OP_UNMAP,
     WINED3D_CS_OP_BLT_SUB_RESOURCE,
+    WINED3D_CS_OP_COPY_SUB_RESOURCE,
     WINED3D_CS_OP_UPDATE_SUB_RESOURCE,
 };
 
@@ -360,6 +361,17 @@ struct wined3d_cs_blt_sub_resource
     enum wined3d_texture_filter_type filter;
 };
 
+struct wined3d_cs_copy_sub_resource
+{
+    enum wined3d_cs_op opcode;
+    struct wined3d_resource *dst_resource;
+    unsigned int dst_sub_resource_idx;
+    struct wined3d_box dst_box;
+    struct wined3d_resource *src_resource;
+    unsigned int src_sub_resource_idx;
+    struct wined3d_box src_box;
+};
+
 struct wined3d_cs_update_sub_resource
 {
     enum wined3d_cs_op opcode;
@@ -1676,14 +1688,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
 {
     const struct wined3d_cs_blt_sub_resource *op = data;
 
-    if (op->dst_resource->type == WINED3D_RTYPE_BUFFER)
-    {
-        if (FAILED(wined3d_buffer_copy(buffer_from_resource(op->dst_resource), op->dst_box.left,
-                buffer_from_resource(op->src_resource), op->src_box.left,
-                op->src_box.right - op->src_box.left)))
-            ERR("Failed to copy buffer.\n");
-    }
-    else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D)
+    if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D)
     {
         struct wined3d_surface *dst_surface, *src_surface = NULL;
         struct wined3d_texture *dst_texture, *src_texture;
@@ -1705,7 +1710,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
     }
     else
     {
-        FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(op->dst_resource->type));
+        ERR("Unexpected resource type %s.\n", debug_d3dresourcetype(op->dst_resource->type));
     }
 
     if (op->src_resource)
@@ -1740,6 +1745,64 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_reso
     cs->ops->submit(cs);
 }
 
+static void wined3d_cs_exec_copy_sub_resource(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_copy_sub_resource *op = data;
+
+    if (op->dst_resource->type == WINED3D_RTYPE_BUFFER)
+    {
+        if (FAILED(wined3d_buffer_copy(buffer_from_resource(op->dst_resource), op->dst_box.left,
+                buffer_from_resource(op->src_resource), op->src_box.left,
+                op->src_box.right - op->src_box.left)))
+            ERR("Failed to copy buffer.\n");
+    }
+    else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D)
+    {
+        struct wined3d_texture *dst_texture, *src_texture;
+        struct wined3d_surface *dst_surface, *src_surface;
+        RECT dst_rect, src_rect;
+
+        dst_texture = texture_from_resource(op->dst_resource);
+        dst_surface = dst_texture->sub_resources[op->dst_sub_resource_idx].u.surface;
+        src_texture = texture_from_resource(op->src_resource);
+        src_surface = src_texture->sub_resources[op->src_sub_resource_idx].u.surface;
+        SetRect(&dst_rect, op->dst_box.left, op->dst_box.top, op->dst_box.right, op->dst_box.bottom);
+        SetRect(&src_rect, op->src_box.left, op->src_box.top, op->src_box.right, op->src_box.bottom);
+
+        if (FAILED(wined3d_surface_blt(dst_surface, &dst_rect, src_surface,
+                &src_rect, 0, NULL, WINED3D_TEXF_POINT)))
+            FIXME("Blit failed.\n");
+    }
+    else
+    {
+        FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(op->dst_resource->type));
+    }
+
+    wined3d_resource_release(op->src_resource);
+    wined3d_resource_release(op->dst_resource);
+}
+
+void wined3d_cs_emit_copy_sub_resource(struct wined3d_cs *cs,
+        struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box,
+        struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box)
+{
+    struct wined3d_cs_copy_sub_resource *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op));
+    op->opcode = WINED3D_CS_OP_COPY_SUB_RESOURCE;
+    op->dst_resource = dst_resource;
+    op->dst_sub_resource_idx = dst_sub_resource_idx;
+    op->dst_box = *dst_box;
+    op->src_resource = src_resource;
+    op->src_sub_resource_idx = src_sub_resource_idx;
+    op->src_box = *src_box;
+
+    wined3d_resource_acquire(dst_resource);
+    wined3d_resource_acquire(src_resource);
+
+    cs->ops->submit(cs);
+}
+
 static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_update_sub_resource *op = data;
@@ -1859,6 +1922,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_MAP                        */ wined3d_cs_exec_map,
     /* WINED3D_CS_OP_UNMAP                      */ wined3d_cs_exec_unmap,
     /* WINED3D_CS_OP_BLT_SUB_RESOURCE           */ wined3d_cs_exec_blt_sub_resource,
+    /* WINED3D_CS_OP_COPY_SUB_RESOURCE          */ wined3d_cs_exec_copy_sub_resource,
     /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE        */ wined3d_cs_exec_update_sub_resource,
 };
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index eef9818..0bc494e 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3886,8 +3886,8 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
         box.front = 0;
         box.back = 1;
 
-        wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, 0, &box,
-                src_resource, 0, &box, 0, NULL, WINED3D_TEXF_POINT);
+        wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, 0, &box,
+                src_resource, 0, &box);
         return;
     }
 
@@ -3922,8 +3922,8 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
         {
             unsigned int idx = j * dst_texture->level_count + i;
 
-            wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, idx, &box,
-                    src_resource, idx, &box, 0, NULL, WINED3D_TEXF_POINT);
+            wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, idx, &box,
+                    src_resource, idx, &box);
         }
     }
 }
@@ -4075,8 +4075,8 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
         return WINED3DERR_INVALIDCALL;
     }
 
-    wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box,
-            src_resource, src_sub_resource_idx, src_box, 0, NULL, WINED3D_TEXF_POINT);
+    wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box,
+            src_resource, src_sub_resource_idx, src_box);
 
     return WINED3D_OK;
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1a01106..d0f7e7e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3231,6 +3231,9 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_reso
         const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects,
         DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_copy_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource,
+        unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource,
+        unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_dispatch(struct wined3d_cs *cs,
         unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, int base_vertex_idx,
-- 
2.10.2




More information about the wine-patches mailing list