Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- I cleaned up the code style a little, but left the behavior of the code alone as much as possible. --- dlls/ddraw/tests/d3d.c | 1058 ------------------------------------ dlls/ddraw/tests/ddraw7.c | 1088 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1088 insertions(+), 1058 deletions(-)
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c index 77836fd627..ec0f8d715c 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 35a45c0345..4a7ea61f5d 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -14267,6 +14267,1093 @@ static void test_viewport(void) DestroyWindow(window); }
+#define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) ) + +static void test_device_load(void) +{ + HWND window; + IDirect3DDevice7 *device; + IDirect3D7 *d3d; + IDirectDraw7 *ddraw; + 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 int diff_count, diff_count2; + unsigned int x, y; + BOOL load_mip_subset_broken = FALSE; + IDirectDrawPalette *palettes[5]; + PALETTEENTRY table1[256]; + DDCOLORKEY ddckey; + D3DDEVICEDESC7 d3dcaps; + ULONG refcount; + + 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); + + /* 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(ddraw, &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 *texture_row = (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; + *texture_row++ = 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(device, 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(device, 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(device, 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 *texture_row = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); + + for (x = 0; x < ddsd.dwWidth; x++) + { + DWORD color = *texture_row++; + DWORD r = (color & 0xff0000) >> 16; + DWORD g = (color & 0xff00) >> 8; + DWORD b = (color & 0xff); + + 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 + { + 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 + { + 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(device, 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(ddraw, &ddsd, &texture_levels[i][0], NULL); + ok(hr==DD_OK, "CreateSurface returned: %x\n", hr); + if (FAILED(hr)) goto out; + } + + hr = IDirect3DDevice7_Load(device, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0); + ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n", hr); + + hr = IDirect3DDevice7_Load(device, 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(device, &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(ddraw, &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 *texture_row = (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; + *texture_row++ = 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(device, 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 *texture_row = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); + + for (x = 0; x < ddsd.dwWidth; x++) + { + DWORD color = *texture_row++; + DWORD r = (color & 0xff0000) >> 16; + DWORD g = (color & 0xff00) >> 8; + DWORD b = (color & 0xff); + + 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 + { + 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 + { + 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(ddraw, &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(ddraw, &ddsd, &texture_levels[0][0], NULL); + ok(hr==DD_OK, "CreateSurface returned: %x\n", hr); + if (FAILED(hr)) goto out; + + hr = IDirect3DDevice7_Load(device, 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(ddraw, &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 *texture_row = (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; + *texture_row++ = 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(device, 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 *texture_row = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); + + for (x = 0; x < ddsd.dwWidth; x++) + { + DWORD color = *texture_row++; + DWORD r = (color & 0xff0000) >> 16; + DWORD g = (color & 0xff00) >> 8; + DWORD b = (color & 0xff); + + 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 + { + 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 + { + 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(device, 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(ddraw, &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(ddraw, &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 *texture_row = (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; + *texture_row++ = 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(device, 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 *texture_row = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); + + for (x = 0; x < ddsd.dwWidth; x++) + { + DWORD color = *texture_row++; + + 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 Windows installations like XP). Skipping affected tests.\n"); + } else { + diff_count = 0; + + for (y = 0; y < ddsd.dwHeight; y++) + { + DWORD *texture_row = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); + + for (x = 0; x < ddsd.dwWidth; x++) + { + DWORD color = *texture_row++; + + 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 != 0xf2 || 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(ddraw, &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 *texture_row = (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; + *texture_row++ = 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(device, 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 *texture_row = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch); + + for (x = 0; x < ddsd.dwWidth; x++) + { + DWORD color = *texture_row++; + + 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(ddraw, &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(ddraw, 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(device, 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(device, 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(device, 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]); + } + } + } + + 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 +15489,5 @@ START_TEST(ddraw7) test_clear(); test_enum_surfaces(); test_viewport(); + test_device_load(); }
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ddraw/tests/ddraw7.c | 64 ++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 14 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 4a7ea61f5d..3cb3516906 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -14284,7 +14284,7 @@ static void test_device_load(void) RECT loadrect; POINT loadpoint; int i, i1, i2; - unsigned int diff_count, diff_count2; + unsigned int diff_count, diff_count2, diff_count3; unsigned int x, y; BOOL load_mip_subset_broken = FALSE; IDirectDrawPalette *palettes[5]; @@ -14825,6 +14825,7 @@ static void test_device_load(void) { diff_count = 0; diff_count2 = 0; + diff_count3 = 0;
memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); ddsd.dwSize = sizeof(ddsd); @@ -14866,15 +14867,26 @@ static void test_device_load(void) if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) || !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++; } + + /* some windows 8 and 10 machines copy the wrong mip */ + if (x < loadpoint.x / 16 || x >= ceil((loadpoint.x + loadrect.right - loadrect.left) / 16.0) || + y < loadpoint.y / 16 || y >= ceil((loadpoint.y + loadrect.bottom - loadrect.top) / 16.0)) + { + if (color & 0xffffff) diff_count3++; + } + else + { + if (r != (0xf0 | (i1 + 4)) || g != x || b != y) diff_count3++; + } } }
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, + ok(diff_count == 0 || diff_count2 == 0 || broken(diff_count3 == 0), "Unexpected destination texture level pixels; %u differences at %d level\n", - min(diff_count, diff_count2), i1); + min(min(diff_count, diff_count2), diff_count3), i1);
loadpoint.x /= 2; loadpoint.y /= 2; @@ -15027,6 +15039,7 @@ static void test_device_load(void) skip("IDirect3DDevice7_Load is broken (happens on some Windows installations like XP). Skipping affected tests.\n"); } else { diff_count = 0; + diff_count3 = 0;
for (y = 0; y < ddsd.dwHeight; y++) { @@ -15035,6 +15048,9 @@ static void test_device_load(void) for (x = 0; x < ddsd.dwWidth; x++) { DWORD color = *texture_row++; + DWORD r = (color & 0xff0000) >> 16; + DWORD g = (color & 0xff00) >> 8; + DWORD b = (color & 0xff);
if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top) @@ -15043,13 +15059,20 @@ static void test_device_load(void) } else { - DWORD r = (color & 0xff0000) >> 16; - DWORD g = (color & 0xff00) >> 8; - DWORD b = (color & 0xff); - if (r != 0xf2 || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++; } + + /* some windows 8 and 10 machines copy the wrong mip */ + if (x < loadpoint.x / 16 || x >= (loadpoint.x + loadrect.right - loadrect.left) / 16 || + y < loadpoint.y / 16 || y >= (loadpoint.y + loadrect.bottom - loadrect.top) / 16) + { + if (color & 0xffffff) diff_count3++; + } + else + { + if (r != 0xf7 || g != x || b != y) diff_count3++; + } } } } @@ -15057,7 +15080,8 @@ static void test_device_load(void) 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); + ok(diff_count == 0 || broken(diff_count3 == 0), + "Unexpected destination texture level pixels; %u differences\n", min(diff_count, diff_count3));
for (i = 0; i < 2; i++) { @@ -15170,6 +15194,7 @@ static void test_device_load(void) if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight) { diff_count = 0; + diff_count3 = 0;
memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); ddsd.dwSize = sizeof(ddsd); @@ -15184,6 +15209,9 @@ static void test_device_load(void) for (x = 0; x < ddsd.dwWidth; x++) { DWORD color = *texture_row++; + DWORD r = (color & 0xff0000) >> 16; + DWORD g = (color & 0xff00) >> 8; + DWORD b = (color & 0xff);
if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left || y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top) @@ -15192,21 +15220,29 @@ static void test_device_load(void) } 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++; } + + /* some windows 8 and 10 machines copy the wrong mip */ + if (x < loadpoint.x / 16 || x >= ceil((loadpoint.x + loadrect.right - loadrect.left) / 16.0) || + y < loadpoint.y / 16 || y >= ceil((loadpoint.y + loadrect.bottom - loadrect.top) / 16.0)) + { + if (color & 0xffffff) diff_count3++; + } + else + { + if (r != (0xf0 | (i + 4)) || g != x || b != y) diff_count3++; + } } }
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); + ok(diff_count == 0 || broken(diff_count3 == 0), + "Unexpected destination texture level pixels; %u differences at %d level\n", + min(diff_count, diff_count3), i1);
i++; }
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=40084
Your paranoid android.
=== w8 (32 bit ddraw7) === ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 2031 differences at 0 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 518 differences at 1 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 138 differences at 2 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 46 differences at 3 level ddraw7.c:15060: Test failed: Unexpected destination texture level pixels; 257 differences ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 256 differences at 2 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 64 differences at 3 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 16 differences at 4 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 4 differences at 5 level
=== w8adm (32 bit ddraw7) === ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 2031 differences at 0 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 518 differences at 1 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 138 differences at 2 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 46 differences at 3 level ddraw7.c:15060: Test failed: Unexpected destination texture level pixels; 257 differences ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 256 differences at 2 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 64 differences at 3 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 16 differences at 4 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 4 differences at 5 level
=== w864 (32 bit ddraw7) === ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 2031 differences at 0 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 518 differences at 1 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 138 differences at 2 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 46 differences at 3 level ddraw7.c:15060: Test failed: Unexpected destination texture level pixels; 257 differences ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 256 differences at 2 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 64 differences at 3 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 16 differences at 4 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 4 differences at 5 level
=== w1064 (32 bit ddraw7) === ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 2031 differences at 0 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 518 differences at 1 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 138 differences at 2 level ddraw7.c:14875: Test failed: Unexpected destination texture level pixels; 46 differences at 3 level ddraw7.c:15060: Test failed: Unexpected destination texture level pixels; 257 differences ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 256 differences at 2 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 64 differences at 3 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 16 differences at 4 level ddraw7.c:15208: Test failed: Unexpected destination texture level pixels; 4 differences at 5 level