Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/d3dx9_36/surface.c | 53 +++++++++++++++++++++++++++++++++----------
dlls/d3dx9_36/tests/surface.c | 1 -
2 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index a44398cf9e5..7d48cc6b132 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -1753,9 +1753,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
DWORD filter, D3DCOLOR color_key)
{
const struct pixel_format_desc *srcformatdesc, *destformatdesc;
+ IDirect3DSurface9 *surface = dst_surface;
+ IDirect3DDevice9 *device;
D3DSURFACE_DESC surfdesc;
D3DLOCKED_RECT lockrect;
struct volume src_size, dst_size;
+ HRESULT hr;
TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s, %#x, 0x%08x)\n",
dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_memory, src_format,
@@ -1811,6 +1814,26 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
return E_NOTIMPL;
}
+ if (surfdesc.Pool == D3DPOOL_DEFAULT && !(surfdesc.Usage & D3DUSAGE_DYNAMIC))
+ {
+ IDirect3DSurface9_GetDevice(dst_surface, &device);
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, surfdesc.Width,
+ surfdesc.Height, surfdesc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
+ IDirect3DDevice9_Release(device);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create staging surface, hr %#x.\n", hr);
+ return D3DERR_INVALIDCALL;
+ }
+ }
+
+ if (FAILED(IDirect3DSurface9_LockRect(surface, &lockrect, dst_rect, 0)))
+ {
+ if (surface != dst_surface)
+ IDirect3DSurface9_Release(surface);
+ return D3DXERR_INVALIDDATA;
+ }
+
if (src_format == surfdesc.Format
&& dst_size.width == src_size.width
&& dst_size.height == src_size.height
@@ -1824,16 +1847,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
&& src_size.height != surfdesc.Height))
{
WARN("Source rect %s is misaligned.\n", wine_dbgstr_rect(src_rect));
- return D3DXERR_INVALIDDATA;
+ hr = D3DXERR_INVALIDDATA;
+ goto done;
}
- if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0)))
- return D3DXERR_INVALIDDATA;
-
copy_pixels(src_memory, src_pitch, 0, lockrect.pBits, lockrect.Pitch, 0,
&src_size, srcformatdesc);
-
- IDirect3DSurface9_UnlockRect(dst_surface);
}
else /* Stretching or format conversion. */
{
@@ -1841,12 +1860,10 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
|| !is_conversion_to_supported(destformatdesc))
{
FIXME("Unsupported format conversion %#x -> %#x.\n", src_format, surfdesc.Format);
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto done;
}
- if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0)))
- return D3DXERR_INVALIDDATA;
-
if ((filter & 0xf) == D3DX_FILTER_NONE)
{
convert_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc,
@@ -1862,11 +1879,23 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
point_filter_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc,
lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key, src_palette);
}
+ }
- IDirect3DSurface9_UnlockRect(dst_surface);
+ hr = D3D_OK;
+done:
+ IDirect3DSurface9_UnlockRect(surface);
+ if (surface != dst_surface)
+ {
+ if (SUCCEEDED(hr))
+ {
+ IDirect3DSurface9_GetDevice(dst_surface, &device);
+ hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, dst_surface, NULL);
+ IDirect3DDevice9_Release(device);
+ }
+ IDirect3DSurface9_Release(surface);
}
- return D3D_OK;
+ return hr;
}
/************************************************************
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index 469c864f308..f153cd92c65 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -867,7 +867,6 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget returned %#x, expected %#x.\n", hr, D3D_OK);
hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
- todo_wine
ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK);
hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
todo_wine
--
2.11.0