From a2c5afe61e27eaac9449b00ff5b5a849c7a192a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Thu, 31 Mar 2016 22:48:54 +0200 Subject: [PATCH] wined3d: Introduce wined3d_texture_get_memory(). Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/surface.c | 59 +++++------------- dlls/wined3d/texture.c | 106 +++++++++++++++++++++------------ dlls/wined3d/wined3d_private.h | 2 + 3 files changed, 85 insertions(+), 82 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 6d0e1471e3d..04f30c67f10 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -454,39 +454,6 @@ HRESULT surface_create_dib_section(struct wined3d_surface *surface) return WINED3D_OK; } -static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data, - DWORD location) -{ - if (location & WINED3D_LOCATION_BUFFER) - { - data->addr = NULL; - data->buffer_object = surface->container->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object; - return; - } - if (location & WINED3D_LOCATION_USER_MEMORY) - { - data->addr = surface->container->user_memory; - data->buffer_object = 0; - return; - } - if (location & WINED3D_LOCATION_DIB) - { - data->addr = surface->dib.bitmap_data; - data->buffer_object = 0; - return; - } - if (location & WINED3D_LOCATION_SYSMEM) - { - data->addr = surface->resource.heap_memory; - data->buffer_object = 0; - return; - } - - ERR("Unexpected locations %s.\n", wined3d_debug_location(location)); - data->addr = NULL; - data->buffer_object = 0; -} - static void surface_prepare_system_memory(struct wined3d_surface *surface) { TRACE("surface %p.\n", surface); @@ -1013,7 +980,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct return; } - surface_get_memory(surface, &data, dst_location); + wined3d_texture_get_memory(texture, surface_get_sub_resource_idx(surface), &data, dst_location); if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) { @@ -1268,6 +1235,7 @@ static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, cons HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, struct wined3d_surface *src_surface, const RECT *src_rect) { + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); struct wined3d_texture *src_texture = src_surface->container; struct wined3d_texture *dst_texture = dst_surface->container; @@ -1364,7 +1332,8 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P surface_load_location(dst_surface, context, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); - surface_get_memory(src_surface, &data, surface_get_sub_resource(src_surface)->locations); + wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data, + src_texture->sub_resources[src_sub_resource_idx].locations); wined3d_texture_get_pitch(src_texture, src_surface->texture_level, &src_row_pitch, &src_slice_pitch); wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, @@ -1844,6 +1813,7 @@ do { \ static void read_from_framebuffer(struct wined3d_surface *surface, struct wined3d_context *old_ctx, DWORD dst_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; const struct wined3d_gl_info *gl_info; @@ -1856,7 +1826,7 @@ static void read_from_framebuffer(struct wined3d_surface *surface, BOOL srcIsUpsideDown; struct wined3d_bo_address data; - surface_get_memory(surface, &data, dst_location); + wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); restore_rt = context_get_rt_surface(old_ctx); if (restore_rt != surface) @@ -2943,14 +2913,17 @@ static DWORD resource_access_from_location(DWORD location) static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) { - struct wined3d_device *device = surface->container->resource.device; + 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_context *context; const struct wined3d_gl_info *gl_info; struct wined3d_bo_address dst, src; UINT size = surface->resource.size; - surface_get_memory(surface, &dst, location); - surface_get_memory(surface, &src, surface_get_sub_resource(surface)->locations); + 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) { @@ -3046,6 +3019,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, { unsigned int width, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; const RECT src_rect = {0, 0, surface->resource.width, surface->resource.height}; + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_texture *texture = surface->container; struct wined3d_device *device = texture->resource.device; @@ -3142,8 +3116,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, /* Don't use PBOs for converted surfaces. During PBO conversion we look at * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is * getting called. */ - if ((format.convert || conversion) - && texture->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object) + if ((format.convert || conversion) && texture->sub_resources[sub_resource_idx].buffer_object) { TRACE("Removing the pbo attached to surface %p.\n", surface); @@ -3153,10 +3126,10 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, surface->resource.map_binding = WINED3D_LOCATION_SYSMEM; surface_load_location(surface, context, surface->resource.map_binding); - wined3d_texture_remove_buffer_object(texture, surface_get_sub_resource_idx(surface), gl_info); + wined3d_texture_remove_buffer_object(texture, sub_resource_idx, gl_info); } - surface_get_memory(surface, &data, sub_resource->locations); + wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->locations); if (format.convert) { /* This code is entered for texture formats which need a fixup. */ diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 279c174069c..851dfc8c5ca 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -104,6 +104,50 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture, sub_resource_idx, texture); } +void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_bo_address *data, DWORD locations) +{ + struct wined3d_texture_sub_resource *sub_resource; + + TRACE("texture %p, sub_resource_idx %u, data %p, locations %s.\n", + texture, sub_resource_idx, data, wined3d_debug_location(locations)); + + sub_resource = &texture->sub_resources[sub_resource_idx]; + if (locations & WINED3D_LOCATION_BUFFER) + { + data->addr = NULL; + data->buffer_object = sub_resource->buffer_object; + return; + } + if (locations & WINED3D_LOCATION_USER_MEMORY) + { + data->addr = texture->user_memory; + data->buffer_object = 0; + return; + } + if (locations & WINED3D_LOCATION_DIB) + { + if (texture->resource.type == WINED3D_RTYPE_TEXTURE_2D) + { + data->addr = sub_resource->u.surface->dib.bitmap_data; + data->buffer_object = 0; + return; + } + ERR("Invalid location WINED3D_LOCATION_DIB for resource type %s.\n", + debug_d3dresourcetype(texture->resource.type)); + } + if (locations & WINED3D_LOCATION_SYSMEM) + { + data->addr = sub_resource->resource->heap_memory; + data->buffer_object = 0; + return; + } + + ERR("Unexpected locations %s.\n", wined3d_debug_location(locations)); + data->addr = NULL; + data->buffer_object = 0; +} + static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops, UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops, @@ -1215,6 +1259,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour struct wined3d_context *context = NULL; struct wined3d_resource *sub_resource; struct wined3d_texture *texture; + struct wined3d_bo_address data; unsigned int texture_level; BYTE *base_memory; BOOL ret; @@ -1290,48 +1335,31 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) wined3d_texture_invalidate_location(texture, sub_resource_idx, ~sub_resource->map_binding); - switch (sub_resource->map_binding) + wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->map_binding); + if (!data.buffer_object) { - case WINED3D_LOCATION_SYSMEM: - base_memory = sub_resource->heap_memory; - break; + base_memory = data.addr; + } + else + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data.buffer_object)); - case WINED3D_LOCATION_USER_MEMORY: - base_memory = texture->user_memory; - break; + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GLbitfield map_flags = wined3d_resource_gl_map_flags(flags); + map_flags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; + base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, + (INT_PTR)data.addr, sub_resource->size, map_flags)); + } + else + { + GLenum access = wined3d_resource_gl_legacy_map_flags(flags); + base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); + base_memory += (INT_PTR)data.addr; + } - case WINED3D_LOCATION_DIB: - if (resource->type != WINED3D_RTYPE_TEXTURE_2D) - ERR("Invalid map binding %#x for resource type %#x.\n", - sub_resource->map_binding, resource->type); - base_memory = texture->sub_resources[sub_resource_idx].u.surface->dib.bitmap_data; - break; - - case WINED3D_LOCATION_BUFFER: - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, - texture->sub_resources[sub_resource_idx].buffer_object)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - GLbitfield map_flags = wined3d_resource_gl_map_flags(flags); - map_flags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; - base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, - 0, sub_resource->size, map_flags)); - } - else - { - GLenum access = wined3d_resource_gl_legacy_map_flags(flags); - base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); - } - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Map PBO"); - break; - - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(sub_resource->map_binding)); - base_memory = NULL; - break; + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("Map PBO"); } if (context) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b86c460eb44..e56689b7897 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2484,6 +2484,8 @@ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, BOOL wined3d_texture_check_block_align(const struct wined3d_texture *texture, unsigned int level, const struct wined3d_box *box) 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; struct wined3d_resource *wined3d_texture_get_sub_resource(const struct wined3d_texture *texture, UINT sub_resource_idx) DECLSPEC_HIDDEN; void wined3d_texture_invalidate_location(struct wined3d_texture *texture,