ddraw/tests: Run test_ck_rgba() for each device type.

Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2021-03-11 16:34:00 +03:00 committed by Alexandre Julliard
parent e68abb70df
commit 041ff96fce
4 changed files with 152 additions and 117 deletions

View file

@ -363,6 +363,29 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y)
return color;
}
static void fill_surface(IDirectDrawSurface *surface, D3DCOLOR color)
{
DDSURFACEDESC surface_desc = {sizeof(surface_desc)};
HRESULT hr;
unsigned int x, y;
DWORD *ptr;
hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL);
ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
for (y = 0; y < surface_desc.dwHeight; ++y)
{
ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch);
for (x = 0; x < surface_desc.dwWidth; ++x)
{
ptr[x] = color;
}
}
hr = IDirectDrawSurface_Unlock(surface, NULL);
ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
}
static void check_rect(IDirectDrawSurface *surface, RECT r, const char *message)
{
LONG x_coords[2][2] =
@ -630,6 +653,8 @@ static IDirect3DDevice *create_device_ex(IDirectDraw *ddraw, HWND window, DWORD
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
if (is_software_device_type(device_guid))
surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
surface_desc.dwWidth = 640;
surface_desc.dwHeight = 480;
@ -658,6 +683,8 @@ static IDirect3DDevice *create_device_ex(IDirectDraw *ddraw, HWND window, DWORD
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
if (is_software_device_type(device_guid))
surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
U2(surface_desc).dwZBufferBitDepth = z_depths[i];
surface_desc.dwWidth = 640;
surface_desc.dwHeight = 480;
@ -1704,7 +1731,7 @@ static void test_zenable(const GUID *device_guid)
DestroyWindow(window);
}
static void test_ck_rgba(void)
static void test_ck_rgba(const GUID *device_guid)
{
static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
static D3DTLVERTEX tquad[] =
@ -1775,7 +1802,7 @@ static void test_ck_rgba(void)
window = create_window();
ddraw = create_ddraw();
ok(!!ddraw, "Failed to create a ddraw object.\n");
if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid)))
{
skip("Failed to create a 3D device, skipping test.\n");
IDirectDraw_Release(ddraw);
@ -1791,6 +1818,8 @@ static void test_ck_rgba(void)
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
if (is_software_device_type(device_guid))
surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
surface_desc.dwWidth = 256;
surface_desc.dwHeight = 256;
surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
@ -1803,11 +1832,11 @@ static void test_ck_rgba(void)
surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00;
surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00;
hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DTexture, (void **)&texture);
ok(SUCCEEDED(hr), "Failed to get texture interface, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DTexture_GetHandle(texture, device, &texture_handle);
ok(SUCCEEDED(hr), "Failed to get texture handle, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirect3DTexture_Release(texture);
memset(&exec_desc, 0, sizeof(exec_desc));
@ -1816,10 +1845,10 @@ static void test_ck_rgba(void)
exec_desc.dwBufferSize = 1024;
exec_desc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
hr = IDirect3DDevice_CreateExecuteBuffer(device, &exec_desc, &execute_buffer, NULL);
ok(SUCCEEDED(hr), "Failed to create execute buffer, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
@ -1827,7 +1856,7 @@ static void test_ck_rgba(void)
void *ptr;
hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
memcpy(exec_desc.lpData, tquad, sizeof(tquad));
ptr = ((BYTE *)exec_desc.lpData) + sizeof(tquad);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 0, 4);
@ -1835,6 +1864,15 @@ static void test_ck_rgba(void)
emit_set_rs(&ptr, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
emit_set_rs(&ptr, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
emit_set_rs(&ptr, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key);
if (is_software_device_type(device_guid))
{
/* It looks like D3DRENDERSTATE_COLORKEYENABLE is ignored with software device
* on Windows and the colour key is always enabled if set on surface. */
IDirectDrawSurface_SetColorKey(surface, DDCKEY_SRCBLT, tests[i].color_key
? &surface_desc.ddckCKSrcBlt : NULL);
}
emit_set_rs(&ptr, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend);
emit_tquad(&ptr, 0);
emit_end(&ptr);
@ -1845,46 +1883,50 @@ static void test_ck_rgba(void)
emit_end(&ptr);
draw2_len = (BYTE *)ptr - (BYTE *)exec_desc.lpData - draw1_len;
hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
memset(&fx, 0, sizeof(fx));
fx.dwSize = sizeof(fx);
U5(fx).dwFillColor = tests[i].fill_color;
hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* RT clears are broken on Windows for software render target. */
if (is_software_device_type(device_guid))
fill_surface(rt, 0xffff0000);
hr = IDirect3DDevice_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
set_execute_data(execute_buffer, 8, sizeof(tquad), draw1_len);
hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice_EndScene(device);
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, tests[i].result1, 1)
ok(compare_color(color, tests[i].result1, 2)
|| broken(compare_color(color, tests[i].result1_r200, 1))
|| broken(compare_color(color, tests[i].result1_warp, 1)),
"Got unexpected color 0x%08x for test %u.\n", color, i);
U5(fx).dwFillColor = 0xff0000ff;
hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
set_execute_data(execute_buffer, 8, sizeof(tquad) + draw1_len, draw2_len);
hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice_EndScene(device);
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* This tests that fragments that are masked out by the color key are
* discarded, instead of just fully transparent. */
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, tests[i].result2, 1)
ok(compare_color(color, tests[i].result2, 2)
|| broken(compare_color(color, tests[i].result2_r200, 1))
|| broken(compare_color(color, tests[i].result2_warp, 1)),
"Got unexpected color 0x%08x for test %u.\n", color, i);
@ -4952,29 +4994,6 @@ static void test_surface_discard(void)
DestroyWindow(window);
}
static void fill_surface(IDirectDrawSurface *surface, D3DCOLOR color)
{
DDSURFACEDESC surface_desc = {sizeof(surface_desc)};
HRESULT hr;
unsigned int x, y;
DWORD *ptr;
hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL);
ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
for (y = 0; y < surface_desc.dwHeight; ++y)
{
ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch);
for (x = 0; x < surface_desc.dwWidth; ++x)
{
ptr[x] = color;
}
}
hr = IDirectDrawSurface_Unlock(surface, NULL);
ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
}
static void test_flip(void)
{
const DWORD placement = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
@ -14358,7 +14377,7 @@ START_TEST(ddraw1)
test_coop_level_threaded();
test_viewport_object();
run_for_each_device_type(test_zenable);
test_ck_rgba();
run_for_each_device_type(test_ck_rgba);
test_ck_default();
test_ck_complex();
test_surface_qi();

View file

@ -1915,7 +1915,7 @@ static void test_zenable(const GUID *device_guid)
DestroyWindow(window);
}
static void test_ck_rgba(void)
static void test_ck_rgba(const GUID *device_guid)
{
static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
static D3DTLVERTEX tquad[] =
@ -1969,7 +1969,7 @@ static void test_ck_rgba(void)
window = create_window();
ddraw = create_ddraw();
ok(!!ddraw, "Failed to create a ddraw object.\n");
if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid)))
{
skip("Failed to create a 3D device, skipping test.\n");
IDirectDraw2_Release(ddraw);
@ -1981,12 +1981,14 @@ static void test_ck_rgba(void)
viewport = create_viewport(device, 0, 0, 640, 480);
viewport_set_background(device, viewport, background);
hr = IDirect3DDevice2_SetCurrentViewport(device, viewport);
ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
if (is_software_device_type(device_guid))
surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
surface_desc.dwWidth = 256;
surface_desc.dwHeight = 256;
surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
@ -1999,72 +2001,76 @@ static void test_ck_rgba(void)
surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00;
surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00;
hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DTexture2, (void **)&texture);
ok(SUCCEEDED(hr), "Failed to get texture interface, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DTexture2_GetHandle(texture, device, &texture_handle);
ok(SUCCEEDED(hr), "Failed to get texture handle, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirect3DTexture2_Release(texture);
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle);
ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key);
ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
memset(&fx, 0, sizeof(fx));
fx.dwSize = sizeof(fx);
U5(fx).dwFillColor = tests[i].fill_color;
hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* RT clears are broken on Windows for software render target. */
if (is_software_device_type(device_guid))
fill_surface(rt, 0xffff0000);
hr = IDirect3DDevice2_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_TLVERTEX, &tquad[0], 4, 0);
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_EndScene(device);
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
ok(compare_color(color, tests[i].result1, 2) || compare_color(color, tests[i].result1_broken, 1),
"Expected color 0x%08x for test %u, got 0x%08x.\n",
tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff;
hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_TLVERTEX, &tquad[4], 4, 0);
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_EndScene(device);
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* This tests that fragments that are masked out by the color key are
* discarded, instead of just fully transparent. */
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
ok(compare_color(color, tests[i].result2, 2) || compare_color(color, tests[i].result2_broken, 1),
"Expected color 0x%08x for test %u, got 0x%08x.\n",
tests[i].result2, i, color);
}
IDirectDrawSurface_Release(rt);
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_TEXTUREHANDLE, 0);
ok(SUCCEEDED(hr), "Failed to unset texture, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface_Release(surface);
destroy_viewport(device, viewport);
destroy_material(background);
@ -15332,7 +15338,7 @@ START_TEST(ddraw2)
test_texture_load_ckey();
test_viewport_object();
run_for_each_device_type(test_zenable);
test_ck_rgba();
run_for_each_device_type(test_ck_rgba);
test_ck_default();
test_ck_complex();
test_surface_qi();

View file

@ -2153,7 +2153,7 @@ static void test_zenable(const GUID *device_guid)
DestroyWindow(window);
}
static void test_ck_rgba(void)
static void test_ck_rgba(const GUID *device_guid)
{
static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
static struct
@ -2209,7 +2209,7 @@ static void test_ck_rgba(void)
UINT i;
window = create_window();
if (!(device = create_device(window, DDSCL_NORMAL)))
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
{
skip("Failed to create a 3D device, skipping test.\n");
DestroyWindow(window);
@ -2218,18 +2218,20 @@ static void test_ck_rgba(void)
viewport = create_viewport(device, 0, 0, 640, 480);
hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw);
ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirect3D3_Release(d3d);
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
if (is_software_device_type(device_guid))
surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
surface_desc.dwWidth = 256;
surface_desc.dwHeight = 256;
U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
@ -2242,63 +2244,65 @@ static void test_ck_rgba(void)
surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00;
surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00;
hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface4_QueryInterface(surface, &IID_IDirect3DTexture2, (void **)&texture);
ok(SUCCEEDED(hr), "Failed to get texture interface, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_SetTexture(device, 0, texture);
ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key);
ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
memset(&fx, 0, sizeof(fx));
fx.dwSize = sizeof(fx);
U5(fx).dwFillColor = tests[i].fill_color;
hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
if (is_software_device_type(device_guid))
fill_surface(rt, 0xffff0000);
hr = IDirect3DDevice3_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0);
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_EndScene(device);
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
ok(compare_color(color, tests[i].result1, 2) || compare_color(color, tests[i].result1_broken, 1),
"Expected color 0x%08x for test %u, got 0x%08x.\n",
tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff;
hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[4], 4, 0);
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_EndScene(device);
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* This tests that fragments that are masked out by the color key are
* discarded, instead of just fully transparent. */
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
ok(compare_color(color, tests[i].result2, 2) || compare_color(color, tests[i].result2_broken, 1),
"Expected color 0x%08x for test %u, got 0x%08x.\n",
tests[i].result2, i, color);
}
@ -18370,7 +18374,7 @@ START_TEST(ddraw4)
test_texture_load_ckey();
test_viewport_object();
run_for_each_device_type(test_zenable);
test_ck_rgba();
run_for_each_device_type(test_ck_rgba);
test_ck_default();
test_ck_complex();
test_surface_qi();

