[PATCH 2/2] wined3d: Handle typeless multisample resolve.

Jan Sikorski jsikorski at codeweavers.com
Wed Feb 24 04:40:35 CST 2021


Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
---
 dlls/d3d11/tests/d3d11.c          |  18 +-
 dlls/d3d8/device.c                |   6 +-
 dlls/d3d9/device.c                |   4 +-
 dlls/ddraw/device.c               |   2 +-
 dlls/ddraw/surface.c              |   6 +-
 dlls/wined3d/arb_program_shader.c |   8 +-
 dlls/wined3d/cs.c                 |  10 +-
 dlls/wined3d/device.c             |  12 +-
 dlls/wined3d/glsl_shader.c        |   8 +-
 dlls/wined3d/surface.c            |  12 +-
 dlls/wined3d/swapchain.c          |   4 +-
 dlls/wined3d/texture.c            | 440 +++++++++++++++++++++++++++---
 dlls/wined3d/wined3d_private.h    |   6 +-
 include/wine/wined3d.h            |   2 +-
 14 files changed, 448 insertions(+), 90 deletions(-)

diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index aa500634fe1..ebe7486972b 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -30296,13 +30296,13 @@ static void test_multisample_resolve2(void)
             4, { 0, 0, 0, 0x3f } },
         { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS,
             DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT,
-            4, { 0, 0, 0, 0x3f }, TRUE },
+            4, { 0, 0, 0, 0x3f } },
         { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT,
             DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT,
-            4, { 0, 0, 0, 0x3f }, TRUE },
+            4, { 0, 0, 0, 0x3f } },
         { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS,
             DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT,
-            4, { 0, 0, 0, 0x3f }, TRUE },
+            4, { 0, 0, 0, 0x3f } },
         { FALSE, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM,
             DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM,
             2, { 0, 0x80 } },
@@ -30314,7 +30314,7 @@ static void test_multisample_resolve2(void)
             2, { 0xff, 0x37 } },
         { FALSE, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_TYPELESS,
             DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM,
-            2, { 0x66, 0x36 }, TRUE },
+            2, { 0x66, 0x36 } },
         { FALSE, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_TYPELESS,
             DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_FLOAT,
             2, { 0xbd, 0xc8 } },
@@ -30323,16 +30323,16 @@ static void test_multisample_resolve2(void)
             4, { 0x80, 0x19, 0x19, 0xff } },
         { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS,
             DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
-            4, { 0x99, 0x23, 0x23, 0xff }, TRUE },
+            4, { 0x99, 0x23, 0x23, 0xff } },
         { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS,
             DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
-            4, { 0x99, 0x23, 0x23, 0xff }, TRUE },
+            4, { 0x99, 0x23, 0x23, 0xff } },
         { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS,
             DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_SNORM,
-            4, { 0, 0x19, 0x19, 0xff }, TRUE },
+            4, { 0, 0x19, 0x19, 0xff } },
         { FALSE, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS,
             DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM,
-            4, { 0x3f, 0xc, 0xc, 0x7f }, TRUE },
+            4, { 0x3f, 0xc, 0xc, 0x7f } },
         { TRUE, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_TYPELESS,
             DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM,
             4, { 0x3f, 0, 0, 0x40 }, TRUE },
@@ -30487,7 +30487,7 @@ static void test_multisample_resolve(void)
          DXGI_FORMAT_R8G8B8A8_TYPELESS,
          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
-         &color, 0xffe1bc89, TRUE},
+         &color, 0xffe1bc89},
         {DXGI_FORMAT_R8G8B8A8_TYPELESS,
          DXGI_FORMAT_R8G8B8A8_TYPELESS,
          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index f4bdb748275..93fc55db73c 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -1395,7 +1395,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
     {
         RECT rect = {0, 0, src_w, src_h};
         wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &rect,
-                src->wined3d_texture, src->sub_resource_idx, &rect, 0, NULL, WINED3D_TEXF_POINT);
+                src->wined3d_texture, src->sub_resource_idx, &rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
     }
     else
     {
@@ -1411,7 +1411,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
                         dst_points[i].x + w, dst_points[i].y + h};
 
                 wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect,
-                        src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
+                        src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
             }
         }
         else
@@ -1423,7 +1423,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
                 RECT dst_rect = {0, 0, w, h};
 
                 wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect,
-                        src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
+                        src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
             }
         }
     }
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index fec631e0e67..ec6839751af 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -1773,7 +1773,7 @@ static HRESULT WINAPI d3d9_device_GetRenderTargetData(IDirect3DDevice9Ex *iface,
         hr = D3DERR_INVALIDCALL;
     else
         hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect,
-                rt_impl->wined3d_texture, rt_impl->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
+                rt_impl->wined3d_texture, rt_impl->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
     wined3d_mutex_unlock();
 
     return hr;
@@ -1874,7 +1874,7 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect
     }
 
     hr = wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, dst_rect, src->wined3d_texture,
