Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/surface.c | 62 ++------------------------- dlls/wined3d/texture.c | 97 +++++++++++++++++++++++------------------- dlls/wined3d/wined3d_private.h | 38 +++++++++++------ 3 files changed, 81 insertions(+), 116 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 8d67e52afa2..33b60d2bc0b 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -138,15 +138,6 @@ static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct checkGLcall("glBlitFramebuffer()"); }
-static BOOL is_multisample_location(const struct wined3d_texture_gl *texture_gl, DWORD location) -{ - if (location == WINED3D_LOCATION_RB_MULTISAMPLE) - return TRUE; - if (location != WINED3D_LOCATION_TEXTURE_RGB && location != WINED3D_LOCATION_TEXTURE_SRGB) - return FALSE; - return texture_gl->target == GL_TEXTURE_2D_MULTISAMPLE || texture_gl->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY; -} - /* Blit between surface locations. Onscreen on different swapchains is not supported. * Depth / stencil is not supported. Context activation is done by the caller. */ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *context, @@ -185,7 +176,7 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont }
/* Resolve the source surface first if needed. */ - if (is_multisample_location(wined3d_texture_gl(src_texture), src_location) + if (wined3d_texture_gl_is_multisample_location(wined3d_texture_gl(src_texture), src_location) && (src_texture->resource.format->id != dst_texture->resource.format->id || abs(src_rect->bottom - src_rect->top) != abs(dst_rect->bottom - dst_rect->top) || abs(src_rect->right - src_rect->left) != abs(dst_rect->right - dst_rect->left))) @@ -708,7 +699,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr return dst_texture; }
-static void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, +void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD src_location, DWORD dst_location) { struct wined3d_resource *resource = &texture->resource; @@ -1432,52 +1423,6 @@ static HRESULT wined3d_texture_blt_special(struct wined3d_texture *dst_texture, }
/* Context activation is done by the caller. */ -BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD dst_location) -{ - struct wined3d_texture_sub_resource *sub_resource; - - sub_resource = &texture->sub_resources[sub_resource_idx]; - wined3d_texture_prepare_location(texture, sub_resource_idx, context, dst_location); - - /* We cannot download data from multisample textures directly. */ - if (is_multisample_location(wined3d_texture_gl(texture), WINED3D_LOCATION_TEXTURE_RGB)) - { - wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_RB_RESOLVED); - texture2d_read_from_framebuffer(texture, sub_resource_idx, context, - WINED3D_LOCATION_RB_RESOLVED, dst_location); - return TRUE; - } - - 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); - - /* Download the sub-resource to system memory. */ - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data; - wined3d_texture_gl_bind_and_dirtify(wined3d_texture_gl(texture), wined3d_context_gl(context), - !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)); - wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); - wined3d_texture_download_data(texture, sub_resource_idx, context, &data); - ++texture->download_count; - return TRUE; - } - - if (!(texture->resource.bind_flags & WINED3D_BIND_DEPTH_STENCIL) - && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) - { - texture2d_read_from_framebuffer(texture, sub_resource_idx, context, - texture->resource.draw_binding, dst_location); - return TRUE; - } - - FIXME("Can't load texture %p, %u with location flags %s into sysmem.\n", - texture, sub_resource_idx, wined3d_debug_location(sub_resource->locations)); - return FALSE; -} - -/* Context activation is done by the caller. */ BOOL texture2d_load_drawable(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context) { @@ -3359,7 +3304,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ 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(wined3d_texture_gl(src_texture), WINED3D_LOCATION_TEXTURE_RGB)) + else if (wined3d_texture_gl_is_multisample_location(wined3d_texture_gl(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"); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 16f0a56875f..13ebd311718 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -2433,6 +2433,53 @@ void wined3d_texture_download_data(struct wined3d_texture *texture, unsigned int } }
+/* Context activation is done by the caller. */ +static BOOL wined3d_texture_gl_load_sysmem(struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl, DWORD dst_location) +{ + struct wined3d_texture_sub_resource *sub_resource; + + sub_resource = &texture_gl->t.sub_resources[sub_resource_idx]; + wined3d_texture_prepare_location(&texture_gl->t, sub_resource_idx, &context_gl->c, dst_location); + + /* We cannot download data from multisample textures directly. */ + if (wined3d_texture_gl_is_multisample_location(texture_gl, WINED3D_LOCATION_TEXTURE_RGB)) + { + wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_RB_RESOLVED); + texture2d_read_from_framebuffer(&texture_gl->t, sub_resource_idx, &context_gl->c, + WINED3D_LOCATION_RB_RESOLVED, dst_location); + return TRUE; + } + + if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) + wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_TEXTURE_RGB); + + /* Download the sub-resource to system memory. */ + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { + struct wined3d_bo_address data; + wined3d_texture_gl_bind_and_dirtify(texture_gl, context_gl, + !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)); + wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &data, dst_location); + wined3d_texture_download_data(&texture_gl->t, sub_resource_idx, &context_gl->c, &data); + ++texture_gl->t.download_count; + return TRUE; + } + + if (!(texture_gl->t.resource.bind_flags & WINED3D_BIND_DEPTH_STENCIL) + && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) + { + texture2d_read_from_framebuffer(&texture_gl->t, sub_resource_idx, &context_gl->c, + texture_gl->t.resource.draw_binding, dst_location); + return TRUE; + } + + FIXME("Can't load texture %p, %u with location flags %s into sysmem.\n", + texture_gl, sub_resource_idx, wined3d_debug_location(sub_resource->locations)); + + return FALSE; +} + /* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */ static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) @@ -2445,7 +2492,8 @@ static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned in case WINED3D_LOCATION_USER_MEMORY: case WINED3D_LOCATION_SYSMEM: case WINED3D_LOCATION_BUFFER: - return texture2d_load_sysmem(texture, sub_resource_idx, context, location); + return wined3d_texture_gl_load_sysmem(wined3d_texture_gl(texture), + sub_resource_idx, wined3d_context_gl(context), location);
case WINED3D_LOCATION_DRAWABLE: return texture2d_load_drawable(texture, sub_resource_idx, context); @@ -2845,6 +2893,7 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in struct wined3d_context *context, DWORD location) { struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture); struct wined3d_context_gl *context_gl = wined3d_context_gl(context); unsigned int row_pitch, slice_pitch;
@@ -2864,8 +2913,7 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in struct wined3d_box src_box;
data.addr += sub_resource->offset; - wined3d_texture_gl_bind_and_dirtify(wined3d_texture_gl(texture), - context_gl, location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_texture_gl_bind_and_dirtify(texture_gl, context_gl, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box); wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format, @@ -2876,8 +2924,7 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; struct wined3d_box src_box;
- wined3d_texture_gl_bind_and_dirtify(wined3d_texture_gl(texture), context_gl, - location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_texture_gl_bind_and_dirtify(texture_gl, context_gl, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box); wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format, @@ -2891,46 +2938,8 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in break;
case WINED3D_LOCATION_SYSMEM: - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {0, texture->resource.heap_memory}; - - data.addr += sub_resource->offset; - if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_gl_bind_and_dirtify(wined3d_texture_gl(texture), context_gl, FALSE); - else - wined3d_texture_gl_bind_and_dirtify(wined3d_texture_gl(texture), context_gl, TRUE); - - wined3d_texture_download_data(texture, sub_resource_idx, context, &data); - ++texture->download_count; - } - else - { - FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; - case WINED3D_LOCATION_BUFFER: - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; - - if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_gl_bind_and_dirtify(wined3d_texture_gl(texture), context_gl, FALSE); - else - wined3d_texture_gl_bind_and_dirtify(wined3d_texture_gl(texture), context_gl, TRUE); - - wined3d_texture_download_data(texture, sub_resource_idx, context, &data); - } - else - { - FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; + return wined3d_texture_gl_load_sysmem(texture_gl, sub_resource_idx, context_gl, location);
default: FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bbcc6acf164..aebaa9ed2f2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3372,6 +3372,18 @@ void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DEC #define RESOURCE_ALIGNMENT 16 #define WINED3D_CONSTANT_BUFFER_ALIGNMENT 16
+#define WINED3D_LOCATION_DISCARDED 0x00000001 +#define WINED3D_LOCATION_SYSMEM 0x00000002 +#define WINED3D_LOCATION_USER_MEMORY 0x00000004 +#define WINED3D_LOCATION_BUFFER 0x00000008 +#define WINED3D_LOCATION_TEXTURE_RGB 0x00000010 +#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000020 +#define WINED3D_LOCATION_DRAWABLE 0x00000040 +#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000080 +#define WINED3D_LOCATION_RB_RESOLVED 0x00000100 + +const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN; + struct wined3d_blt_info { GLenum bind_target; @@ -3533,10 +3545,10 @@ void texture2d_load_fb_texture(struct wined3d_texture_gl *texture_gl, unsigned i BOOL srgb, struct wined3d_context *context) DECLSPEC_HIDDEN; BOOL texture2d_load_renderbuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD dst_location) DECLSPEC_HIDDEN; -BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD dst_location) DECLSPEC_HIDDEN; BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; +void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD src_location, DWORD dst_location) DECLSPEC_HIDDEN;
HRESULT wined3d_texture_check_box_dimensions(const struct wined3d_texture *texture, unsigned int level, const struct wined3d_box *box) DECLSPEC_HIDDEN; @@ -3622,6 +3634,16 @@ static inline GLenum wined3d_texture_gl_get_sub_resource_target(const struct win ? cube_targets[sub_resource_idx / texture_gl->t.level_count] : texture_gl->target; }
+static inline BOOL wined3d_texture_gl_is_multisample_location(const struct wined3d_texture_gl *texture_gl, + DWORD location) +{ + if (location == WINED3D_LOCATION_RB_MULTISAMPLE) + return TRUE; + if (location != WINED3D_LOCATION_TEXTURE_RGB && location != WINED3D_LOCATION_TEXTURE_SRGB) + return FALSE; + return texture_gl->target == GL_TEXTURE_2D_MULTISAMPLE || texture_gl->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY; +} + void wined3d_texture_gl_apply_sampler_desc(struct wined3d_texture_gl *texture_gl, const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; void wined3d_texture_gl_bind(struct wined3d_texture_gl *texture_gl, @@ -3634,18 +3656,6 @@ void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *t struct wined3d_context_gl *context_gl, unsigned int level, const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
-#define WINED3D_LOCATION_DISCARDED 0x00000001 -#define WINED3D_LOCATION_SYSMEM 0x00000002 -#define WINED3D_LOCATION_USER_MEMORY 0x00000004 -#define WINED3D_LOCATION_BUFFER 0x00000008 -#define WINED3D_LOCATION_TEXTURE_RGB 0x00000010 -#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000020 -#define WINED3D_LOCATION_DRAWABLE 0x00000040 -#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000080 -#define WINED3D_LOCATION_RB_RESOLVED 0x00000100 - -const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN; - struct wined3d_renderbuffer_entry { struct list entry;