Signed-off-by: Andrew Wesie awesie@gmail.com --- 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 6711e83..78e9364 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -3802,3 +3802,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 a2dcbb0..4812fa5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3352,6 +3352,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;