From d0fdb1ea7e9f952e5a60851518db511f32c0a7a9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Fri, 24 Aug 2007 23:51:14 +0200 Subject: [PATCH] d3d: Add a test for double surface locking. --- dlls/d3d8/tests/surface.c | 22 ++++++++++++++++++++++ dlls/d3d9/tests/surface.c | 23 +++++++++++++++++++++++ dlls/ddraw/surface.c | 12 +++++++++++- dlls/ddraw/tests/dsurface.c | 27 +++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/dlls/d3d8/tests/surface.c b/dlls/d3d8/tests/surface.c index 71dce2f70d2..2225960ec99 100644 --- a/dlls/d3d8/tests/surface.c +++ b/dlls/d3d8/tests/surface.c @@ -192,6 +192,28 @@ static void test_lockrect_invalid(IDirect3DDevice8 *device) rect->right, rect->bottom, D3DERR_INVALIDCALL); } + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "LockRect failed (0x%08x) for rect NULL\n", hr); + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Double LockRect returned 0x%08x for rect NULL\n", hr); + hr = IDirect3DSurface8_UnlockRect(surface); + ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr); + + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[0], 0); + ok(hr == D3D_OK, "LockRect failed (0x%08x) for rect [%d, %d]->[%d, %d]" + ", expected D3D_OK (0x%08x)\n", hr, valid[0].left, valid[0].top, + valid[0].right, valid[0].bottom, D3D_OK); + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[0], 0); + ok(hr == D3DERR_INVALIDCALL, "Double LockRect failed (0x%08x) for rect [%d, %d]->[%d, %d]" + ", expected D3DERR_INVALIDCALL (0x%08x)\n", hr, valid[0].left, valid[0].top, + valid[0].right, valid[0].bottom,D3DERR_INVALIDCALL); + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[1], 0); + ok(hr == D3DERR_INVALIDCALL, "Double LockRect failed (0x%08x) for rect [%d, %d]->[%d, %d]" + ", expected D3DERR_INVALIDCALL (0x%08x)\n", hr, valid[1].left, valid[1].top, + valid[1].right, valid[1].bottom, D3DERR_INVALIDCALL); + hr = IDirect3DSurface8_UnlockRect(surface); + ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr); + IDirect3DSurface8_Release(surface); } diff --git a/dlls/d3d9/tests/surface.c b/dlls/d3d9/tests/surface.c index c84e9332bd0..a7fef001e2e 100644 --- a/dlls/d3d9/tests/surface.c +++ b/dlls/d3d9/tests/surface.c @@ -238,6 +238,7 @@ static void test_lockrect_invalid(IDirect3DDevice9 *device) BYTE *base; HRESULT hr; + const RECT test_rect_2 = { 0, 0, 8, 8 }; const RECT test_data[] = { {60, 60, 68, 68}, /* Valid */ {60, 60, 60, 68}, /* 0 height */ @@ -286,6 +287,28 @@ static void test_lockrect_invalid(IDirect3DDevice9 *device) ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr); } + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "LockRect failed (0x%08x) for rect NULL\n", hr); + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Double LockRect for rect NULL returned 0x%08x\n", hr); + hr = IDirect3DSurface9_UnlockRect(surface); + ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr); + + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0], 0); + ok(hr == D3D_OK, "LockRect failed (0x%08x) for rect [%d, %d]->[%d, %d]" + ", expected D3D_OK (0x%08x)\n", hr, test_data[0].left, test_data[0].top, + test_data[0].right, test_data[0].bottom, D3D_OK); + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0], 0); + ok(hr == D3DERR_INVALIDCALL, "Double LockRect failed (0x%08x) for rect [%d, %d]->[%d, %d]" + ", expected D3DERR_INVALIDCALL (0x%08x)\n", hr, test_data[0].left, test_data[0].top, + test_data[0].right, test_data[0].bottom, D3DERR_INVALIDCALL); + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0); + ok(hr == D3DERR_INVALIDCALL, "Double LockRect failed (0x%08x) for rect [%d, %d]->[%d, %d]" + ", expected D3DERR_INVALIDCALL (0x%08x)\n", hr, test_rect_2.left, test_rect_2.top, + test_rect_2.right, test_rect_2.bottom, D3DERR_INVALIDCALL); + hr = IDirect3DSurface9_UnlockRect(surface); + ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr); + IDirect3DSurface9_Release(surface); } diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 5dc823e3fe6..a5a0b2141ba 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -613,7 +613,17 @@ IDirectDrawSurfaceImpl_Lock(IDirectDrawSurface7 *iface, if(hr != D3D_OK) { LeaveCriticalSection(&ddraw_cs); - return hr; + switch(hr) + { + /* D3D8 and D3D9 return the general D3DERR_INVALIDCALL error, but ddraw has a more + * specific error. But since IWineD3DSurface::LockRect returns that error in this + * only occasion, keep d3d8 and d3d9 free from the return value override. There are + * many different places where d3d8/9 would have to catch the DDERR_SURFACEBUSY, it + * is much easier to do it in one place in ddraw + */ + case WINED3DERR_INVALIDCALL: return DDERR_SURFACEBUSY; + default: return hr; + } } /* Override the memory area. The pitch should be set already. Strangely windows diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c index b2cd033059c..6c223f4e854 100644 --- a/dlls/ddraw/tests/dsurface.c +++ b/dlls/ddraw/tests/dsurface.c @@ -1630,6 +1630,33 @@ static void test_lockrect_invalid(void) rect->right, rect->bottom, DDERR_INVALIDPARAMS); } + hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL); + ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr); + hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr); + if(SUCCEEDED(hr)) { + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr); + } + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr); + + memset(&locked_desc, 0, sizeof(locked_desc)); + locked_desc.dwSize = sizeof(locked_desc); + hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL); + ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + + /* Locking a different rectangle returns DD_OK, but it seems to break the surface. + * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles + */ + + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr); + IDirectDrawSurface_Release(surface); } } -- 2.11.4.GIT