-            src->sub_resource_idx, src_rect, 0, NULL, wined3d_texture_filter_type_from_d3d(filter));
+            src->sub_resource_idx, src_rect, 0, NULL, wined3d_texture_filter_type_from_d3d(filter), WINED3DFMT_UNKNOWN);
     if (hr == WINEDDERR_INVALIDRECT)
         hr = D3DERR_INVALIDCALL;
     if (SUCCEEDED(hr) && dst->texture)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 4d24c22650e..c187be02980 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -6123,7 +6123,7 @@ static void copy_mipmap_chain(struct d3d_device *device, struct ddraw_surface *d
             RECT dst_rect = {point.x, point.y, point.x + src_w, point.y + src_h};
 
             if (FAILED(hr = wined3d_texture_blt(dst_level->wined3d_texture, dst_level->sub_resource_idx, &dst_rect,
-                    src_level->wined3d_texture, src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT)))
+                    src_level->wined3d_texture, src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN)))
                 ERR("Blit failed, hr %#x.\n", hr);
 
             ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 0ca19d4f8a5..686fc267c43 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -113,7 +113,7 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
             dst_texture = ddraw->wined3d_frontbuffer;
 
         if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture,
-                surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval)
+                surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN)) && swap_interval)
         {
             hr = wined3d_swapchain_present(ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0);
             ddraw->flags |= DDRAW_SWAPPED;
@@ -1535,7 +1535,7 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT *
         wined3d_flags |= WINED3D_BLT_SYNCHRONOUS;
 
     return wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, dst_rect,
-            src_surface->wined3d_texture, src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter);
+            src_surface->wined3d_texture, src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter, WINED3DFMT_UNKNOWN);
 }
 
 static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, const RECT *dst_rect_in,
@@ -4377,7 +4377,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac
         hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0);
     if (SUCCEEDED(hr))
         hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect,
-                src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT);
+                src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
     if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
         hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0);
     wined3d_mutex_unlock();
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index af8f2a508fa..bd23f0830b4 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -7792,7 +7792,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
         struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
         DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
         unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
-        const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
+        const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture);
     struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
@@ -7805,10 +7805,10 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
     RECT s, d;
 
     TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, "
-            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n",
+            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s, format_id %s.\n",
             blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location),
             wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location),
-            wine_dbgstr_rect(dst_rect), color_key, debug_d3dtexturefiltertype(filter));
+            wine_dbgstr_rect(dst_rect), color_key, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
 
     if (!arbfp_blit_supported(op, context, &src_texture->resource, src_location,
             &dst_texture->resource, dst_location))
@@ -7821,7 +7821,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
 
         TRACE("Forwarding to blitter %p.\n", next);
         return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
-                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter);
+                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter, format_id);
     }
 
     arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter);
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 0385b8f4693..635a030e46b 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -411,6 +411,7 @@ struct wined3d_cs_blt_sub_resource
     DWORD flags;
     struct wined3d_blt_fx fx;
     enum wined3d_texture_filter_type filter;
+    enum wined3d_format_id format_id;
 };
 
 struct wined3d_cs_update_sub_resource
@@ -549,7 +550,7 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
 
         /* Blit the logo into the upper left corner of the back-buffer. */
         wined3d_texture_blt(back_buffer, 0, &rect, logo_texture, 0,
-                &rect, WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT);
+                &rect, WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
     }
 
     if ((cursor_texture = swapchain->device->cursor_texture)
@@ -574,7 +575,7 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
             MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&dst_rect, 2);
         if (wined3d_clip_blit(&clip_rect, &dst_rect, &src_rect))
             wined3d_texture_blt(back_buffer, 0, &dst_rect, cursor_texture, 0,
-                    &src_rect, WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT);
+                    &src_rect, WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
     }
 
     swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->swap_interval, op->flags);
@@ -2368,7 +2369,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
     {
         if (FAILED(texture2d_blt(texture_from_resource(op->dst_resource), op->dst_sub_resource_idx,
                 &op->dst_box, texture_from_resource(op->src_resource), op->src_sub_resource_idx,
-                &op->src_box, op->flags, &op->fx, op->filter)))
+                &op->src_box, op->flags, &op->fx, op->filter, op->format_id)))
             FIXME("Blit failed.\n");
     }
 
@@ -2381,7 +2382,7 @@ error:
 void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource,
         unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource,
         unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags,
-        const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
+        const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_cs_blt_sub_resource *op;
 
@@ -2399,6 +2400,7 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_reso
     else
         memset(&op->fx, 0, sizeof(op->fx));
     op->filter = filter;
+    op->format_id = format_id;
 
     wined3d_resource_acquire(dst_resource);
     if (src_resource)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 1fd5f4b012e..53922efc078 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4316,7 +4316,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
                 wined3d_cs_emit_blt_sub_resource(device->cs,
                         &dst_texture->resource, j * dst_level_count + i, &box,
                         &src_texture->resource, j * src_level_count + i + src_skip_levels, &box,
-                        0, NULL, WINED3D_TEXF_POINT);
+                        0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
             }
         }
     }
@@ -4362,7 +4362,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
                     wined3d_cs_emit_blt_sub_resource(device->cs,
                             &dst_texture->resource, i * dst_level_count + j, &box,
                             &src_texture->resource, i * src_level_count + src_level, &box,
-                            0, NULL, WINED3D_TEXF_POINT);
+                            0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
                 }
             }
         }
@@ -4594,7 +4594,7 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
     {
         wined3d_box_set(&src_box, 0, 0, src_resource->size, 1, 0, 1);
         wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, 0, &src_box,
-                src_resource, 0, &src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT);
+                src_resource, 0, &src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
         return;
     }
 
@@ -4619,7 +4619,7 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
             unsigned int idx = j * dst_texture->level_count + i;
 
             wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, idx, &dst_box,
-                    src_resource, idx, &src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT);
+                    src_resource, idx, &src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
         }
     }
 }
@@ -4780,7 +4780,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
     }
 
     wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box,
-            src_resource, src_sub_resource_idx, src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT);
+            src_resource, src_sub_resource_idx, src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
 
     return WINED3D_OK;
 }
@@ -4895,7 +4895,7 @@ void CDECL wined3d_device_resolve_sub_resource(struct wined3d_device *device,
     SetRect(&src_rect, 0, 0, wined3d_texture_get_level_width(src_texture, src_level),
             wined3d_texture_get_level_height(src_texture, src_level));
     wined3d_texture_blt(dst_texture, dst_sub_resource_idx, &dst_rect,
-            src_texture, src_sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
+            src_texture, src_sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT, format_id);
 }
 
 HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device,
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 45eebcc2c20..4567370f3fc 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -13061,7 +13061,7 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli
         struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
         DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
         unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
-        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter)
+        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture);
     struct wined3d_texture_gl *dst_texture_gl = wined3d_texture_gl(dst_texture);
@@ -13078,10 +13078,10 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli
     RECT s, d;
 
     TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, "
-            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n",
+            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s, format_id %s.\n",
             blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location),
             wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location),
-            wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter));
+            wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
 
     if (!glsl_blitter_supported(op, context, src_texture_gl, src_location, dst_texture_gl, dst_location))
     {
@@ -13093,7 +13093,7 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli
 
         TRACE("Forwarding to blitter %p.\n", next);
         return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
-                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter);
+                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id);
     }
 
     glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index d5d07d8c401..4b39c47cfe2 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1400,7 +1400,7 @@ static DWORD cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
         struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
         DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
         unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
-        const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
+        const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1};
     struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1};
@@ -1476,7 +1476,7 @@ static bool wined3d_is_colour_blit(enum wined3d_blit_op blit_op)
 HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
         const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
         const struct wined3d_box *src_box, DWORD flags, const struct wined3d_blt_fx *fx,
-        enum wined3d_texture_filter_type filter)
+        enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_texture_sub_resource *src_sub_resource, *dst_sub_resource;
     struct wined3d_device *device = dst_texture->resource.device;
@@ -1495,9 +1495,9 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
             | WINED3D_BLT_RAW;
 
     TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_box %s, src_texture %p, "
-            "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s.\n",
+            "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s, format_id %s.\n",
             dst_texture, dst_sub_resource_idx, debug_box(dst_box), src_texture, src_sub_resource_idx,
-            debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter));
+            debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
     TRACE("Usage is %s.\n", debug_d3dusage(dst_texture->resource.usage));
 
     if (fx)
@@ -1581,7 +1581,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
         context = context_acquire(device, dst_texture, dst_sub_resource_idx);
         valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context,
                 src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect,
-                dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, NULL, filter);
+                dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, NULL, filter, format_id);
         context_release(context);
 
         wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, valid_locations);
@@ -1715,7 +1715,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
 
     valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context,
             src_texture, src_sub_resource_idx, src_location, &src_rect,
-            dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, colour_key, filter);
+            dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, colour_key, filter, format_id);
 
     context_release(context);
 
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 72e17a6f833..39fac6c37fa 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -267,7 +267,7 @@ HRESULT CDECL wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapc
     }
 
     return wined3d_texture_blt(dst_texture, sub_resource_idx, &dst_rect,
-            swapchain->front_buffer, 0, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
+            swapchain->front_buffer, 0, &src_rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
 }
 
 struct wined3d_texture * CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
@@ -492,7 +492,7 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
 
     wined3d_texture_validate_location(texture, 0, WINED3D_LOCATION_DRAWABLE);
     device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, texture, 0,
-            location, src_rect, texture, 0, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter);
+            location, src_rect, texture, 0, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter, WINED3DFMT_UNKNOWN);
     wined3d_texture_invalidate_location(texture, 0, WINED3D_LOCATION_DRAWABLE);
 }
 
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index f4f929db2ca..1d763bbb369 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -320,9 +320,13 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont
         enum wined3d_texture_filter_type filter, struct wined3d_texture *src_texture,
         unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect,
         struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location,
