wined3d: Handle system memory copies in wined3d_texture_load_location().
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
351e6ddf09
commit
a7e5d4038c
|
@ -2496,45 +2496,6 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
|
||||||
return WINED3DERR_INVALIDCALL;
|
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. */
|
/* Context activation is done by the caller. */
|
||||||
static void surface_load_sysmem(struct wined3d_surface *surface,
|
static void surface_load_sysmem(struct wined3d_surface *surface,
|
||||||
struct wined3d_context *context, DWORD dst_location)
|
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);
|
wined3d_texture_prepare_location(texture, sub_resource_idx, context, dst_location);
|
||||||
|
|
||||||
sub_resource = &texture->sub_resources[sub_resource_idx];
|
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))
|
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);
|
wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
|
||||||
|
|
||||||
|
|
|
@ -178,11 +178,56 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture,
|
||||||
sub_resource_idx, 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
|
/* Context activation is done by the caller. Context may be NULL in
|
||||||
* WINED3D_NO3D mode. */
|
* WINED3D_NO3D mode. */
|
||||||
BOOL wined3d_texture_load_location(struct wined3d_texture *texture,
|
BOOL wined3d_texture_load_location(struct wined3d_texture *texture,
|
||||||
unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
|
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;
|
DWORD current = texture->sub_resources[sub_resource_idx].locations;
|
||||||
BOOL ret;
|
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);
|
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);
|
wined3d_texture_validate_location(texture, sub_resource_idx, location);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue