Stefan Dösinger : d3d: Add a test for double surface locking.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Aug 31 07:22:17 CDT 2007
Module: wine
Branch: master
Commit: d0fdb1ea7e9f952e5a60851518db511f32c0a7a9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d0fdb1ea7e9f952e5a60851518db511f32c0a7a9
Author: Stefan Dösinger <stefandoesinger at gmx.at>
Date: Fri Aug 24 23:51:14 2007 +0200
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 deletions(-)
diff --git a/dlls/d3d8/tests/surface.c b/dlls/d3d8/tests/surface.c
index 71dce2f..2225960 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 c84e933..a7fef00 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 5dc823e..a5a0b21 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 b2cd033..6c223f4 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);
}
}
More information about the wine-cvs
mailing list