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