From 2470b0e447488818d7996b78b534102f04dbcfba Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Sun, 5 Aug 2018 02:47:52 +0430 Subject: [PATCH] ddraw/tests: Rewrite DeviceLoadTest(). Based on a patch by Alex Henrie. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/ddraw/tests/d3d.c | 1058 ------------------------------------- dlls/ddraw/tests/ddraw7.c | 482 +++++++++++++++++ 2 files changed, 482 insertions(+), 1058 deletions(-) diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c index 77836fd627e..ec0f8d715ca 100644 --- a/dlls/ddraw/tests/d3d.c +++ b/dlls/ddraw/tests/d3d.c @@ -1404,1063 +1404,6 @@ out: IDirect3DVertexBuffer7_Release(lpVBufSrc); } -#define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) ) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -static void DeviceLoadTest(void) -{ - DDSURFACEDESC2 ddsd; - IDirectDrawSurface7 *texture_levels[2][8]; - IDirectDrawSurface7 *cube_face_levels[2][6][8]; - DWORD flags; - HRESULT hr; - DDBLTFX ddbltfx; - RECT loadrect; - POINT loadpoint; - int i, i1, i2; - unsigned diff_count = 0, diff_count2 = 0; - unsigned x, y; - BOOL load_mip_subset_broken = FALSE; - IDirectDrawPalette *palettes[5]; - PALETTEENTRY table1[256]; - DDCOLORKEY ddckey; - D3DDEVICEDESC7 d3dcaps; - - /* Test loading of texture subrectangle with a mipmap surface. */ - memset(texture_levels, 0, sizeof(texture_levels)); - memset(cube_face_levels, 0, sizeof(cube_face_levels)); - memset(palettes, 0, sizeof(palettes)); - - for (i = 0; i < 2; i++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - ddsd.dwWidth = 128; - ddsd.dwHeight = 128; - U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat); - U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB; - U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32; - U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000; - U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00; - U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd); - ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr); - ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount); - if (U2(ddsd).dwMipMapCount != 8) goto out; - - for (i1 = 1; i1 < 8; i1++) - { - hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]); - ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); - if (FAILED(hr)) goto out; - } - } - - for (i1 = 0; i1 < 8; i1++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - /* x stored in green component, y in blue. */ - DWORD color = 0xff0000 | (x << 8) | y; - *textureRow++ = color; - } - } - - hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - } - - for (i1 = 0; i1 < 8; i1++) - { - memset(&ddbltfx, 0, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - U5(ddbltfx).dwFillColor = 0; - hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); - ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr); - } - - /* First test some broken coordinates. */ - loadpoint.x = loadpoint.y = 0; - SetRectEmpty(&loadrect); - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0); - ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr); - - loadpoint.x = loadpoint.y = 50; - loadrect.left = 0; - loadrect.top = 0; - loadrect.right = 100; - loadrect.bottom = 100; - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0); - ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr); - - /* Test actual loading. */ - loadpoint.x = loadpoint.y = 31; - loadrect.left = 30; - loadrect.top = 20; - loadrect.right = 93; - loadrect.bottom = 52; - - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0); - ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr); - - for (i1 = 0; i1 < 8; i1++) - { - diff_count = 0; - diff_count2 = 0; - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - DWORD color = *textureRow++; - - if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || - y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top) - { - if (color & 0xffffff) diff_count++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - - if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++; - } - - /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may - technically be correct as it's not precisely defined by docs. */ - if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || - y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1) - { - if (color & 0xffffff) diff_count2++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - - if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) || - !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++; - } - } - } - - hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - - ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", - MIN(diff_count, diff_count2), i1); - - loadpoint.x /= 2; - loadpoint.y /= 2; - loadrect.top /= 2; - loadrect.left /= 2; - loadrect.right = (loadrect.right + 1) / 2; - loadrect.bottom = (loadrect.bottom + 1) / 2; - } - - /* This crashes on native (tested on real windows XP / directx9 / nvidia and - * qemu Win98 / directx7 / RGB software rasterizer): - * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this) - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0); - */ - - /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */ - for (i = 0; i < 2; i++) - { - for (i1 = 7; i1 >= 0; i1--) - { - if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]); - } - } - memset(texture_levels, 0, sizeof(texture_levels)); - - /* Test texture size mismatch. */ - for (i = 0; i < 2; i++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - ddsd.dwWidth = i ? 256 : 128; - ddsd.dwHeight = 128; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - } - - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0); - ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr); - - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0); - ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr); - - IDirectDrawSurface7_Release(texture_levels[0][0]); - IDirectDrawSurface7_Release(texture_levels[1][0]); - memset(texture_levels, 0, sizeof(texture_levels)); - - memset(&d3dcaps, 0, sizeof(d3dcaps)); - hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps); - ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr); - - if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP)) - { - skip("No cubemap support\n"); - } - else - { - /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */ - for (i = 0; i < 2; i++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES; - ddsd.dwWidth = 128; - ddsd.dwHeight = 128; - U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat); - U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB; - U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32; - U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000; - U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00; - U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - flags = DDSCAPS2_CUBEMAP_NEGATIVEX; - for (i1 = 1; i1 < 6; i1++, flags <<= 1) - { - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags; - hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]); - ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); - if (FAILED(hr)) goto out; - } - - for (i1 = 0; i1 < 6; i1++) - { - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd); - ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr); - ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount); - if (U2(ddsd).dwMipMapCount != 8) goto out; - - for (i2 = 1; i2 < 8; i2++) - { - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL; - hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]); - ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); - if (FAILED(hr)) goto out; - } - } - } - - for (i = 0; i < 6; i++) - for (i1 = 0; i1 < 8; i1++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - /* face number in low 4 bits of red, x stored in green component, y in blue. */ - DWORD color = 0xf00000 | (i << 16) | (x << 8) | y; - *textureRow++ = color; - } - } - - hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - } - - for (i = 0; i < 6; i++) - for (i1 = 0; i1 < 8; i1++) - { - memset(&ddbltfx, 0, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - U5(ddbltfx).dwFillColor = 0; - hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); - ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr); - } - - loadpoint.x = loadpoint.y = 10; - loadrect.left = 30; - loadrect.top = 20; - loadrect.right = 93; - loadrect.bottom = 52; - - hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect, - DDSCAPS2_CUBEMAP_ALLFACES); - ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr); - - for (i = 0; i < 6; i++) - { - loadpoint.x = loadpoint.y = 10; - loadrect.left = 30; - loadrect.top = 20; - loadrect.right = 93; - loadrect.bottom = 52; - - for (i1 = 0; i1 < 8; i1++) - { - diff_count = 0; - diff_count2 = 0; - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - DWORD color = *textureRow++; - - if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || - y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top) - { - if (color & 0xffffff) diff_count++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - - if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x || - b != y + loadrect.top - loadpoint.y) diff_count++; - } - - /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may - technically be correct as it's not precisely defined by docs. */ - if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || - y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1) - { - if (color & 0xffffff) diff_count2++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - - if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) || - !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++; - } - } - } - - hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - - ok(diff_count == 0 || diff_count2 == 0, - "Unexpected destination texture level pixels; %u differences at face %x level %d\n", - MIN(diff_count, diff_count2), i, i1); - - loadpoint.x /= 2; - loadpoint.y /= 2; - loadrect.top /= 2; - loadrect.left /= 2; - loadrect.right = (loadrect.right + 1) / 2; - loadrect.bottom = (loadrect.bottom + 1) / 2; - } - } - - for (i = 0; i < 2; i++) - for (i1 = 5; i1 >= 0; i1--) - for (i2 = 7; i2 >= 0; i2--) - { - if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]); - } - memset(cube_face_levels, 0, sizeof(cube_face_levels)); - - /* Test cubemap loading from regular texture. */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX; - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES; - ddsd.dwWidth = 128; - ddsd.dwHeight = 128; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - ddsd.dwWidth = 128; - ddsd.dwHeight = 128; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL, - DDSCAPS2_CUBEMAP_ALLFACES); - ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr); - - IDirectDrawSurface7_Release(cube_face_levels[0][0][0]); - memset(cube_face_levels, 0, sizeof(cube_face_levels)); - IDirectDrawSurface7_Release(texture_levels[0][0]); - memset(texture_levels, 0, sizeof(texture_levels)); - - /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag) - * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP, - * Catalyst 10.2 driver, 6.14.10.6925) - */ - } - - /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */ - for (i = 0; i < 2; i++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - ddsd.dwWidth = 128; - ddsd.dwHeight = 128; - U2(ddsd).dwMipMapCount = i ? 4 : 8; - U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat); - U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB; - U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32; - U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000; - U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00; - U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd); - ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr); - ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount); - if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out; - - for (i1 = 1; i1 < (i ? 4 : 8); i1++) - { - hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]); - ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); - if (FAILED(hr)) goto out; - } - } - - for (i1 = 0; i1 < 8; i1++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - /* x stored in green component, y in blue. */ - DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y; - *textureRow++ = color; - } - } - - hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - } - - for (i1 = 0; i1 < 4; i1++) - { - memset(&ddbltfx, 0, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - U5(ddbltfx).dwFillColor = 0; - hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); - ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr); - } - - loadpoint.x = loadpoint.y = 31; - loadrect.left = 30; - loadrect.top = 20; - loadrect.right = 93; - loadrect.bottom = 52; - - /* Destination mip levels are a subset of source mip levels. */ - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0); - ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr); - - for (i1 = 0; i1 < 4; i1++) - { - diff_count = 0; - diff_count2 = 0; - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - DWORD color = *textureRow++; - - if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || - y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top) - { - if (color & 0xffffff) diff_count++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - - if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x || - b != y + loadrect.top - loadpoint.y) diff_count++; - } - - /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may - technically be correct as it's not precisely defined by docs. */ - if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || - y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1) - { - if (color & 0xffffff) diff_count2++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - - if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) || - !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++; - } - } - } - - hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - - ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", - MIN(diff_count, diff_count2), i1); - - loadpoint.x /= 2; - loadpoint.y /= 2; - loadrect.top /= 2; - loadrect.left /= 2; - loadrect.right = (loadrect.right + 1) / 2; - loadrect.bottom = (loadrect.bottom + 1) / 2; - } - - /* Destination mip levels are a superset of source mip levels (should fail). */ - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0); - ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr); - - for (i = 0; i < 2; i++) - { - for (i1 = 7; i1 >= 0; i1--) - { - if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]); - } - } - memset(texture_levels, 0, sizeof(texture_levels)); - - /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - ddsd.dwWidth = 128; - ddsd.dwHeight = 128; - U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat); - U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB; - U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32; - U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000; - U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00; - U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - ddsd.dwWidth = 32; - ddsd.dwHeight = 32; - U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat); - U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB; - U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32; - U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000; - U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00; - U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (i1 = 1; i1 < 8; i1++) - { - hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]); - ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); - if (FAILED(hr)) goto out; - } - - for (i1 = 0; i1 < 8; i1++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - /* x stored in green component, y in blue. */ - DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y; - *textureRow++ = color; - } - } - - hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - } - - memset(&ddbltfx, 0, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - U5(ddbltfx).dwFillColor = 0; - hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); - ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr); - - loadpoint.x = loadpoint.y = 32; - loadrect.left = 32; - loadrect.top = 32; - loadrect.right = 96; - loadrect.bottom = 96; - - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0); - ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr); - - loadpoint.x /= 4; - loadpoint.y /= 4; - loadrect.top /= 4; - loadrect.left /= 4; - loadrect.right = (loadrect.right + 3) / 4; - loadrect.bottom = (loadrect.bottom + 3) / 4; - - /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken: - * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with - * copied subrectangles divided more than needed, without apparent logic. But it works - * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g. - * some games don't work that worked in Win98, so it is assumed here XP results are wrong. - * The following code attempts to detect broken results, actual tests will then be skipped - */ - load_mip_subset_broken = TRUE; - diff_count = 0; - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - DWORD color = *textureRow++; - - if (x < 2 || x >= 2 + 4 || - y < 2 || y >= 2 + 4) - { - if (color & 0xffffff) diff_count++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - - if ((r & (0xf0)) != 0xf0) diff_count++; - } - } - } - - if (diff_count) load_mip_subset_broken = FALSE; - - if (load_mip_subset_broken) { - skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n"); - } else { - diff_count = 0; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - DWORD color = *textureRow++; - - if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || - y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top) - { - if (color & 0xffffff) diff_count++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - - if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x || - b != y + loadrect.top - loadpoint.y) diff_count++; - } - } - } - } - - hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - - ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count); - - for (i = 0; i < 2; i++) - { - for (i1 = 7; i1 >= 0; i1--) - { - if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]); - } - } - memset(texture_levels, 0, sizeof(texture_levels)); - - if (!load_mip_subset_broken) - { - /* Test loading when destination mip levels are a subset of source mip levels and start from smaller - * surface (than first source mip level) - */ - for (i = 0; i < 2; i++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - ddsd.dwWidth = i ? 32 : 128; - ddsd.dwHeight = i ? 32 : 128; - if (i) U2(ddsd).dwMipMapCount = 4; - U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat); - U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB; - U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32; - U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000; - U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00; - U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd); - ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr); - ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount); - if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out; - - for (i1 = 1; i1 < (i ? 4 : 8); i1++) - { - hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]); - ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); - if (FAILED(hr)) goto out; - } - } - - for (i1 = 0; i1 < 8; i1++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - /* x stored in green component, y in blue. */ - DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y; - *textureRow++ = color; - } - } - - hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - } - - for (i1 = 0; i1 < 4; i1++) - { - memset(&ddbltfx, 0, sizeof(ddbltfx)); - ddbltfx.dwSize = sizeof(ddbltfx); - U5(ddbltfx).dwFillColor = 0; - hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); - ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr); - } - - loadpoint.x = loadpoint.y = 0; - loadrect.left = 0; - loadrect.top = 0; - loadrect.right = 64; - loadrect.bottom = 64; - - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0); - ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr); - - i = 0; - for (i1 = 0; i1 < 8 && i < 4; i1++) - { - DDSURFACEDESC2 ddsd2; - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd); - ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr); - - memset(&ddsd2, 0, sizeof(DDSURFACEDESC2)); - ddsd2.dwSize = sizeof(ddsd2); - hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2); - ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr); - - if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight) - { - diff_count = 0; - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr); - if (FAILED(hr)) goto out; - - for (y = 0 ; y < ddsd.dwHeight; y++) - { - DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); - - for (x = 0; x < ddsd.dwWidth; x++) - { - DWORD color = *textureRow++; - - if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || - y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top) - { - if (color & 0xffffff) diff_count++; - } - else - { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - - if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x || - b != y + loadrect.top - loadpoint.y) diff_count++; - } - } - } - - hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL); - ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr); - - ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1); - - i++; - } - - loadpoint.x /= 2; - loadpoint.y /= 2; - loadrect.top /= 2; - loadrect.left /= 2; - loadrect.right = (loadrect.right + 1) / 2; - loadrect.bottom = (loadrect.bottom + 1) / 2; - } - - for (i = 0; i < 2; i++) - { - for (i1 = 7; i1 >= 0; i1--) - { - if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]); - } - } - memset(texture_levels, 0, sizeof(texture_levels)); - } - - /* Test palette copying. */ - for (i = 0; i < 2; i++) - { - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - ddsd.dwWidth = 128; - ddsd.dwHeight = 128; - U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat); - U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8; - U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8; - hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL); - ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); - if (FAILED(hr)) goto out; - - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd); - ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr); - ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount); - if (U2(ddsd).dwMipMapCount != 8) goto out; - - for (i1 = 1; i1 < 8; i1++) - { - hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]); - ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); - if (FAILED(hr)) goto out; - } - } - - memset(table1, 0, sizeof(table1)); - for (i = 0; i < 3; i++) - { - table1[0].peBlue = i + 1; - hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL); - ok(hr == DD_OK, "CreatePalette returned %08x\n", hr); - if (FAILED(hr)) - { - skip("IDirectDraw7_CreatePalette failed; skipping further tests\n"); - goto out; - } - } - - hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]); - ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr); - - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0); - ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr); - - hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]); - ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr); - - hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]); - ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr); - - hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]); - ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr); - hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]); - ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr); - - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0); - ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr); - - memset(table1, 0, sizeof(table1)); - hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]); - ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr); - if (SUCCEEDED(hr)) - { - hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1); - ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr); - ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue); - } - - /* Test colorkey copying. */ - ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64; - hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey); - ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr); - hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey); - ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "Got unexpected hr %#x.\n", hr); - - hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey); - ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr); - - hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0); - ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr); - - hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey); - ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr); - ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64, - "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue); - - out: - - for (i = 0; i < 5; i++) - { - if (palettes[i]) IDirectDrawPalette_Release(palettes[i]); - } - - for (i = 0; i < 2; i++) - { - for (i1 = 7; i1 >= 0; i1--) - { - if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]); - } - } - - for (i = 0; i < 2; i++) - for (i1 = 5; i1 >= 0; i1--) - for (i2 = 7; i2 >= 0; i2--) - { - if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]); - } -} - static void SetMaterialTest(void) { HRESULT rc; @@ -3422,7 +2365,6 @@ START_TEST(d3d) SetMaterialTest(); CapsTest(); VertexBufferDescTest(); - DeviceLoadTest(); SetRenderTargetTest(); VertexBufferLockRest(); z_format_test(); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 35a45c03456..4b9d367a748 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -14267,6 +14267,487 @@ static void test_viewport(void) DestroyWindow(window); } +static unsigned int validate_loaded_surface(IDirectDrawSurface7 *surface, unsigned int face, + unsigned int level, const RECT *src_rect, const POINT *dst_point) +{ + DDSURFACEDESC2 surface_desc; + unsigned int diff, x, y; + HRESULT hr; + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to map surface, hr %#x.\n", hr); + + for (y = 0, diff = 0; y < surface_desc.dwHeight; ++y) + { + DWORD *texture_row = (DWORD *)((char *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); + + for (x = 0; x < surface_desc.dwWidth; ++x) + { + DWORD colour = texture_row[x]; + DWORD r = (colour & 0xff0000) >> 16; + DWORD g = (colour & 0xff00) >> 8; + DWORD b = (colour & 0xff); + + if (x < dst_point->x || x >= dst_point->x + src_rect->right - src_rect->left + || y < dst_point->y || y >= dst_point->y + src_rect->bottom - src_rect->top) + { + if (colour & 0xffffff) + ++diff; + } + else + { + if (r != ((face << 4) | level) + || g != x + src_rect->left - dst_point->x + || b != y + src_rect->top - dst_point->y) + ++diff; + } + } + } + + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unmap surface, hr %#x.\n", hr); + + return diff; +} + +static void test_device_load(void) +{ + IDirectDrawSurface7 *src_surface, *dst_surface, *surface, *tmp; + DDSCAPS2 mip_caps = {0, DDSCAPS2_MIPMAPSUBLEVEL, 0, {0}}; + IDirectDrawPalette *src_palette, *dst_palette, *palette; + unsigned int i, j, k, l, x, y; + DDSURFACEDESC2 surface_desc; + IDirect3DDevice7 *device; + PALETTEENTRY table1[256]; + D3DDEVICEDESC7 d3d_caps; + DDCOLORKEY colour_key; + IDirectDraw7 *ddraw; + BOOL cube_support; + IDirect3D7 *d3d; + ULONG refcount; + HWND window; + DDBLTFX fx; + HRESULT hr; + +#define TEX_MIP 0x01 +#define TEX_CUBE 0x02 +#define NULL_COORDS 0x04 + + /* Creating partial cube maps (e.g. created with just + * DDSCAPS2_CUBEMAP_POSITIVEX) BSODs some Windows machines. (Radeon X1600, + * Windows XP, Catalyst 10.2 driver, 6.14.10.6925) + * + * Passing non-toplevel surfaces to IDirect3DDevice7_Load() crashes on + * native. (Windows XP / NVIDIA, Windows 98 / RGB software rasteriser) */ + static const struct + { + unsigned int src_w, src_h, src_mip_count; + RECT src_rect; + DWORD src_flags; + unsigned int dst_w, dst_h, dst_mip_count; + POINT dst_point; + DWORD dst_flags; + HRESULT hr; + } + tests[] = + { + {128, 128, 0, { 0, 0, 0, 0}, TEX_MIP, 128, 128, 0, { 0, 0}, TEX_MIP, DDERR_INVALIDPARAMS}, + {128, 128, 0, { 0, 0, 100, 100}, TEX_MIP, 128, 128, 0, {50, 50}, TEX_MIP, DDERR_INVALIDPARAMS}, + {128, 128, 0, {30, 20, 93, 52}, TEX_MIP, 128, 128, 0, {31, 31}, TEX_MIP, D3D_OK}, + {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS, 128, 128, 0, { 0, 0}, NULL_COORDS, D3D_OK}, + {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS, 256, 128, 0, { 0, 0}, NULL_COORDS, DDERR_INVALIDPARAMS}, + {256, 128, 0, { 0, 0, 0, 0}, NULL_COORDS, 128, 128, 0, { 0, 0}, NULL_COORDS, DDERR_INVALIDPARAMS}, + {128, 128, 0, {30, 20, 93, 52}, TEX_MIP | TEX_CUBE, 128, 128, 0, {10, 10}, TEX_MIP | TEX_CUBE, D3D_OK}, + {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS, 128, 128, 0, { 0, 0}, TEX_CUBE | NULL_COORDS, DDERR_INVALIDPARAMS}, + {128, 128, 0, {30, 20, 93, 52}, TEX_MIP, 128, 128, 4, {31, 31}, TEX_MIP, D3D_OK}, + {128, 128, 4, {30, 20, 93, 52}, TEX_MIP, 128, 128, 0, {31, 31}, TEX_MIP, DDERR_INVALIDPARAMS}, + {128, 128, 0, {32, 32, 96, 96}, TEX_MIP, 32, 32, 0, {32, 32}, 0, D3D_OK}, + {128, 128, 0, { 0, 0, 64, 64}, TEX_MIP, 32, 32, 4, { 0, 0}, TEX_MIP, D3D_OK}, + }; + + window = create_window(); + if (!(device = create_device(window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice7_GetDirect3D(device, &d3d); + ok(SUCCEEDED(hr), "Failed to get Direct3D7 interface, hr %#x.\n", hr); + hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw); + ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); + IDirect3D7_Release(d3d); + + memset(&d3d_caps, 0, sizeof(d3d_caps)); + hr = IDirect3DDevice7_GetCaps(device, &d3d_caps); + ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); + cube_support = d3d_caps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + unsigned int src_count, dst_count; + POINT dst_point, dst_point_broken; + RECT src_rect, src_rect_broken; + + if ((tests[i].src_flags | tests[i].dst_flags) & TEX_CUBE && !cube_support) + { + skip("No cubemap support, skipping test %u.\n", i); + continue; + } + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + if (tests[i].src_mip_count) + surface_desc.dwFlags |= DDSD_MIPMAPCOUNT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + if (tests[i].src_flags & (TEX_MIP | TEX_CUBE)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX; + if (tests[i].src_flags & TEX_MIP) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_MIPMAP; + if (tests[i].src_flags & TEX_CUBE) + surface_desc.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES; + surface_desc.dwWidth = tests[i].src_w; + surface_desc.dwHeight = tests[i].src_h; + U2(surface_desc).dwMipMapCount = tests[i].src_mip_count; + U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); + U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32; + U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000; + U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00; + U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &src_surface, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to create source surface, hr %#x.\n", i, hr); + + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + if (tests[i].dst_mip_count) + surface_desc.dwFlags |= DDSD_MIPMAPCOUNT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + if (tests[i].dst_flags & (TEX_MIP | TEX_CUBE)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX; + if (tests[i].dst_flags & TEX_MIP) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_MIPMAP; + surface_desc.ddsCaps.dwCaps2 = 0; + if (tests[i].dst_flags & TEX_CUBE) + surface_desc.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES; + surface_desc.dwWidth = tests[i].dst_w; + surface_desc.dwHeight = tests[i].dst_h; + U2(surface_desc).dwMipMapCount = tests[i].dst_mip_count; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to create destination surface, hr %#x.\n", i, hr); + + src_count = dst_count = 1; + if (tests[i].src_flags & TEX_MIP) + src_count = tests[i].src_mip_count ? tests[i].src_mip_count : 8; + if (tests[i].dst_flags & TEX_MIP) + dst_count = tests[i].dst_mip_count ? tests[i].dst_mip_count : 8; + + surface = src_surface; + IDirectDrawSurface7_AddRef(surface); + for (j = 0;;) + { + DDSCAPS2 face_caps = {0, 0, 0, {0}}; + + /* Check the number of created mipmaps. */ + if (tests[i].src_flags & TEX_MIP) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &surface_desc); + ok(SUCCEEDED(hr), "Test %u: Failed to get surface description, hr %#x.\n", i, hr); + ok(U2(surface_desc).dwMipMapCount == src_count, + "Test %u: Got unexpected mip count %u, expected %u.\n", + i, U2(surface_desc).dwMipMapCount, src_count); + } + + for (k = 0; ; ++k) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to map surface, hr %#x.\n", i, hr); + + for (y = 0; y < surface_desc.dwHeight; ++y) + { + DWORD *texture_row = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); + + for (x = 0; x < surface_desc.dwWidth; ++x) + { + /* The face number is stored in the high 4 bits of the + * red component, the mip-level in the low 4 bits. The + * x-coordinate is stored in the green component, and + * the y-coordinate in the blue component. */ + texture_row[x] = (j << 20) | (k << 16) | (x << 8) | y; + } + } + + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to unmap surface, hr %#x.\n", i, hr); + + hr = IDirectDrawSurface7_GetAttachedSurface(surface, &mip_caps, &tmp); + IDirectDrawSurface7_Release(surface); + if (FAILED(hr)) + break; + surface = tmp; + } + + if (!(tests[i].src_flags & TEX_CUBE) || ++j >= 6) + break; + + face_caps.dwCaps2 = DDSCAPS2_CUBEMAP | (DDSCAPS2_CUBEMAP_POSITIVEX << j); + hr = IDirectDrawSurface7_GetAttachedSurface(src_surface, &face_caps, &surface); + ok(SUCCEEDED(hr), "Test %u: Failed to get face %u.\n", i, j); + } + + surface = dst_surface; + IDirectDrawSurface7_AddRef(surface); + for (j = 0;;) + { + DDSCAPS2 face_caps = {0, 0, 0, {0}}; + + /* Check the number of created mipmaps. */ + if (tests[i].dst_flags & TEX_MIP) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &surface_desc); + ok(SUCCEEDED(hr), "Test %u: Failed to get surface description, hr %#x.\n", i, hr); + ok(U2(surface_desc).dwMipMapCount == dst_count, + "Test %u: Got unexpected mip count %u, expected %u.\n", + i, U2(surface_desc).dwMipMapCount, dst_count); + } + + for (;;) + { + memset(&fx, 0, sizeof(fx)); + fx.dwSize = sizeof(fx); + U5(fx).dwFillColor = 0x00000000; + hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(SUCCEEDED(hr), "Test %u: Failed to clear surface, hr %#x.\n", i, hr); + + hr = IDirectDrawSurface7_GetAttachedSurface(surface, &mip_caps, &tmp); + IDirectDrawSurface7_Release(surface); + if (FAILED(hr)) + break; + surface = tmp; + } + + if (!(tests[i].dst_flags & TEX_CUBE) || ++j >= 6) + break; + + face_caps.dwCaps2 = DDSCAPS2_CUBEMAP | (DDSCAPS2_CUBEMAP_POSITIVEX << j); + hr = IDirectDrawSurface7_GetAttachedSurface(dst_surface, &face_caps, &surface); + ok(SUCCEEDED(hr), "Test %u: Failed to get face %u.\n", i, j); + } + + src_rect = tests[i].src_rect; + dst_point = tests[i].dst_point; + hr = IDirect3DDevice7_Load(device, + dst_surface, tests[i].dst_flags & NULL_COORDS ? NULL : &dst_point, + src_surface, tests[i].src_flags & NULL_COORDS ? NULL : &src_rect, + tests[i].dst_flags & TEX_CUBE ? DDSCAPS2_CUBEMAP_ALLFACES : 0); + ok(hr == tests[i].hr, "Test %u: Got unexpected hr %#x.\n", i, hr); + + if (SUCCEEDED(hr)) + { + unsigned int level_offset, level_offset_broken; + + for (level_offset = 0, k = tests[i].src_w; k > tests[i].dst_w; ++level_offset, k /= 2); + level_offset_broken = src_count - dst_count; + + surface = dst_surface; + IDirectDrawSurface7_AddRef(surface); + for (j = 0;;) + { + DDSCAPS2 face_caps = {0, 0, 0, {0}}; + + if (tests[i].src_flags & NULL_COORDS) + SetRect(&src_rect, 0, 0, tests[i].src_w, tests[i].src_h); + else + src_rect = tests[i].src_rect; + + if (tests[i].dst_flags & NULL_COORDS) + dst_point.x = dst_point.y = 0; + else + dst_point = tests[i].dst_point; + + for (k = 0; k < level_offset; ++k) + { + dst_point.x /= 2; + dst_point.y /= 2; + src_rect.top /= 2; + src_rect.left /= 2; + src_rect.right = (src_rect.right + 1) / 2; + src_rect.bottom = (src_rect.bottom + 1) / 2; + } + + for (k = 0; ; ++k) + { + unsigned int diff, diff2, diff3; + + diff = validate_loaded_surface(surface, j, k + level_offset, &src_rect, &dst_point); + + /* On some newer (XP+) versions of Windows, it appears the + * source/destination coordinates are divided too often. + * This works correctly on Windows 98 with the RGB + * software rasteriser. */ + src_rect_broken = src_rect; + dst_point_broken = dst_point; + for (l = 0; l < level_offset; ++l) + { + dst_point_broken.x /= 2; + dst_point_broken.y /= 2; + src_rect_broken.top /= 2; + src_rect_broken.left /= 2; + src_rect_broken.right = (src_rect_broken.right + 1) / 2; + src_rect_broken.bottom = (src_rect_broken.bottom + 1) / 2; + } + diff2 = validate_loaded_surface(surface, j, k + level_offset, + &src_rect_broken, &dst_point_broken); + + /* On Windows 8+ things are slightly worse still. Instead + * of applying the correct level offset twice, like on + * XP+, an incorrect offset is applied in addition to the + * correct one. Additionally, on Windows 8+, this offset + * also affects the selected source mip-level, as opposed + * to Windows XP+ where it only affects the + * source/destination coordinates. */ + src_rect_broken = src_rect; + dst_point_broken = dst_point; + for (l = 0; l < level_offset_broken; ++l) + { + dst_point_broken.x /= 2; + dst_point_broken.y /= 2; + src_rect_broken.top /= 2; + src_rect_broken.left /= 2; + src_rect_broken.right = (src_rect_broken.right + 1) / 2; + src_rect_broken.bottom = (src_rect_broken.bottom + 1) / 2; + } + diff3 = validate_loaded_surface(surface, j, k + level_offset_broken, + &src_rect_broken, &dst_point_broken); + + ok(!diff || broken(!diff2 || !diff3), "Test %u, face %u, level %u: " + "Unexpected destination texture level pixels; %u/%u/%u differences.\n", + i, j, k, diff, diff2, diff3); + + hr = IDirectDrawSurface7_GetAttachedSurface(surface, &mip_caps, &tmp); + IDirectDrawSurface7_Release(surface); + if (FAILED(hr)) + break; + surface = tmp; + + dst_point.x /= 2; + dst_point.y /= 2; + src_rect.top /= 2; + src_rect.left /= 2; + src_rect.right = (src_rect.right + 1) / 2; + src_rect.bottom = (src_rect.bottom + 1) / 2; + } + + if (!(tests[i].dst_flags & TEX_CUBE) || ++j >= 6) + break; + + face_caps.dwCaps2 = DDSCAPS2_CUBEMAP | (DDSCAPS2_CUBEMAP_POSITIVEX << j); + hr = IDirectDrawSurface7_GetAttachedSurface(dst_surface, &face_caps, &surface); + ok(SUCCEEDED(hr), "Test %u: Failed to get face %u.\n", i, j); + } + } + + IDirectDrawSurface7_Release(dst_surface); + IDirectDrawSurface7_Release(src_surface); + } +#undef TEX_MIP +#undef TEX_CUBE +#undef NULL_COORDS + + 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.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); + U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8; + U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 8; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &src_surface, NULL); + ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr); + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL); + ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr); + hr = IDirectDrawSurface7_GetAttachedSurface(src_surface, &mip_caps, &surface); + ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr); + + /* Test palette copying. */ + memset(table1, 0, sizeof(table1)); + table1[0].peBlue = 1; + hr = IDirectDraw7_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &src_palette, NULL); + ok(SUCCEEDED(hr), "Failed to create source palette, hr %#x.\n", hr); + table1[0].peBlue = 3; + hr = IDirectDraw7_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &dst_palette, NULL); + ok(SUCCEEDED(hr), "Failed to create destination palette, hr %#x.\n", hr); + + hr = IDirectDrawSurface7_SetPalette(src_surface, src_palette); + ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr); + + hr = IDirect3DDevice7_Load(device, dst_surface, NULL, src_surface, NULL, 0); + ok(SUCCEEDED(hr), "Failed to load texture, hr %#x.\n", hr); + + hr = IDirectDrawSurface7_GetPalette(surface, &palette); + ok(hr == DDERR_NOPALETTEATTACHED, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_GetPalette(dst_surface, &palette); + ok(hr == DDERR_NOPALETTEATTACHED, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDrawSurface7_SetPalette(surface, src_palette); + ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_SetPalette(dst_surface, dst_palette); + ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr); + + hr = IDirect3DDevice7_Load(device, dst_surface, NULL, src_surface, NULL, 0); + ok(SUCCEEDED(hr), "Failed to load texture, hr %#x.\n", hr); + + hr = IDirectDrawSurface7_GetPalette(dst_surface, &palette); + ok(SUCCEEDED(hr), "Failed to get palette, hr %#x.\n", hr); + ok(palette == dst_palette, "Got unexpected palette %p, expected %p.\n", palette, dst_palette); + memset(table1, 0, sizeof(table1)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 0, 256, table1); + ok(SUCCEEDED(hr), "Failed to retrieve palette entries, hr %#x.\n", hr); + ok(table1[0].peBlue == 1, "Got unexpected palette colour %#x.\n", (unsigned int)table1[0].peBlue); + IDirectDrawPalette_Release(palette); + + IDirectDrawPalette_Release(dst_palette); + IDirectDrawPalette_Release(src_palette); + + /* Test colour-key copying. */ + colour_key.dwColorSpaceLowValue = 32; + colour_key.dwColorSpaceHighValue = 64; + hr = IDirectDrawSurface7_SetColorKey(src_surface, DDCKEY_SRCBLT, &colour_key); + ok(SUCCEEDED(hr), "Failed to set colour-key, hr %#x.\n", hr); + hr = IDirectDrawSurface7_SetColorKey(surface, DDCKEY_SRCBLT, &colour_key); + ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDrawSurface7_GetColorKey(dst_surface, DDCKEY_SRCBLT, &colour_key); + ok(hr == DDERR_NOCOLORKEY, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice7_Load(device, dst_surface, NULL, src_surface, NULL, 0); + ok(SUCCEEDED(hr), "Failed to load texture, hr %#x.\n", hr); + + hr = IDirectDrawSurface7_GetColorKey(dst_surface, DDCKEY_SRCBLT, &colour_key); + ok(SUCCEEDED(hr), "Failed to get colour-key, hr %#x.\n", hr); + ok(colour_key.dwColorSpaceLowValue == 32, "Got unexpected value %u.\n", colour_key.dwColorSpaceLowValue); + ok(colour_key.dwColorSpaceHighValue == 32, "Got unexpected value %u.\n", colour_key.dwColorSpaceHighValue); + + IDirectDrawSurface7_Release(surface); + IDirectDrawSurface7_Release(dst_surface); + IDirectDrawSurface7_Release(src_surface); + + IDirectDraw7_Release(ddraw); + refcount = IDirect3DDevice7_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -14402,4 +14883,5 @@ START_TEST(ddraw7) test_clear(); test_enum_surfaces(); test_viewport(); + test_device_load(); }