From fffaf03c0d722aa4e9036ec69e77c2d9b2c60ed1 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 27 Jan 2014 10:07:51 +0100 Subject: [PATCH] ddraw/tests: Rewrite AttachmentTest() and AttachmentTest7(). --- 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 191c13f138e..8926a9c05aa 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 78ba16b77f9..bf409f2ac3f 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 06914839113..939a9b611eb 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 b09067a042a..2a681f122de 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 a6232f24961..3494f82bdec 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();