-        const RECT *dst_rect)
+        const RECT *dst_rect, enum wined3d_format_id format_id)
 {
+    unsigned int dst_save_sub_resource_idx = dst_sub_resource_idx;
     struct wined3d_texture *required_texture, *restore_texture;
+    struct wined3d_texture *dst_save_texture = dst_texture;
+    struct wined3d_texture *src_staging_texture = NULL;
+    struct wined3d_texture *dst_staging_texture = NULL;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context_gl *context_gl;
     unsigned int restore_idx;
@@ -332,10 +336,10 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont
     RECT s, d;
 
     TRACE("device %p, context %p, filter %s, src_texture %p, src_sub_resource_idx %u, src_location %s, "
-            "src_rect %s, dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s.\n",
+            "src_rect %s, dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, format_id %s.\n",
             device, context, debug_d3dtexturefiltertype(filter), src_texture, src_sub_resource_idx,
             wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), dst_texture,
-            dst_sub_resource_idx, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect));
+            dst_sub_resource_idx, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect), debug_d3dformat(format_id));
 
     scaled_resolve = wined3d_texture_gl_is_multisample_location(wined3d_texture_gl(src_texture), src_location)
             && (abs(src_rect->bottom - src_rect->top) != abs(dst_rect->bottom - dst_rect->top)
@@ -346,6 +350,101 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont
     else
         gl_filter = scaled_resolve ? GL_SCALED_RESOLVE_FASTEST_EXT : GL_NEAREST;
 
+    context_gl = wined3d_context_gl(context);
+    if (!context_gl->valid)
+    {
+        context_release(context);
+        WARN("Invalid context, skipping blit.\n");
+        return;
+    }
+
+    gl_info = context_gl->gl_info;
+
+    switch (format_id)
+    {
+        case WINED3DFMT_R8G8B8A8_UNORM_SRGB:
+        case WINED3DFMT_B8G8R8A8_UNORM_SRGB:
+        case WINED3DFMT_B8G8R8X8_UNORM_SRGB:
+            gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
+            context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE));
+            break;
+        default:
+            break;
+    }
+
+    if (format_id != WINED3DFMT_UNKNOWN && src_texture->resource.format->id != format_id)
+    {
+        struct wined3d_texture_gl *src_staging_texture_gl = NULL;
+        struct wined3d_texture_gl *src_texture_gl = NULL;
+        struct wined3d_resource_desc desc;
+        unsigned src_level;
+        HRESULT hr;
+
+        src_level = src_sub_resource_idx % src_texture->level_count;
+        desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
+        desc.format = format_id;
+        desc.multisample_type = src_texture->resource.multisample_type;
+        desc.multisample_quality = src_texture->resource.multisample_quality;
+        desc.usage = WINED3DUSAGE_PRIVATE;
+        desc.bind_flags = 0;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU;
+        desc.width = wined3d_texture_get_level_width(src_texture, src_level);
+        desc.height = wined3d_texture_get_level_height(src_texture, src_level);
+        desc.depth = 1;
+        desc.size = 0;
+
+        hr = wined3d_texture_create(device, &desc, 1, 1, 0, NULL, NULL, &wined3d_null_parent_ops, &src_staging_texture);
+        if (FAILED(hr))
+        {
+            ERR("Failed to create staging texture, hr %#x.\n", hr);
+            return;
+        }
+
+        src_texture_gl = wined3d_texture_gl(src_texture);
+        src_staging_texture_gl = wined3d_texture_gl(src_staging_texture);
+
+        wined3d_texture_prepare_location(src_staging_texture, 0, context, WINED3D_LOCATION_TEXTURE_RGB);
+
+        GL_EXTCALL(glCopyImageSubData(wined3d_texture_gl_get_texture_name(src_texture_gl, context, false),
+                src_texture_gl->target, src_level, 0, 0, 0,
+                wined3d_texture_gl_get_texture_name(src_staging_texture_gl, context, false),
+                src_staging_texture_gl->target, 0, 0, 0, 0, desc.width, desc.height, 1));
+
+        checkGLcall("glCopyImageSubData()");
+        src_texture = src_staging_texture;
+        src_sub_resource_idx = 0;
+    }
+
+    if (format_id != WINED3DFMT_UNKNOWN && dst_texture->resource.format->id != format_id)
+    {
+        struct wined3d_resource_desc desc;
+        unsigned dst_level;
+        HRESULT hr;
+
+        dst_level = dst_sub_resource_idx % dst_texture->level_count;
+        desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
+        desc.format = format_id;
+        desc.multisample_type = dst_texture->resource.multisample_type;
+        desc.multisample_quality = dst_texture->resource.multisample_quality;
+        desc.usage = WINED3DUSAGE_PRIVATE;
+        desc.bind_flags = 0;
+        desc.access = WINED3D_RESOURCE_ACCESS_GPU;
+        desc.width = wined3d_texture_get_level_width(dst_texture, dst_level);
+        desc.height = wined3d_texture_get_level_height(dst_texture, dst_level);
+        desc.depth = 1;
+        desc.size = 0;
+
+        hr = wined3d_texture_create(device, &desc, 1, 1, 0, NULL, NULL, &wined3d_null_parent_ops, &dst_staging_texture);
+        if (FAILED(hr))
+        {
+            ERR("Failed to create staging texture, hr %#x.\n", hr);
+            return;
+        }
+
+        dst_texture = dst_staging_texture;
+        dst_sub_resource_idx = 0;
+    }
+
     /* Make sure the locations are up-to-date. Loading the destination
      * surface isn't required if the entire surface is overwritten. (And is
      * in fact harmful if we're being called by surface_load_location() with
@@ -374,16 +473,6 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont
     else
         restore_texture = NULL;
 
-    context_gl = wined3d_context_gl(context);
-    if (!context_gl->valid)
-    {
-        context_release(context);
-        WARN("Invalid context, skipping blit.\n");
-        return;
-    }
-
-    gl_info = context_gl->gl_info;
-
     if (src_location == WINED3D_LOCATION_DRAWABLE)
     {
         TRACE("Source texture %p is onscreen.\n", src_texture);
@@ -437,6 +526,27 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont
     if (dst_location == WINED3D_LOCATION_DRAWABLE && dst_texture->swapchain->front_buffer == dst_texture)
         gl_info->gl_ops.gl.p_glFlush();
 
+    if (dst_staging_texture)
+    {
+        struct wined3d_texture_gl *dst_texture_gl, *dst_save_texture_gl;
+        dst_texture_gl = wined3d_texture_gl(dst_texture);
+        dst_save_texture_gl = wined3d_texture_gl(dst_save_texture);
+
+        wined3d_texture_prepare_location(dst_save_texture, 0, context, WINED3D_LOCATION_TEXTURE_RGB);
+
+        GL_EXTCALL(glCopyImageSubData(wined3d_texture_gl_get_texture_name(dst_texture_gl, context, false),
+                dst_texture_gl->target, 0, 0, 0, 0,
+                wined3d_texture_gl_get_texture_name(dst_save_texture_gl, context, false),
+                dst_save_texture_gl->target, dst_save_sub_resource_idx % dst_texture->level_count, 0, 0, 0,
+                dst_texture->resource.width, dst_texture->resource.height, 1));
+
+        checkGLcall("glCopyImageSubData()");
+        wined3d_texture_decref(dst_texture);
+    }
+
+    if (src_staging_texture)
+        wined3d_texture_decref(src_staging_texture);
+
     if (restore_texture)
         context_restore(context, restore_texture, restore_idx);
 }
@@ -682,8 +792,8 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture,
     {
         DWORD required_access = wined3d_resource_access_from_location(location);
         if ((texture->resource.access & required_access) != required_access)
-            WARN("Operation requires %#x access, but texture only has %#x.\n",
-                    required_access, texture->resource.access);
+            WARN("Operation requires %#x access, but texture only has %#x, location %s, current %s.\n",
+                    required_access, texture->resource.access, wined3d_debug_location(location), wined3d_debug_location(current));
     }
 
     if (current & WINED3D_LOCATION_DISCARDED)
@@ -2933,7 +3043,7 @@ static BOOL wined3d_texture_load_drawable(struct wined3d_texture *texture,
     device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context,
             texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &r,
             texture, sub_resource_idx, WINED3D_LOCATION_DRAWABLE, &r,
-            NULL, WINED3D_TEXF_POINT);
+            NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
 
     return TRUE;
 }
@@ -2971,7 +3081,7 @@ static BOOL wined3d_texture_load_renderbuffer(struct wined3d_texture *texture,
         src_location = WINED3D_LOCATION_TEXTURE_RGB;
 
     texture2d_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT, texture,
-            sub_resource_idx, src_location, &rect, texture, sub_resource_idx, dst_location, &rect);
+            sub_resource_idx, src_location, &rect, texture, sub_resource_idx, dst_location, &rect, WINED3DFMT_UNKNOWN);
 
     return TRUE;
 }
@@ -3018,11 +3128,11 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g
         if (srgb)
             texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT,
                     &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect,
-                    &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect);
+                    &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect, WINED3DFMT_UNKNOWN);
         else
             texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT,
                     &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect,
-                    &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect);
+                    &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect, WINED3DFMT_UNKNOWN);
 
         return TRUE;
     }
@@ -3039,7 +3149,7 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g
         if (fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info,
                 &texture_gl->t.resource, src_location, &texture_gl->t.resource, dst_location))
             texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT, &texture_gl->t, sub_resource_idx,
-                    src_location, &src_rect, &texture_gl->t, sub_resource_idx, dst_location, &src_rect);
+                    src_location, &src_rect, &texture_gl->t, sub_resource_idx, dst_location, &src_rect, WINED3DFMT_UNKNOWN);
 
         return TRUE;
     }
@@ -3849,16 +3959,18 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
 
 HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
         const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
-        const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
+        const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter,
+        enum wined3d_format_id format_id)
 {
     struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1};
     struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1};
     HRESULT hr;
 
     TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, "
-            "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n",
+            "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s, format_id %s.\n",
             dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture,
-            src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter));
+            src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter),
+            debug_d3dformat(format_id));
 
     if (dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count
             || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
@@ -3901,7 +4013,7 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned
     }
 
     wined3d_cs_emit_blt_sub_resource(dst_texture->resource.device->cs, &dst_texture->resource, dst_sub_resource_idx,
-            &dst_box, &src_texture->resource, src_sub_resource_idx, &src_box, flags, fx, filter);
+            &dst_box, &src_texture->resource, src_sub_resource_idx, &src_box, flags, fx, filter, format_id);
 
     return WINED3D_OK;
 }
@@ -5655,7 +5767,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
         struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
         DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
         unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
-        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter)
+        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture);
     struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
@@ -5676,7 +5788,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
     {
         if ((next = blitter->next))
             return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
-                    src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter);
+                    src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id);
     }
 
     TRACE("Blt from texture %p, %u to rendertarget %p, %u.\n",
@@ -5864,7 +5976,7 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
         struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
         DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
         unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
-        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter)
+        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
     struct wined3d_resource *src_resource, *dst_resource;
@@ -5873,10 +5985,10 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
     struct wined3d_blitter *next;
 
     TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, "
-            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n",
+            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s, format_id %s.\n",
             blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location),
             wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location),
-            wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter));
+            wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
 
     src_resource = &src_texture->resource;
     dst_resource = &dst_texture->resource;
@@ -5902,14 +6014,14 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
 
         TRACE("Forwarding to blitter %p.\n", next);
         return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
-                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter);
+                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id);
     }
 
     if (blit_op == WINED3D_BLIT_OP_COLOR_BLIT)
     {
         TRACE("Colour blit.\n");
         texture2d_blt_fbo(device, context, filter, src_texture, src_sub_resource_idx, src_location,
-                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect);
+                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, format_id);
         return dst_location;
     }
 
@@ -5980,7 +6092,7 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
         struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
         DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
         unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
-        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter)
+        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture);
     struct wined3d_texture_gl *dst_texture_gl = wined3d_texture_gl(dst_texture);
@@ -6007,7 +6119,7 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
 
         TRACE("Forwarding to blitter %p.\n", next);
         return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
-                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter);
+                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id);
     }
 
     TRACE("Blit using ARB_copy_image.\n");
@@ -6381,7 +6493,7 @@ static void vk_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_dev
 
 static bool vk_blitter_blit_supported(enum wined3d_blit_op op, const struct wined3d_context *context,
         const struct wined3d_resource *src_resource, const RECT *src_rect,
-        const struct wined3d_resource *dst_resource, const RECT *dst_rect)
+        const struct wined3d_resource *dst_resource, const RECT *dst_rect, enum wined3d_format_id format_id)
 {
     const struct wined3d_format *src_format = src_resource->format;
     const struct wined3d_format *dst_format = dst_resource->format;
@@ -6413,7 +6525,9 @@ static bool vk_blitter_blit_supported(enum wined3d_blit_op op, const struct wine
         }
 
         if (op != WINED3D_BLIT_OP_RAW_BLIT
-                && wined3d_format_vk(src_format)->vk_format != wined3d_format_vk(dst_format)->vk_format)
+                && wined3d_format_vk(src_format)->vk_format != wined3d_format_vk(dst_format)->vk_format
+                && ((!wined3d_format_is_typeless(src_format) && !wined3d_format_is_typeless(dst_format))
+                        || (format_id == WINED3DFMT_UNKNOWN)))
         {
             TRACE("Format conversion not supported.\n");
             return false;
@@ -6445,11 +6559,78 @@ static bool vk_blitter_blit_supported(enum wined3d_blit_op op, const struct wine
     return true;
 }
 
+static VkResult create_staging_image_for_resolve(struct wined3d_context_vk *context_vk,
+        VkImageType vk_image_type, VkFormat vk_format, unsigned width, unsigned height, unsigned depth,
+        unsigned sample_count, VkImage *image)
+{
+    struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(context_vk->c.device->adapter);
+    struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+    const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+    VkMemoryAllocateInfo allocate_info = {0};
+    VkMemoryRequirements memory_requirements;
+    VkImageCreateInfo create_info;
+    VkDeviceMemory device_memory;
+    VkResult vr;
+
+    create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    create_info.pNext = NULL;
+    create_info.flags = 0;
+    create_info.imageType = vk_image_type;
+    create_info.format = vk_format;
+    create_info.extent.width = width;
+    create_info.extent.height = height;
+    create_info.extent.depth = depth;
+    create_info.mipLevels = 1;
+    create_info.arrayLayers = 1;
+    create_info.samples = sample_count;
+    create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+    create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+            | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+            | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+    create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    create_info.queueFamilyIndexCount = 0;
+    create_info.pQueueFamilyIndices = NULL;
+    create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+    vr = VK_CALL(vkCreateImage(device_vk->vk_device, &create_info, NULL, image));
+    if (vr != VK_SUCCESS)
+    {
+        ERR("Failed to create image, vr %#x.\n", vr);
+        return vr;
+    }
+
+    wined3d_context_vk_destroy_image(context_vk, *image, context_vk->current_command_buffer.id);
+
+    VK_CALL(vkGetImageMemoryRequirements(device_vk->vk_device, *image, &memory_requirements));
+
+    allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    allocate_info.allocationSize = memory_requirements.size;
+    allocate_info.memoryTypeIndex = wined3d_adapter_vk_get_memory_type_index(adapter_vk, ~0, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+    vr = VK_CALL(vkAllocateMemory(device_vk->vk_device, &allocate_info, NULL, &device_memory));
+    if (vr != VK_SUCCESS)
+    {
+        ERR("Failed to allocate memory, vr %#x.\n", vr);
+        return vr;
+    }
+
+    wined3d_context_vk_destroy_memory(context_vk, device_memory, context_vk->current_command_buffer.id);
+
+    vr = VK_CALL(vkBindImageMemory(device_vk->vk_device, *image, device_memory, 0));
+    if (vr != VK_SUCCESS)
+    {
+        ERR("Failed to bind image memory, vr %#x.\n", vr);
+        return vr;
+    }
+
+    return VK_SUCCESS;
+}
+
 static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
         struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
         DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
         unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
-        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter)
+        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id)
 {
     struct wined3d_texture_vk *src_texture_vk = wined3d_texture_vk(src_texture);
     struct wined3d_texture_vk *dst_texture_vk = wined3d_texture_vk(dst_texture);
@@ -6459,21 +6640,23 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_
     VkImageAspectFlags src_aspect, dst_aspect;
     VkCommandBuffer vk_command_buffer;
     struct wined3d_blitter *next;
+    unsigned src_sample_count;
     bool resolve = false;
 
     TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, "
-            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n",
+            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s, format_id %s.\n",
             blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location),
             wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location),
-            wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter));
+            wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
 
-    if (!vk_blitter_blit_supported(op, context, &src_texture->resource, src_rect, &dst_texture->resource, dst_rect))
+    if (!vk_blitter_blit_supported(op, context, &src_texture->resource, src_rect, &dst_texture->resource, dst_rect, format_id))
         goto next;
 
     src_aspect = vk_aspect_mask_from_format(src_texture_vk->t.resource.format);
     dst_aspect = vk_aspect_mask_from_format(dst_texture_vk->t.resource.format);
 
-    if (wined3d_resource_get_sample_count(&src_texture_vk->t.resource) > 1)
+    src_sample_count = wined3d_resource_get_sample_count(&src_texture_vk->t.resource);
+    if (src_sample_count > 1)
         resolve = true;
 
     src_level = src_sub_resource_idx % src_texture->level_count;
@@ -6523,7 +6706,180 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_
             dst_texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
             dst_texture_vk->vk_image, dst_aspect);
 
-    if (resolve)
+
+    if (resolve && format_id != WINED3DFMT_UNKNOWN
+            && (src_texture->resource.format->id != format_id || dst_texture->resource.format->id != format_id))
+    {
+        const struct wined3d_format_vk *src_format_vk = wined3d_format_vk(src_texture->resource.format);
+        const struct wined3d_format_vk *dst_format_vk = wined3d_format_vk(dst_texture->resource.format);
+        VkImage src_vk_image, dst_vk_image;
+        VkImageResolve resolve_region;
+        VkImageType vk_image_type;
+        VkImageCopy copy_region;
+        VkFormat vk_format;
+        VkResult vr;
+
+        TRACE("Doing typeless resolve %s to %s (via %s)\n", debug_d3dformat(src_texture->resource.format->id),
+                debug_d3dformat(dst_texture->resource.format->id), debug_d3dformat(format_id));
+
+        if (!wined3d_format_is_typeless(&src_format_vk->f))
+        {
+            vk_format = src_format_vk->vk_format;
+        }
+        else if (!wined3d_format_is_typeless(&dst_format_vk->f))
+        {
+            vk_format = dst_format_vk->vk_format;
+        }
+        else
+        {
+            vk_format = wined3d_format_vk(wined3d_get_format(context->device->adapter, format_id, 0))->vk_format;
+        }
+
+        switch (src_texture->resource.type)
+        {
+            case WINED3D_RTYPE_TEXTURE_1D:
+                vk_image_type = VK_IMAGE_TYPE_1D;
+                break;
+            case WINED3D_RTYPE_TEXTURE_2D:
+                vk_image_type = VK_IMAGE_TYPE_2D;
+                break;
+            case WINED3D_RTYPE_TEXTURE_3D:
+                vk_image_type = VK_IMAGE_TYPE_3D;
+                break;
+            default:
+                ERR("Unexpected resource type: %s\n", debug_d3dresourcetype(src_texture->resource.type));
+                goto next;
+        }
+
+        resolve_region.dstSubresource.aspectMask = dst_aspect;
+        resolve_region.extent.width = src_rect->right - src_rect->left;
+        resolve_region.extent.height = src_rect->bottom - src_rect->top;
+        resolve_region.extent.depth = 1;
+
+        if (src_texture->resource.format->id != format_id)
+        {
+            vr = create_staging_image_for_resolve(context_vk, vk_image_type, vk_format,
+                    resolve_region.extent.width, resolve_region.extent.height, 1, src_sample_count, &src_vk_image);
+            if (vr != VK_SUCCESS)
+                goto next;
+
+            wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
+                    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                    0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, src_vk_image, src_aspect);
+
+            copy_region.srcSubresource.aspectMask = src_aspect;
+            copy_region.srcSubresource.mipLevel = src_level;
+            copy_region.srcSubresource.baseArrayLayer = src_layer;
+            copy_region.srcSubresource.layerCount = 1;
+            copy_region.srcOffset.x = src_rect->left;
+            copy_region.srcOffset.y = src_rect->top;
+            copy_region.srcOffset.z = 0;
+            copy_region.dstSubresource.aspectMask = src_aspect;
+            copy_region.dstSubresource.mipLevel = 0;
+            copy_region.dstSubresource.baseArrayLayer = 0;
+            copy_region.dstSubresource.layerCount = 1;
+            copy_region.dstOffset.x = 0;
+            copy_region.dstOffset.y = 0;
+            copy_region.dstOffset.z = 0;
+            copy_region.extent.width = resolve_region.extent.width;
+            copy_region.extent.height = resolve_region.extent.height;
+            copy_region.extent.depth = 1;
+
+            VK_CALL(vkCmdCopyImage(vk_command_buffer, src_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                    src_vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region));
+
+            wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
+                    VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                    VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                    src_vk_image, src_aspect);
+
+            resolve_region.srcSubresource.aspectMask = src_aspect;
+            resolve_region.srcSubresource.mipLevel = 0;
+            resolve_region.srcSubresource.baseArrayLayer = 0;
+            resolve_region.srcSubresource.layerCount = 1;
+            resolve_region.srcOffset.x = 0;
+            resolve_region.srcOffset.y = 0;
+            resolve_region.srcOffset.z = 0;
+        }
+        else
+        {
+            src_vk_image = src_texture_vk->vk_image;
+
+            resolve_region.srcSubresource.aspectMask = src_aspect;
+            resolve_region.srcSubresource.mipLevel = src_level;
+            resolve_region.srcSubresource.baseArrayLayer = src_layer;
+            resolve_region.srcSubresource.layerCount = 1;
+            resolve_region.srcOffset.x = src_rect->left;
+            resolve_region.srcOffset.y = src_rect->top;
+            resolve_region.srcOffset.z = 0;
+        }
+
+        if (dst_texture->resource.format->id != format_id)
+        {
+            vr = create_staging_image_for_resolve(context_vk, vk_image_type, vk_format,
+                    resolve_region.extent.width, resolve_region.extent.height, 1, VK_SAMPLE_COUNT_1_BIT, &dst_vk_image);
+            if (vr != VK_SUCCESS)
+                goto next;
+
+            wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
+                    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT,
+                    VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_vk_image, dst_aspect);
+
+            resolve_region.dstSubresource.mipLevel = 0;
+            resolve_region.dstSubresource.baseArrayLayer = 0;
+            resolve_region.dstSubresource.layerCount = 1;
+            resolve_region.dstOffset.x = 0;
+            resolve_region.dstOffset.y = 0;
+            resolve_region.dstOffset.z = 0;
+        }
+        else
+        {
+            dst_vk_image = dst_texture_vk->vk_image;
+
+            resolve_region.dstSubresource.mipLevel = dst_level;
+            resolve_region.dstSubresource.baseArrayLayer = dst_layer;
+            resolve_region.dstSubresource.layerCount = 1;
+            resolve_region.dstOffset.x = dst_rect->left;
+            resolve_region.dstOffset.y = dst_rect->top;
+            resolve_region.dstOffset.z = 0;
+        }
+
+        VK_CALL(vkCmdResolveImage(vk_command_buffer, src_vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                dst_vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region));
+
+        if (dst_vk_image != dst_texture_vk->vk_image)
+        {
+            wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
+                    VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                    VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                    dst_vk_image, dst_aspect);
+
+            copy_region.srcSubresource.aspectMask = dst_aspect;
+            copy_region.srcSubresource.mipLevel = 0;
+            copy_region.srcSubresource.baseArrayLayer = 0;
+            copy_region.srcSubresource.layerCount = 1;
+            copy_region.srcOffset.x = 0;
+            copy_region.srcOffset.y = 0;
+            copy_region.srcOffset.z = 0;
+            copy_region.dstSubresource.aspectMask = dst_aspect;
+            copy_region.dstSubresource.mipLevel = dst_level;
+            copy_region.dstSubresource.baseArrayLayer = dst_layer;
+            copy_region.dstSubresource.layerCount = 1;
+            copy_region.dstOffset.x = dst_rect->left;
+            copy_region.dstOffset.y = dst_rect->top;
+            copy_region.dstOffset.z = 0;
+            copy_region.extent.width = resolve_region.extent.width;
+            copy_region.extent.height = resolve_region.extent.height;
+            copy_region.extent.depth = 1;
+
+            VK_CALL(vkCmdCopyImage(vk_command_buffer, dst_vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                    dst_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region));
+        }
+    }
+    else if (resolve)
     {
         VkImageResolve region;
 
@@ -6606,7 +6962,7 @@ next:
 
     TRACE("Forwarding to blitter %p.\n", next);
     return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
-            src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter);
+            src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id);
 }
 
 static const struct wined3d_blitter_ops vk_blitter_ops =
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2a75ab5d43d..b141918cefa 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2756,7 +2756,7 @@ struct wined3d_blitter_ops
             struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location,
             const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
             DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *colour_key,
-            enum wined3d_texture_filter_type filter);
+            enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id);
 };
 
 void wined3d_arbfp_blitter_create(struct wined3d_blitter **next,
@@ -4320,7 +4320,7 @@ static inline bool wined3d_texture_is_full_rect(const struct wined3d_texture *te
 HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
         const struct wined3d_box *dst_box, struct wined3d_texture *src_texture,
         unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags,
-        const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
+        const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) DECLSPEC_HIDDEN;
 void texture2d_get_blt_info(const struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx,
         const RECT *rect, struct wined3d_blt_info *info) DECLSPEC_HIDDEN;
 void texture2d_load_fb_texture(struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx,
@@ -4710,7 +4710,7 @@ void wined3d_cs_emit_add_dirty_texture_region(struct wined3d_cs *cs,
 void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource,
         unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource,
         unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags,
-        const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
+        const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects,
         DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view,
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 96cb6fc1d86..e47f823ea13 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2830,7 +2830,7 @@ HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture
         UINT layer, const struct wined3d_box *dirty_region);
 HRESULT __cdecl wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_idx, const RECT *dst_rect_in,
         struct wined3d_texture *src_texture, unsigned int src_idx, const RECT *src_rect_in, DWORD flags,
-        const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter);
+        const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter, enum wined3d_format_id);
 HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
         UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
-- 
2.30.0




More information about the wine-devel mailing list