From: Elizabeth Figura <zfigura@codeweavers.com> A resolve which involves scaling or conversion, but is not typeless, can only go through the FBO blitter. Such a resolve is a colour or depth blit, not a raw blit, so it can't go through the raw blitter, and the GLSL blitter doesn't handle multisampled source textures. Going forward we can probably simplify this logic further to avoid recursion. --- dlls/wined3d/surface.c | 10 ++-------- dlls/wined3d/texture_gl.c | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 47aef38885a..cf081a17c68 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1379,7 +1379,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ BOOL scale, convert, resolve, resolve_typeless = FALSE; const struct wined3d_format *resolve_format = NULL; const struct wined3d_color_key *colour_key = NULL; - DWORD src_location, dst_location, valid_locations; + DWORD dst_location, valid_locations; struct wined3d_context *context; enum wined3d_blit_op blit_op; RECT src_rect, dst_rect; @@ -1613,12 +1613,6 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ context = context_acquire(device, dst_texture, dst_sub_resource_idx); - if (src_texture->resource.multisample_type != WINED3D_MULTISAMPLE_NONE && !resolve_typeless - && ((scale && !context->d3d_info->scaled_resolve) || convert)) - src_location = WINED3D_LOCATION_RB_RESOLVED; - else - src_location = src_texture->resource.draw_binding; - if (!(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) dst_location = dst_texture->resource.map_binding; else if (dst_texture->resource.multisample_type != WINED3D_MULTISAMPLE_NONE @@ -1628,7 +1622,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ dst_location = dst_texture->resource.draw_binding; valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context, - src_texture, src_sub_resource_idx, src_location, &src_rect, + src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect, dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, colour_key, filter, resolve_format); context_release(context); diff --git a/dlls/wined3d/texture_gl.c b/dlls/wined3d/texture_gl.c index 19f5987b041..87f02cbaa6f 100644 --- a/dlls/wined3d/texture_gl.c +++ b/dlls/wined3d/texture_gl.c @@ -697,7 +697,7 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont { struct wined3d_texture *required_texture, *restore_texture, *dst_save_texture = dst_texture; unsigned int restore_idx, dst_save_sub_resource_idx = dst_sub_resource_idx; - bool resolve, scaled_resolve, restore_context = false; + bool resolve, scaled_resolve, typeless_resolve, restore_context = false; struct wined3d_texture *src_staging_texture = NULL; const struct wined3d_gl_info *gl_info; struct wined3d_context_gl *context_gl; @@ -715,6 +715,19 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont scaled_resolve = resolve && (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)); + typeless_resolve = resolve && (wined3d_format_is_typeless(src_texture->resource.format) + || wined3d_format_is_typeless(dst_texture->resource.format)) + && (src_texture->resource.format->typeless_id == dst_texture->resource.format->typeless_id); + + if (resolve && !typeless_resolve) + { + if ((scaled_resolve && !context->d3d_info->scaled_resolve) + || src_texture->resource.format->id != dst_texture->resource.format->id) + { + src_location = WINED3D_LOCATION_RB_RESOLVED; + resolve = scaled_resolve = typeless_resolve = false; + } + } if (filter == WINED3D_TEXF_LINEAR) gl_filter = scaled_resolve ? GL_SCALED_RESOLVE_NICEST_EXT : GL_LINEAR; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10465