Based on a patch by Alex Henrie.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
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();
}
--
2.11.0