View file

@ -1784,7 +1784,7 @@ static void test_zenable(const GUID *device_guid)
DestroyWindow(window);
}
static void test_ck_rgba(void)
static void test_ck_rgba(const GUID *device_guid)
{
static struct
{
@ -1837,7 +1837,7 @@ static void test_ck_rgba(void)
UINT i;
window = create_window();
if (!(device = create_device(window, DDSCL_NORMAL)))
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
{
skip("Failed to create a 3D device, skipping test.\n");
DestroyWindow(window);
@ -1845,15 +1845,17 @@ static void test_ck_rgba(void)
}
hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirect3D7_Release(d3d);
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
if (is_software_device_type(device_guid))
surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
surface_desc.dwWidth = 256;
surface_desc.dwHeight = 256;
U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
@ -1866,60 +1868,64 @@ static void test_ck_rgba(void)
surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00;
surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00;
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &texture, NULL);
ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetTexture(device, 0, texture);
ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key);
ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend);
ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
memset(&fx, 0, sizeof(fx));
fx.dwSize = sizeof(fx);
U5(fx).dwFillColor = tests[i].fill_color;
hr = IDirectDrawSurface7_Blt(texture, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* RT clears are broken on Windows for software render target. */
if (is_software_device_type(device_guid))
fill_surface(rt, 0xffff0000);
hr = IDirect3DDevice7_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0);
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_EndScene(device);
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
ok(compare_color(color, tests[i].result1, 2) || compare_color(color, tests[i].result1_broken, 1),
"Expected color 0x%08x for test %u, got 0x%08x.\n",
tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff;
hr = IDirectDrawSurface7_Blt(texture, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[4], 4, 0);
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_EndScene(device);
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* This tests that fragments that are masked out by the color key are
* discarded, instead of just fully transparent. */
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
ok(compare_color(color, tests[i].result2, 2) || compare_color(color, tests[i].result2_broken, 1),
"Expected color 0x%08x for test %u, got 0x%08x.\n",
tests[i].result2, i, color);
}
@ -18658,7 +18664,7 @@ START_TEST(ddraw7)
run_for_each_device_type(test_depth_blit);
test_texture_load_ckey();
run_for_each_device_type(test_zenable);
test_ck_rgba();
run_for_each_device_type(test_ck_rgba);
test_ck_default();
test_ck_complex();
test_surface_qi();