From a7e5d4038c3a1557ef902499addf16724940b2c1 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 17 Feb 2017 14:08:16 +0100 Subject: [PATCH] wined3d: Handle system memory copies in wined3d_texture_load_location(). Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/surface.c | 45 ------------------------------------ dlls/wined3d/texture.c | 52 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 507be21e94b..b30585c9133 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -2496,45 +2496,6 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE return WINED3DERR_INVALIDCALL; } -static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) -{ - unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); - struct wined3d_texture *texture = surface->container; - struct wined3d_device *device = texture->resource.device; - struct wined3d_texture_sub_resource *sub_resource; - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - struct wined3d_bo_address dst, src; - - sub_resource = &texture->sub_resources[sub_resource_idx]; - wined3d_texture_get_memory(texture, sub_resource_idx, &dst, location); - wined3d_texture_get_memory(texture, sub_resource_idx, &src, sub_resource->locations); - - if (dst.buffer_object) - { - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); - GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, sub_resource->size, src.addr)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Upload PBO"); - context_release(context); - return; - } - if (src.buffer_object) - { - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); - GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, dst.addr)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("Download PBO"); - context_release(context); - return; - } - memcpy(dst.addr, src.addr, sub_resource->size); -} - /* Context activation is done by the caller. */ static void surface_load_sysmem(struct wined3d_surface *surface, struct wined3d_context *context, DWORD dst_location) @@ -2547,12 +2508,6 @@ static void surface_load_sysmem(struct wined3d_surface *surface, wined3d_texture_prepare_location(texture, sub_resource_idx, context, dst_location); sub_resource = &texture->sub_resources[sub_resource_idx]; - if (sub_resource->locations & surface_simple_locations) - { - surface_copy_simple_location(surface, dst_location); - return; - } - if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index e6f2c6cd892..d86e7ec281c 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -178,11 +178,56 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture, sub_resource_idx, texture); } +static BOOL wined3d_texture_copy_sysmem_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) +{ + unsigned int size = texture->sub_resources[sub_resource_idx].size; + struct wined3d_device *device = texture->resource.device; + const struct wined3d_gl_info *gl_info; + struct wined3d_bo_address dst, src; + + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) + return FALSE; + + wined3d_texture_get_memory(texture, sub_resource_idx, &dst, location); + wined3d_texture_get_memory(texture, sub_resource_idx, &src, + texture->sub_resources[sub_resource_idx].locations); + + if (dst.buffer_object) + { + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); + GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("PBO upload"); + context_release(context); + return TRUE; + } + + if (src.buffer_object) + { + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); + GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("PBO download"); + context_release(context); + return TRUE; + } + + memcpy(dst.addr, src.addr, size); + return TRUE; +} + /* Context activation is done by the caller. Context may be NULL in * WINED3D_NO3D mode. */ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) { + static const DWORD sysmem_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY + | WINED3D_LOCATION_BUFFER; DWORD current = texture->sub_resources[sub_resource_idx].locations; BOOL ret; @@ -223,7 +268,12 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, return wined3d_texture_load_location(texture, sub_resource_idx, context, location); } - if ((ret = texture->texture_ops->texture_load_location(texture, sub_resource_idx, context, location))) + if ((location & sysmem_locations) && (current & sysmem_locations)) + ret = wined3d_texture_copy_sysmem_location(texture, sub_resource_idx, context, location); + else + ret = texture->texture_ops->texture_load_location(texture, sub_resource_idx, context, location); + + if (ret) wined3d_texture_validate_location(texture, sub_resource_idx, location); return ret;