[PATCH 1/5] ddraw/tests: Rewrite AttachmentTest() and AttachmentTest7().
Henri Verbeet
hverbeet at codeweavers.com
Mon Jan 27 03:07:51 CST 2014
---
dlls/ddraw/tests/ddraw1.c | 247 ++++++++++++++++++
dlls/ddraw/tests/ddraw2.c | 247 ++++++++++++++++++
dlls/ddraw/tests/ddraw4.c | 273 ++++++++++++++++++++
dlls/ddraw/tests/ddraw7.c | 255 +++++++++++++++++++
dlls/ddraw/tests/dsurface.c | 583 -------------------------------------------
5 files changed, 1022 insertions(+), 583 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 7ab339f..809753c 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -4153,6 +4153,252 @@ static void test_primary_palette(void)
DestroyWindow(window);
}
+static HRESULT WINAPI surface_counter(IDirectDrawSurface *surface, DDSURFACEDESC *desc, void *context)
+{
+ UINT *surface_count = context;
+
+ ++(*surface_count);
+ IDirectDrawSurface_Release(surface);
+
+ return DDENUMRET_OK;
+}
+
+static void test_surface_attachment(void)
+{
+ IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
+ DDSCAPS caps = {DDSCAPS_TEXTURE};
+ DDSURFACEDESC surface_desc;
+ IDirectDraw *ddraw;
+ UINT surface_count;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ if (!(ddraw = create_ddraw()))
+ {
+ skip("Failed to create a ddraw object, skipping test.\n");
+ return;
+ }
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+ hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
+ U2(surface_desc).dwMipMapCount = 3;
+ surface_desc.dwWidth = 128;
+ surface_desc.dwHeight = 128;
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_GetAttachedSurface(surface1, &caps, &surface2);
+ ok(SUCCEEDED(hr), "Failed to get mip level, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_GetAttachedSurface(surface2, &caps, &surface3);
+ ok(SUCCEEDED(hr), "Failed to get mip level, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_GetAttachedSurface(surface3, &caps, &surface4);
+ ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
+
+ surface_count = 0;
+ IDirectDrawSurface_EnumAttachedSurfaces(surface1, &surface_count, surface_counter);
+ ok(surface_count == 1, "Got unexpected surface_count %u.\n", surface_count);
+ surface_count = 0;
+ IDirectDrawSurface_EnumAttachedSurfaces(surface2, &surface_count, surface_counter);
+ ok(surface_count == 1, "Got unexpected surface_count %u.\n", surface_count);
+ surface_count = 0;
+ IDirectDrawSurface_EnumAttachedSurfaces(surface3, &surface_count, surface_counter);
+ ok(!surface_count, "Got unexpected surface_count %u.\n", surface_count);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+ surface_desc.dwWidth = 16;
+ surface_desc.dwHeight = 16;
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface3, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface_Release(surface4);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 16;
+ surface_desc.dwHeight = 16;
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ if (SUCCEEDED(hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4)))
+ {
+ skip("Running on refrast, skipping some tests.\n");
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface4);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ }
+ else
+ {
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface3, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ }
+
+ IDirectDrawSurface_Release(surface4);
+ IDirectDrawSurface_Release(surface3);
+ IDirectDrawSurface_Release(surface2);
+ IDirectDrawSurface_Release(surface1);
+
+ hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ /* Try a single primary and two offscreen plain surfaces. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = GetSystemMetrics(SM_CXSCREEN);
+ surface_desc.dwHeight = GetSystemMetrics(SM_CYSCREEN);
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = GetSystemMetrics(SM_CXSCREEN);
+ surface_desc.dwHeight = GetSystemMetrics(SM_CYSCREEN);
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface3, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ /* This one has a different size. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 128;
+ surface_desc.dwHeight = 128;
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ /* Try the reverse without detaching first. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
+ ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ /* Try to detach reversed. */
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(hr == DDERR_CANNOTDETACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface_Release(surface4);
+ IDirectDrawSurface_Release(surface3);
+ IDirectDrawSurface_Release(surface2);
+ IDirectDrawSurface_Release(surface1);
+
+ /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ surface_desc.dwWidth = 64;
+ surface_desc.dwHeight = 64;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
+ surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
+ surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; /* D3DFMT_R5G6B5 */
+ U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 16;
+ U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xf800;
+ U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x07e0;
+ U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x001f;
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface3, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
+ surface_desc.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
+ U1(surface_desc.ddpfPixelFormat).dwZBufferBitDepth = 16;
+ U3(surface_desc.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
+ ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
+
+ /* Attaching while already attached to other surface. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface3, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface3, 0, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ IDirectDrawSurface_Release(surface3);
+
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* Automatic detachment on release. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface_Release(surface1);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface_Release(surface2);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDraw_Release(ddraw);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ DestroyWindow(window);
+}
+
START_TEST(ddraw1)
{
test_coop_level_create_device_window();
@@ -4185,4 +4431,5 @@ START_TEST(ddraw1)
test_flip();
test_sysmem_overlay();
test_primary_palette();
+ test_surface_attachment();
}
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index e4e8ff3..1890eeb 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -5250,6 +5250,252 @@ static void test_primary_palette(void)
DestroyWindow(window);
}
+static HRESULT WINAPI surface_counter(IDirectDrawSurface *surface, DDSURFACEDESC *desc, void *context)
+{
+ UINT *surface_count = context;
+
+ ++(*surface_count);
+ IDirectDrawSurface_Release(surface);
+
+ return DDENUMRET_OK;
+}
+
+static void test_surface_attachment(void)
+{
+ IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
+ DDSCAPS caps = {DDSCAPS_TEXTURE};
+ DDSURFACEDESC surface_desc;
+ IDirectDraw2 *ddraw;
+ UINT surface_count;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ if (!(ddraw = create_ddraw()))
+ {
+ skip("Failed to create a ddraw object, skipping test.\n");
+ return;
+ }
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+ hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
+ U2(surface_desc).dwMipMapCount = 3;
+ surface_desc.dwWidth = 128;
+ surface_desc.dwHeight = 128;
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_GetAttachedSurface(surface1, &caps, &surface2);
+ ok(SUCCEEDED(hr), "Failed to get mip level, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_GetAttachedSurface(surface2, &caps, &surface3);
+ ok(SUCCEEDED(hr), "Failed to get mip level, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_GetAttachedSurface(surface3, &caps, &surface4);
+ ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
+
+ surface_count = 0;
+ IDirectDrawSurface_EnumAttachedSurfaces(surface1, &surface_count, surface_counter);
+ ok(surface_count == 1, "Got unexpected surface_count %u.\n", surface_count);
+ surface_count = 0;
+ IDirectDrawSurface_EnumAttachedSurfaces(surface2, &surface_count, surface_counter);
+ ok(surface_count == 1, "Got unexpected surface_count %u.\n", surface_count);
+ surface_count = 0;
+ IDirectDrawSurface_EnumAttachedSurfaces(surface3, &surface_count, surface_counter);
+ ok(!surface_count, "Got unexpected surface_count %u.\n", surface_count);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+ surface_desc.dwWidth = 16;
+ surface_desc.dwHeight = 16;
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface3, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface_Release(surface4);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 16;
+ surface_desc.dwHeight = 16;
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ if (SUCCEEDED(hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4)))
+ {
+ skip("Running on refrast, skipping some tests.\n");
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface4);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ }
+ else
+ {
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface3, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ }
+
+ IDirectDrawSurface_Release(surface4);
+ IDirectDrawSurface_Release(surface3);
+ IDirectDrawSurface_Release(surface2);
+ IDirectDrawSurface_Release(surface1);
+
+ hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ /* Try a single primary and two offscreen plain surfaces. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = GetSystemMetrics(SM_CXSCREEN);
+ surface_desc.dwHeight = GetSystemMetrics(SM_CYSCREEN);
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = GetSystemMetrics(SM_CXSCREEN);
+ surface_desc.dwHeight = GetSystemMetrics(SM_CYSCREEN);
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface3, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ /* This one has a different size. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 128;
+ surface_desc.dwHeight = 128;
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ /* Try the reverse without detaching first. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
+ ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ /* Try to detach reversed. */
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(hr == DDERR_CANNOTDETACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface_Release(surface4);
+ IDirectDrawSurface_Release(surface3);
+ IDirectDrawSurface_Release(surface2);
+ IDirectDrawSurface_Release(surface1);
+
+ /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ surface_desc.dwWidth = 64;
+ surface_desc.dwHeight = 64;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
+ surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
+ surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; /* D3DFMT_R5G6B5 */
+ U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 16;
+ U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xf800;
+ U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x07e0;
+ U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x001f;
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface3, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
+ surface_desc.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
+ U1(surface_desc.ddpfPixelFormat).dwZBufferBitDepth = 16;
+ U3(surface_desc.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
+ ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
+
+ /* Attaching while already attached to other surface. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface3, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface3, 0, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ IDirectDrawSurface_Release(surface3);
+
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* Automatic detachment on release. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface_Release(surface1);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface_Release(surface2);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDraw2_Release(ddraw);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ DestroyWindow(window);
+}
+
START_TEST(ddraw2)
{
test_coop_level_create_device_window();
@@ -5288,4 +5534,5 @@ START_TEST(ddraw2)
test_user_memory_getdc();
test_sysmem_overlay();
test_primary_palette();
+ test_surface_attachment();
}
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index a639834..a9d8237 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -5846,6 +5846,278 @@ static void test_primary_palette(void)
DestroyWindow(window);
}
+static HRESULT WINAPI surface_counter(IDirectDrawSurface4 *surface, DDSURFACEDESC2 *desc, void *context)
+{
+ UINT *surface_count = context;
+
+ ++(*surface_count);
+ IDirectDrawSurface_Release(surface);
+
+ return DDENUMRET_OK;
+}
+
+static void test_surface_attachment(void)
+{
+ IDirectDrawSurface4 *surface1, *surface2, *surface3, *surface4;
+ IDirectDrawSurface *surface1v1, *surface2v1;
+ DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0};
+ DDSURFACEDESC2 surface_desc;
+ IDirectDraw4 *ddraw;
+ UINT surface_count;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ if (!(ddraw = create_ddraw()))
+ {
+ skip("Failed to create a ddraw object, skipping test.\n");
+ return;
+ }
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+ hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
+ U2(surface_desc).dwMipMapCount = 3;
+ surface_desc.dwWidth = 128;
+ surface_desc.dwHeight = 128;
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_GetAttachedSurface(surface1, &caps, &surface2);
+ ok(SUCCEEDED(hr), "Failed to get mip level, hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_GetAttachedSurface(surface2, &caps, &surface3);
+ ok(SUCCEEDED(hr), "Failed to get mip level, hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_GetAttachedSurface(surface3, &caps, &surface4);
+ ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
+
+ surface_count = 0;
+ IDirectDrawSurface4_EnumAttachedSurfaces(surface1, &surface_count, surface_counter);
+ ok(surface_count == 1, "Got unexpected surface_count %u.\n", surface_count);
+ surface_count = 0;
+ IDirectDrawSurface4_EnumAttachedSurfaces(surface2, &surface_count, surface_counter);
+ ok(surface_count == 1, "Got unexpected surface_count %u.\n", surface_count);
+ surface_count = 0;
+ IDirectDrawSurface4_EnumAttachedSurfaces(surface3, &surface_count, surface_counter);
+ ok(!surface_count, "Got unexpected surface_count %u.\n", surface_count);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+ surface_desc.dwWidth = 16;
+ surface_desc.dwHeight = 16;
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface3, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface4, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface2, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface4, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface4_Release(surface4);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 16;
+ surface_desc.dwHeight = 16;
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ if (SUCCEEDED(hr = IDirectDrawSurface4_AddAttachedSurface(surface1, surface4)))
+ {
+ skip("Running on refrast, skipping some tests.\n");
+ hr = IDirectDrawSurface4_DeleteAttachedSurface(surface1, 0, surface4);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ }
+ else
+ {
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface3, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface4, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface2, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface4, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ }
+
+ IDirectDrawSurface4_Release(surface4);
+ IDirectDrawSurface4_Release(surface3);
+ IDirectDrawSurface4_Release(surface2);
+ IDirectDrawSurface4_Release(surface1);
+
+ hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ /* Try a single primary and two offscreen plain surfaces. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = GetSystemMetrics(SM_CXSCREEN);
+ surface_desc.dwHeight = GetSystemMetrics(SM_CYSCREEN);
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = GetSystemMetrics(SM_CXSCREEN);
+ surface_desc.dwHeight = GetSystemMetrics(SM_CYSCREEN);
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface3, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ /* This one has a different size. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 128;
+ surface_desc.dwHeight = 128;
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface1, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ /* Try the reverse without detaching first. */
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface2, surface1);
+ todo_wine ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_DeleteAttachedSurface(surface1, 0, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface2, surface1);
+ todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ /* Try to detach reversed. */
+ hr = IDirectDrawSurface4_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(hr == DDERR_CANNOTDETACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_DeleteAttachedSurface(surface2, 0, surface1);
+ todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface2, surface3);
+ todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_DeleteAttachedSurface(surface2, 0, surface3);
+ todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface4_Release(surface4);
+ IDirectDrawSurface4_Release(surface3);
+ IDirectDrawSurface4_Release(surface2);
+ IDirectDrawSurface4_Release(surface1);
+
+ /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ surface_desc.dwWidth = 64;
+ surface_desc.dwHeight = 64;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
+ U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
+ U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; /* D3DFMT_R5G6B5 */
+ U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 16;
+ U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0xf800;
+ U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x07e0;
+ U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x001f;
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface3, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
+ U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
+ U1(U4(surface_desc).ddpfPixelFormat).dwZBufferBitDepth = 16;
+ U3(U4(surface_desc).ddpfPixelFormat).dwZBitMask = 0x0000ffff;
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_QueryInterface(surface1, &IID_IDirectDrawSurface, (void **)&surface1v1);
+ ok(SUCCEEDED(hr), "Failed to get interface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_QueryInterface(surface2, &IID_IDirectDrawSurface, (void **)&surface2v1);
+ ok(SUCCEEDED(hr), "Failed to get interface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface1, surface2);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+ refcount = get_refcount((IUnknown *)surface2v1);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface1, surface2);
+ ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
+ todo_wine ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1v1, 0, surface2v1);
+ ok(hr == DDERR_SURFACENOTATTACHED, "Got unexpected hr %#x.\n", hr);
+
+ /* Attaching while already attached to other surface. */
+ hr = IDirectDrawSurface4_AddAttachedSurface(surface3, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_DeleteAttachedSurface(surface3, 0, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ IDirectDrawSurface4_Release(surface3);
+
+ hr = IDirectDrawSurface4_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+ refcount = get_refcount((IUnknown *)surface2v1);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* DeleteAttachedSurface() when attaching via IDirectDrawSurface. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(hr == DDERR_SURFACENOTATTACHED, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1v1, 0, surface2v1);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ refcount = IDirectDrawSurface4_Release(surface2);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface4_Release(surface1);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+
+ /* Automatic detachment on release. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2v1);
+ ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface_Release(surface1v1);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface_Release(surface2v1);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDraw4_Release(ddraw);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ DestroyWindow(window);
+}
+
START_TEST(ddraw4)
{
test_process_vertices();
@@ -5889,4 +6161,5 @@ START_TEST(ddraw4)
test_user_memory_getdc();
test_sysmem_overlay();
test_primary_palette();
+ test_surface_attachment();
}
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 9520842..dcd4d1e 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -5725,6 +5725,260 @@ static void test_primary_palette(void)
DestroyWindow(window);
}
+static HRESULT WINAPI surface_counter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
+{
+ UINT *surface_count = context;
+
+ ++(*surface_count);
+ IDirectDrawSurface_Release(surface);
+
+ return DDENUMRET_OK;
+}
+
+static void test_surface_attachment(void)
+{
+ IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
+ IDirectDrawSurface *surface1v1, *surface2v1;
+ DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0};
+ DDSURFACEDESC2 surface_desc;
+ IDirectDraw7 *ddraw;
+ UINT surface_count;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ if (!(ddraw = create_ddraw()))
+ {
+ skip("Failed to create a ddraw object, skipping test.\n");
+ return;
+ }
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+ hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
+ U2(surface_desc).dwMipMapCount = 3;
+ surface_desc.dwWidth = 128;
+ surface_desc.dwHeight = 128;
+ if (FAILED(hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface1, NULL)))
+ {
+ skip("Failed to create a texture, skipping tests.\n");
+ IDirectDraw7_Release(ddraw);
+ DestroyWindow(window);
+ return;
+ }
+
+ hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
+ ok(SUCCEEDED(hr), "Failed to get mip level, hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
+ ok(SUCCEEDED(hr), "Failed to get mip level, hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
+ ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
+
+ surface_count = 0;
+ IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &surface_count, surface_counter);
+ ok(surface_count == 1, "Got unexpected surface_count %u.\n", surface_count);
+ surface_count = 0;
+ IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &surface_count, surface_counter);
+ ok(surface_count == 1, "Got unexpected surface_count %u.\n", surface_count);
+ surface_count = 0;
+ IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &surface_count, surface_counter);
+ ok(!surface_count, "Got unexpected surface_count %u.\n", surface_count);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+ surface_desc.dwWidth = 16;
+ surface_desc.dwHeight = 16;
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface7_Release(surface4);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 16;
+ surface_desc.dwHeight = 16;
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface7_Release(surface4);
+ IDirectDrawSurface7_Release(surface3);
+ IDirectDrawSurface7_Release(surface2);
+ IDirectDrawSurface7_Release(surface1);
+
+ hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ /* Try a single primary and two offscreen plain surfaces. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = GetSystemMetrics(SM_CXSCREEN);
+ surface_desc.dwHeight = GetSystemMetrics(SM_CYSCREEN);
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = GetSystemMetrics(SM_CXSCREEN);
+ surface_desc.dwHeight = GetSystemMetrics(SM_CYSCREEN);
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface3, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ /* This one has a different size. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 128;
+ surface_desc.dwHeight = 128;
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface4, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
+ ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface7_Release(surface4);
+ IDirectDrawSurface7_Release(surface3);
+ IDirectDrawSurface7_Release(surface2);
+ IDirectDrawSurface7_Release(surface1);
+
+ /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ surface_desc.dwWidth = 64;
+ surface_desc.dwHeight = 64;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
+ U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
+ U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; /* D3DFMT_R5G6B5 */
+ U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 16;
+ U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0xf800;
+ U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x07e0;
+ U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x001f;
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface3, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
+ U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
+ U1(U4(surface_desc).ddpfPixelFormat).dwZBufferBitDepth = 16;
+ U3(U4(surface_desc).ddpfPixelFormat).dwZBitMask = 0x0000ffff;
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface7_QueryInterface(surface1, &IID_IDirectDrawSurface, (void **)&surface1v1);
+ ok(SUCCEEDED(hr), "Failed to get interface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_QueryInterface(surface2, &IID_IDirectDrawSurface, (void **)&surface2v1);
+ ok(SUCCEEDED(hr), "Failed to get interface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+ refcount = get_refcount((IUnknown *)surface2v1);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
+ ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
+ todo_wine ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1v1, 0, surface2v1);
+ ok(hr == DDERR_SURFACENOTATTACHED, "Got unexpected hr %#x.\n", hr);
+
+ /* Attaching while already attached to other surface. */
+ hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface2);
+ todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ IDirectDrawSurface7_Release(surface3);
+
+ hr = IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+ refcount = get_refcount((IUnknown *)surface2v1);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* DeleteAttachedSurface() when attaching via IDirectDrawSurface. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface2);
+ ok(hr == DDERR_SURFACENOTATTACHED, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface_DeleteAttachedSurface(surface1v1, 0, surface2v1);
+ ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
+ refcount = IDirectDrawSurface7_Release(surface2);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface7_Release(surface1);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+
+ /* Automatic detachment on release. */
+ hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
+ ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
+ refcount = get_refcount((IUnknown *)surface2v1);
+ ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface_Release(surface1v1);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDrawSurface_Release(surface2v1);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ refcount = IDirectDraw7_Release(ddraw);
+ ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+ DestroyWindow(window);
+}
+
START_TEST(ddraw7)
{
HMODULE module = GetModuleHandleA("ddraw.dll");
@@ -5776,4 +6030,5 @@ START_TEST(ddraw7)
test_user_memory_getdc();
test_sysmem_overlay();
test_primary_palette();
+ test_surface_attachment();
}
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index b07eddb..560c323 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -1111,587 +1111,6 @@ static void EnumTest(void)
IDirectDrawSurface_Release(surface);
}
-static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
-{
- UINT *num = context;
- (*num)++;
- IDirectDrawSurface_Release(surface);
- return DDENUMRET_OK;
-}
-
-static void AttachmentTest7(void)
-{
- HRESULT hr;
- IDirectDraw7 *dd7;
- IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
- IDirectDrawSurface *surface1v1, *surface2v1;
- DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0};
- DDSURFACEDESC2 ddsd, ddsd2;
- DWORD ref;
- UINT num;
- HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
- 100, 100, 160, 160, NULL, NULL, NULL, NULL);
-
- hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
- ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
- U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
- ddsd.dwWidth = 128;
- ddsd.dwHeight = 128;
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- /* ROOT */
- num = 0;
- IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
- ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
- /* DONE ROOT */
-
- /* LEVEL 1 */
- hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
- ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
- num = 0;
- IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
- ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
- /* DONE LEVEL 1 */
-
- /* LEVEL 2 */
- hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
- ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
- IDirectDrawSurface7_Release(surface2);
- num = 0;
- IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
- ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
- /* Done level 2 */
- /* Mip level 3 is still needed */
- hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
- ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
- ok(!surface4, "expected NULL pointer\n");
-
- /* Try to attach a 16x16 miplevel - Should not work as far I can see */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
- ddsd.dwWidth = 16;
- ddsd.dwHeight = 16;
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
-
- IDirectDrawSurface7_Release(surface2);
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = 16;
- ddsd.dwHeight = 16;
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
-
- IDirectDrawSurface7_Release(surface3);
- IDirectDrawSurface7_Release(surface2);
- IDirectDrawSurface7_Release(surface1);
-
- hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
-
- /* Those are some invalid descriptions, no need to test attachments with them */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
- ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
- ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
-
- /* Try a single primary and two offscreen plain surfaces */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
- ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
- ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- /* This one has a different size */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = 128;
- ddsd.dwHeight = 128;
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
-
- IDirectDrawSurface7_Release(surface4);
- IDirectDrawSurface7_Release(surface3);
- IDirectDrawSurface7_Release(surface2);
- IDirectDrawSurface7_Release(surface1);
-
- /* Test DeleteAttachedSurface and automatic detachment of attached surfaces on release */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
- ddsd.dwWidth = 64;
- ddsd.dwHeight = 64;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
- U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
- U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB; /* D3DFMT_R5G6B5 */
- U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
- U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
- U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
- U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
-
- memset(&ddsd2, 0, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
- ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
- ddsd2.dwWidth = ddsd.dwWidth;
- ddsd2.dwHeight = ddsd.dwHeight;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
- U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
- U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
- U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
- U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
-
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
- ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surface2, NULL);
- ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- hr = IDirectDrawSurface7_QueryInterface(surface1, &IID_IDirectDrawSurface, (void **)&surface1v1);
- ok(hr == DD_OK, "IDirectDrawSurface7_QueryInterface returned %08x\n", hr);
- hr = IDirectDrawSurface7_QueryInterface(surface2, &IID_IDirectDrawSurface, (void **)&surface2v1);
- ok(hr == DD_OK, "IDirectDrawSurface7_QueryInterface returned %08x\n", hr);
-
- /* DeleteAttachedSurface when attaching via IDirectDrawSurface7 */
- hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
- ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- ref = getRefcount((IUnknown *)surface2);
- ok(ref == 2, "Got refcount %d, expected 2\n", ref);
- ref = getRefcount((IUnknown *)surface2v1);
- ok(ref == 1, "Got refcount %d, expected 1\n", ref);
-
- /* Try reattach */
- hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
- ok(hr == DDERR_SURFACEALREADYATTACHED, "AddAttachedSurface returned %08x\n", hr);
-
- /* Attachment / detachment on another interface */
- hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
- todo_wine ok(hr == DDERR_CANNOTATTACHSURFACE, "AddAttachedSurface returned %08x\n", hr);
- hr = IDirectDrawSurface_DeleteAttachedSurface(surface1v1, 0, surface2v1);
- ok(hr == DDERR_SURFACENOTATTACHED, "DeleteAttachedSurface returned %08x\n", hr);
-
- /* Attaching while already attached to other surface */
- hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
- ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
- todo_wine ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- hr = IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface2);
- ok(hr == DD_OK, "DeleteAttachedSurface returned %08x\n", hr);
- }
- IDirectDrawSurface7_Release(surface3);
- }
-
- hr = IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface2);
- ok(hr == DD_OK, "DeleteAttachedSurface returned %08x\n", hr);
- ref = getRefcount((IUnknown *)surface2);
- ok(ref == 1, "Got refcount %d, expected 1\n", ref);
- ref = getRefcount((IUnknown *)surface2v1);
- ok(ref == 1, "Got refcount %d, expected 1\n", ref);
- }
-
- /* DeleteAttachedSurface when attaching via IDirectDrawSurface */
- hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
- ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- hr = IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface2);
- ok(hr == DDERR_SURFACENOTATTACHED, "DeleteAttachedSurface returned %08x\n", hr);
- hr = IDirectDrawSurface_DeleteAttachedSurface(surface1v1, 0, surface2v1);
- ok(hr == DD_OK, "DeleteAttachedSurface returned %08x\n", hr);
- }
- ref = IDirectDrawSurface7_Release(surface2);
- ok(!ref, "Got refcount %d, expected 0\n", ref);
- ref = IDirectDrawSurface7_Release(surface1);
- ok(!ref, "Got refcount %d, expected 0\n", ref);
-
- /* Automatic detachment on release */
- hr = IDirectDrawSurface_AddAttachedSurface(surface1v1, surface2v1);
- ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
- ref = getRefcount((IUnknown *)surface2v1);
- ok(ref == 2, "Got refcount %d, expected 2\n", ref);
- ref = IDirectDrawSurface_Release(surface1v1);
- ok(!ref, "Got refcount %d, expected 0\n", ref);
- ref = getRefcount((IUnknown *)surface2v1);
- ok(ref == 1, "Got refcount %d, expected 1\n", ref);
- ref = IDirectDrawSurface_Release(surface2v1);
- ok(!ref, "Got refcount %d, expected 0\n", ref);
- }
- else
- IDirectDrawSurface7_Release(surface1);
- }
-
- hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
- ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
- IDirectDraw7_Release(dd7);
-}
-
-static void AttachmentTest(void)
-{
- HRESULT hr;
- IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
- DDSURFACEDESC ddsd, ddsd2;
- DWORD ref;
- DDSCAPS caps = {DDSCAPS_TEXTURE};
- BOOL refrast = FALSE;
- HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
- 100, 100, 160, 160, NULL, NULL, NULL, NULL);
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
- U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
- ddsd.dwWidth = 128;
- ddsd.dwHeight = 128;
- hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
- ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
- hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
- ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
-
- /* Try to attach a 16x16 miplevel - Should not work as far I can see */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
- ddsd.dwWidth = 16;
- ddsd.dwHeight = 16;
- hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
- hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
-
- IDirectDrawSurface7_Release(surface4);
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = 16;
- ddsd.dwHeight = 16;
- hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- if (SUCCEEDED(IDirectDrawSurface7_AddAttachedSurface(surface1, surface4)))
- {
- IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
- refrast = TRUE;
- }
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
- if (refrast)
- ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
- else
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
- if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1); /* Succeeds on refrast */
- if (refrast)
- ok(hr == S_OK, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
- else
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
- if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4); /* Succeeds on refrast */
- if (refrast)
- ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
- else
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
- if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
- if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4); /* Succeeds on refrast */
- if (refrast)
- ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
- else
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
- if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
-
- hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
- if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
-
- IDirectDrawSurface7_Release(surface4);
- IDirectDrawSurface7_Release(surface3);
- IDirectDrawSurface7_Release(surface2);
- IDirectDrawSurface7_Release(surface1);
-
- hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
-
- /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
- hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
- ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
- /* This old ddraw version happily creates explicit front buffers */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
- hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
- IDirectDrawSurface_Release(surface1);
-
- /* Try a single primary and two offscreen plain surfaces */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
- ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
- hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
- ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
- hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- /* This one has a different size */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = 128;
- ddsd.dwHeight = 128;
- hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
- ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
-
- hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
- ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
- "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
- if(SUCCEEDED(hr))
- {
- /* Try the reverse without detaching first */
- hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
- ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
- hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
- ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
- }
- hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
- ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
- "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
- if(SUCCEEDED(hr))
- {
- /* Try to detach reversed */
- hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
- ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
- /* Now the proper detach */
- hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
- ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
- }
- hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
- ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
- "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
- if(SUCCEEDED(hr))
- {
- hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
- ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
- }
- hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
- hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
- ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
-
- IDirectDrawSurface_Release(surface4);
- IDirectDrawSurface_Release(surface3);
- IDirectDrawSurface_Release(surface2);
- IDirectDrawSurface_Release(surface1);
-
- /* Test DeleteAttachedSurface and automatic detachment of attached surfaces on release */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
- ddsd.dwWidth = 64;
- ddsd.dwHeight = 64;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
- ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
- ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; /* D3DFMT_R5G6B5 */
- U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16;
- U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xF800;
- U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x07E0;
- U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001F;
-
- memset(&ddsd2, 0, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
- ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
- ddsd2.dwWidth = ddsd.dwWidth;
- ddsd2.dwHeight = ddsd.dwHeight;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
- ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
- ddsd2.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
- U1(ddsd2.ddpfPixelFormat).dwZBufferBitDepth = 16;
- U3(ddsd2.ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
-
- hr = IDirectDraw_CreateSurface(lpDD, (DDSURFACEDESC *)&ddsd, &surface1, NULL);
- ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- hr = IDirectDraw_CreateSurface(lpDD, (DDSURFACEDESC *)&ddsd2, &surface2, NULL);
- ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- /* DeleteAttachedSurface */
- hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
- ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- ref = getRefcount((IUnknown *)surface2);
- ok(ref == 2, "Got refcount %d, expected 2\n", ref);
-
- /* Try reattach */
- hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
- ok(hr == DDERR_SURFACEALREADYATTACHED, "AddAttachedSurface returned %08x\n", hr);
-
- /* Attaching while already attached to other surface */
- hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
- ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- hr = IDirectDrawSurface_AddAttachedSurface(surface3, surface2);
- todo_wine ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
- if (SUCCEEDED(hr))
- {
- hr = IDirectDrawSurface_DeleteAttachedSurface(surface3, 0, surface2);
- ok(hr == DD_OK, "DeleteAttachedSurface returned %08x\n", hr);
- }
- IDirectDrawSurface_Release(surface3);
- }
-
- hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
- ok(hr == DD_OK, "DeleteAttachedSurface returned %08x\n", hr);
- ref = getRefcount((IUnknown *)surface2);
- ok(ref == 1, "Got refcount %d, expected 2\n", ref);
- }
-
- /* Automatic detachment on release */
- hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
- ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
- ref = getRefcount((IUnknown *)surface2);
- ok(ref == 2, "Got refcount %d, expected 2\n", ref);
- ref = IDirectDrawSurface_Release(surface1);
- ok(!ref, "Got refcount %d, expected 0\n", ref);
- ref = getRefcount((IUnknown *)surface2);
- ok(ref == 1, "Got refcount %d, expected 1\n", ref);
- ref = IDirectDrawSurface_Release(surface2);
- ok(!ref, "Got refcount %d, expected 0\n", ref);
- }
- else
- IDirectDrawSurface_Release(surface1);
- }
-
- hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
- ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
-
- DestroyWindow(window);
-}
-
struct compare
{
DWORD width, height;
@@ -4606,8 +4025,6 @@ START_TEST(dsurface)
GetDDInterface_4();
GetDDInterface_7();
EnumTest();
- AttachmentTest();
- AttachmentTest7();
CubeMapTest();
test_lockrect_invalid();
CompressedTest();
--
1.7.10.4
More information about the wine-patches
mailing list