Commit d0fdb1ea authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

d3d: Add a test for double surface locking.

parent b53e1ffa
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment