Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- This supersedes patch 154371.
v2: Avoid leaking the surface on the StretchRect() error path. Only bother creating an intermediate surface if mapping the source surface actually failed.
--- dlls/d3dx9_36/surface.c | 43 +++++++++++++++++++++++++++++++------------ dlls/d3dx9_36/tests/surface.c | 4 ---- 2 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 7d48cc6b132..3cf8c60d6ab 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -1924,10 +1924,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface, const PALETTEENTRY *dst_palette, const RECT *dst_rect, IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect, DWORD filter, D3DCOLOR color_key) { - RECT rect; + IDirect3DSurface9 *surface = src_surface; + IDirect3DDevice9 *device; + D3DSURFACE_DESC src_desc; D3DLOCKED_RECT lock; - D3DSURFACE_DESC SrcDesc; HRESULT hr; + RECT s;
TRACE("dst_surface %p, dst_palette %p, dst_rect %s, src_surface %p, " "src_palette %p, src_rect %s, filter %#x, color_key 0x%08x.\n", @@ -1937,23 +1939,40 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface, if (!dst_surface || !src_surface) return D3DERR_INVALIDCALL;
- IDirect3DSurface9_GetDesc(src_surface, &SrcDesc); + IDirect3DSurface9_GetDesc(src_surface, &src_desc);
if (!src_rect) - SetRect(&rect, 0, 0, SrcDesc.Width, SrcDesc.Height); - else - rect = *src_rect; + { + SetRect(&s, 0, 0, src_desc.Width, src_desc.Height); + src_rect = &s; + }
- if (FAILED(IDirect3DSurface9_LockRect(src_surface, &lock, NULL, D3DLOCK_READONLY))) + if (FAILED(IDirect3DSurface9_LockRect(surface, &lock, NULL, D3DLOCK_READONLY))) { - FIXME("Called for unlockable source surface.\n"); - return D3DXERR_INVALIDDATA; + IDirect3DSurface9_GetDevice(src_surface, &device); + if (FAILED(IDirect3DDevice9_CreateRenderTarget(device, src_desc.Width, src_desc.Height, + src_desc.Format, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL))) + { + IDirect3DDevice9_Release(device); + return D3DXERR_INVALIDDATA; + } + + if (SUCCEEDED(hr = IDirect3DDevice9_StretchRect(device, src_surface, NULL, surface, NULL, D3DTEXF_NONE))) + hr = IDirect3DSurface9_LockRect(surface, &lock, NULL, D3DLOCK_READONLY); + IDirect3DDevice9_Release(device); + if (FAILED(hr)) + { + IDirect3DSurface9_Release(surface); + return D3DXERR_INVALIDDATA; + } }
- hr = D3DXLoadSurfaceFromMemory(dst_surface, dst_palette, dst_rect, - lock.pBits, SrcDesc.Format, lock.Pitch, src_palette, &rect, filter, color_key); + hr = D3DXLoadSurfaceFromMemory(dst_surface, dst_palette, dst_rect, lock.pBits, + src_desc.Format, lock.Pitch, src_palette, src_rect, filter, color_key);
- IDirect3DSurface9_UnlockRect(src_surface); + IDirect3DSurface9_UnlockRect(surface); + if (surface != src_surface) + IDirect3DSurface9_Release(surface);
return hr; } diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index f153cd92c65..d3450722ef7 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -869,16 +869,12 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0); 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 ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK); hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0xff000000); - 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_TRIANGLE | D3DX_FILTER_MIRROR, 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_LINEAR, 0); - todo_wine ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK);
IDirect3DSurface9_Release(newsurf);
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=44653
Your paranoid android.
=== debian9 (build log) ===
X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 140 (RANDR) Minor opcode of failed request: 21 (RRSetCrtcConfig) X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 140 (RANDR) Minor opcode of failed request: 21 (RRSetCrtcConfig) X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 140 (RANDR) Minor opcode of failed request: 21 (RRSetCrtcConfig)
=== debian9 (build log) ===
X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 140 (RANDR) Minor opcode of failed request: 21 (RRSetCrtcConfig) X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 140 (RANDR) Minor opcode of failed request: 21 (RRSetCrtcConfig) X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 140 (RANDR) Minor opcode of failed request: 21 (RRSetCrtcConfig)