ddraw/tests: Rewrite AttachmentTest() and AttachmentTest7().

This commit is contained in:
Henri Verbeet 2014-01-27 10:07:51 +01:00 committed by Alexandre Julliard
parent e98844e5c9
commit fffaf03c0d
5 changed files with 1022 additions and 583 deletions

View File

@ -4153,6 +4153,252 @@ static void test_primary_palette(void)
DestroyWindow(window); 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) START_TEST(ddraw1)
{ {
test_coop_level_create_device_window(); test_coop_level_create_device_window();
@ -4185,4 +4431,5 @@ START_TEST(ddraw1)
test_flip(); test_flip();
test_sysmem_overlay(); test_sysmem_overlay();
test_primary_palette(); test_primary_palette();
test_surface_attachment();
} }

View File

@ -5250,6 +5250,252 @@ static void test_primary_palette(void)
DestroyWindow(window); 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) START_TEST(ddraw2)
{ {
test_coop_level_create_device_window(); test_coop_level_create_device_window();
@ -5288,4 +5534,5 @@ START_TEST(ddraw2)
test_user_memory_getdc(); test_user_memory_getdc();
test_sysmem_overlay(); test_sysmem_overlay();
test_primary_palette(); test_primary_palette();
test_surface_attachment();
} }

View File

@ -5846,6 +5846,278 @@ static void test_primary_palette(void)
DestroyWindow(window); 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) START_TEST(ddraw4)
{ {
test_process_vertices(); test_process_vertices();
@ -5889,4 +6161,5 @@ START_TEST(ddraw4)
test_user_memory_getdc(); test_user_memory_getdc();
test_sysmem_overlay(); test_sysmem_overlay();
test_primary_palette(); test_primary_palette();
test_surface_attachment();
} }

View File

@ -5725,6 +5725,260 @@ static void test_primary_palette(void)
DestroyWindow(window); 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) START_TEST(ddraw7)
{ {
HMODULE module = GetModuleHandleA("ddraw.dll"); HMODULE module = GetModuleHandleA("ddraw.dll");
@ -5776,4 +6030,5 @@ START_TEST(ddraw7)
test_user_memory_getdc(); test_user_memory_getdc();
test_sysmem_overlay(); test_sysmem_overlay();
test_primary_palette(); test_primary_palette();
test_surface_attachment();
} }

View File

@ -1111,587 +1111,6 @@ static void EnumTest(void)
IDirectDrawSurface_Release(surface); 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 struct compare
{ {
DWORD width, height; DWORD width, height;
@ -4606,8 +4025,6 @@ START_TEST(dsurface)
GetDDInterface_4(); GetDDInterface_4();
GetDDInterface_7(); GetDDInterface_7();
EnumTest(); EnumTest();
AttachmentTest();
AttachmentTest7();
CubeMapTest(); CubeMapTest();
test_lockrect_invalid(); test_lockrect_invalid();
CompressedTest(); CompressedTest();