Commit 2470b0e4 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

ddraw/tests: Rewrite DeviceLoadTest().

Based on a patch by Alex Henrie. Signed-off-by: 's avatarHenri Verbeet <hverbeet@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 5e3866cb
......@@ -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();
......
......@@ -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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment