diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 5777fd50a59..b528e2cc9f3 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -944,12 +944,26 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(IDirect3DDevice8 *iface, wined3d_mutex_lock(); wined3d_resource = wined3d_surface_get_resource(Source->wined3d_surface); wined3d_resource_get_desc(wined3d_resource, &wined3d_desc); + if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) + { + WARN("Source %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", + pSourceSurface); + wined3d_mutex_unlock(); + return D3DERR_INVALIDCALL; + } srcFormat = wined3d_desc.format; src_w = wined3d_desc.width; src_h = wined3d_desc.height; wined3d_resource = wined3d_surface_get_resource(Dest->wined3d_surface); wined3d_resource_get_desc(wined3d_resource, &wined3d_desc); + if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) + { + WARN("Dest %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", + pDestinationSurface); + wined3d_mutex_unlock(); + return D3DERR_INVALIDCALL; + } destFormat = wined3d_desc.format; /* Check that the source and destination formats match */ diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index cfac2cd0747..2e1bc985e9e 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -3091,6 +3091,78 @@ done: UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL)); } +static void depth_blit_test(void) +{ + HWND hwnd = NULL; + IDirect3D8 *d3d8 = NULL; + IDirect3DDevice8 *device = NULL; + IDirect3DSurface8 *backbuffer, *ds1, *ds2, *ds3; + RECT src_rect; + const POINT dst_point = {0, 0}; + HRESULT hr; + + d3d8 = pDirect3DCreate8(D3D_SDK_VERSION); + ok(d3d8 != NULL, "Direct3DCreate8 failed.\n"); + hwnd = CreateWindow("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindow failed.\n"); + if (!d3d8 || !hwnd) + goto done; + + device = create_device(d3d8, hwnd, hwnd, TRUE); + if (!device) + { + skip("Failed to create a D3D device, skipping tests.\n"); + goto done; + } + + hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer); + ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr); + hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds1); + ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr); + hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, &ds2); + ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr); + hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, &ds3); + ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr); + + hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0); + ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr); + + /* Partial blit. */ + SetRect(&src_rect, 0, 0, 320, 240); + hr = IDirect3DDevice8_CopyRects(device, ds1, &src_rect, 1, ds2, &dst_point); + ok(hr == D3DERR_INVALIDCALL, "CopyRects returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); + /* Flipped. */ + SetRect(&src_rect, 0, 480, 640, 0); + hr = IDirect3DDevice8_CopyRects(device, ds1, &src_rect, 1, ds2, &dst_point); + ok(hr == D3DERR_INVALIDCALL, "CopyRects returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); + /* Full, explicit. */ + SetRect(&src_rect, 0, 0, 640, 480); + hr = IDirect3DDevice8_CopyRects(device, ds1, &src_rect, 1, ds2, &dst_point); + ok(hr == D3DERR_INVALIDCALL, "CopyRects returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); + /* Depth -> color blit.*/ + hr = IDirect3DDevice8_CopyRects(device, ds1, &src_rect, 1, backbuffer, &dst_point); + ok(hr == D3DERR_INVALIDCALL, "CopyRects returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); + /* Full, NULL rects, current depth stencil -> unbound depth stencil */ + hr = IDirect3DDevice8_CopyRects(device, ds1, NULL, 0, ds2, NULL); + ok(hr == D3DERR_INVALIDCALL, "CopyRects returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); + /* Full, NULL rects, unbound depth stencil -> current depth stencil */ + hr = IDirect3DDevice8_CopyRects(device, ds2, NULL, 0, ds1, NULL); + ok(hr == D3DERR_INVALIDCALL, "CopyRects returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); + /* Full, NULL rects, unbound depth stencil -> unbound depth stencil */ + hr = IDirect3DDevice8_CopyRects(device, ds2, NULL, 0, ds3, NULL); + ok(hr == D3DERR_INVALIDCALL, "CopyRects returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); + + IDirect3DSurface8_Release(backbuffer); + IDirect3DSurface8_Release(ds3); + IDirect3DSurface8_Release(ds2); + IDirect3DSurface8_Release(ds1); + +done: + if (device) IDirect3DDevice8_Release(device); + if (d3d8) IDirect3D8_Release(d3d8); + if (hwnd) DestroyWindow(hwnd); +} + START_TEST(device) { HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" ); @@ -3145,6 +3217,7 @@ START_TEST(device) test_wrong_shader(); test_mode_change(); test_device_window_reset(); + depth_blit_test(); } UnregisterClassA("d3d8_test_wc", GetModuleHandleA(NULL)); } diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c index d8e1ed24835..aab81014b59 100644 --- a/dlls/d3d8/tests/visual.c +++ b/dlls/d3d8/tests/visual.c @@ -2429,7 +2429,7 @@ static void multisample_copy_rects_test(IDirect3DDevice8 *device) ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr); hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); + ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL); hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0); ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);