Module: wine Branch: master Commit: 87192548edc106510879ec5bfd1e5cd40f7c64fe URL: http://source.winehq.org/git/wine.git/?a=commit;h=87192548edc106510879ec5bfd...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Wed Mar 8 10:53:02 2017 +0100
wined3d: Send blits through the command stream.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wined3d/cs.c | 69 ++++++++++++++++++++++++++++++++++++++++++ dlls/wined3d/texture.c | 11 ++++--- dlls/wined3d/wined3d_private.h | 4 +++ 3 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 9f3de81..6de8dbd 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -63,6 +63,7 @@ enum wined3d_cs_op WINED3D_CS_OP_UNLOAD_RESOURCE, WINED3D_CS_OP_MAP, WINED3D_CS_OP_UNMAP, + WINED3D_CS_OP_BLT_SUB_RESOURCE, WINED3D_CS_OP_UPDATE_SUB_RESOURCE, };
@@ -345,6 +346,20 @@ struct wined3d_cs_unmap HRESULT *hr; };
+struct wined3d_cs_blt_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; + DWORD flags; + struct wined3d_blt_fx fx; + enum wined3d_texture_filter_type filter; +}; + struct wined3d_cs_update_sub_resource { enum wined3d_cs_op opcode; @@ -1657,6 +1672,59 @@ HRESULT wined3d_cs_unmap(struct wined3d_cs *cs, struct wined3d_resource *resourc return hr; }
+static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *data) +{ + struct wined3d_surface *dst_surface, *src_surface = NULL; + const struct wined3d_cs_blt_sub_resource *op = data; + struct wined3d_texture *dst_texture, *src_texture; + RECT src_rect, dst_rect; + + dst_texture = texture_from_resource(op->dst_resource); + dst_surface = dst_texture->sub_resources[op->dst_sub_resource_idx].u.surface; + if (op->src_resource) + { + 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, op->flags, &op->fx, op->filter))) + FIXME("Blit failed.\n"); + + if (op->src_resource) + wined3d_resource_release(op->src_resource); + wined3d_resource_release(op->dst_resource); +} + +void wined3d_cs_emit_blt_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, DWORD flags, + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) +{ + struct wined3d_cs_blt_sub_resource *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_BLT_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; + op->flags = flags; + if (fx) + op->fx = *fx; + op->filter = filter; + + wined3d_resource_acquire(dst_resource); + if (src_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; @@ -1775,6 +1843,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_UNLOAD_RESOURCE */ wined3d_cs_exec_unload_resource, /* 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_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, };
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 4dea254..2688735 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -2629,7 +2629,6 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned { struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; - struct wined3d_texture_sub_resource *dst_resource, *src_resource = NULL; unsigned int dst_format_flags, src_format_flags = 0; HRESULT hr;
@@ -2638,7 +2637,7 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture, src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter));
- if (!(dst_resource = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx)) + if (dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) return WINED3DERR_INVALIDCALL;
@@ -2649,7 +2648,7 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned
if (src_texture) { - if (!(src_resource = wined3d_texture_get_sub_resource(src_texture, src_sub_resource_idx)) + if (src_sub_resource_idx >= src_texture->level_count * src_texture->layer_count || src_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) return WINED3DERR_INVALIDCALL;
@@ -2680,8 +2679,10 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned return WINED3DERR_INVALIDCALL; }
- return wined3d_surface_blt(dst_resource->u.surface, dst_rect, - src_resource ? src_resource->u.surface : NULL, src_rect, flags, fx, filter); + wined3d_cs_emit_blt_sub_resource(dst_texture->resource.device->cs, &dst_texture->resource, dst_sub_resource_idx, + &dst_box, src_texture ? &src_texture->resource : NULL, src_sub_resource_idx, &src_box, flags, fx, filter); + + return WINED3D_OK; }
HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture *texture, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 48f2f36..e8c858e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3212,6 +3212,10 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HID void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_destroy_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object) DECLSPEC_HIDDEN; +void wined3d_cs_emit_blt_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, DWORD flags, + 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_dispatch(struct wined3d_cs *cs,