ddraw/tests: Run test_depth_blit() 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:33:58 +03:00 committed by Alexandre Julliard
parent ff6bf06ce3
commit a63716af13
3 changed files with 210 additions and 121 deletions

View File

@ -360,6 +360,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(hr == DD_OK, "Got unexpected 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(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
}
static void check_rect(IDirectDrawSurface *surface, RECT r, const char *message)
{
LONG x_coords[2][2] =
@ -461,6 +484,8 @@ static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWOR
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;
@ -496,6 +521,8 @@ static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWOR
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;
@ -1263,7 +1290,7 @@ static void test_coop_level_threaded(void)
IDirectDraw2_Release(ddraw);
}
static void test_depth_blit(void)
static void test_depth_blit(const GUID *device_guid)
{
static D3DLVERTEX quad1[] =
{
@ -1283,6 +1310,7 @@ static void test_depth_blit(void)
IDirect3DDevice2 *device;
IDirectDrawSurface *ds1, *ds2, *ds3, *rt;
BOOL depth_fill_broken = FALSE;
IDirect3DViewport2 *viewport;
RECT src_rect, dst_rect;
unsigned int i, j;
@ -1297,7 +1325,7 @@ static void test_depth_blit(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);
@ -1312,8 +1340,10 @@ static void test_depth_blit(void)
memset(&ddsd_existing, 0, sizeof(ddsd_existing));
ddsd_existing.dwSize = sizeof(ddsd_existing);
hr = IDirectDrawSurface_GetSurfaceDesc(ds1, &ddsd_existing);
ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ddsd_new.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
if (is_software_device_type(device_guid))
ddsd_new.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
ddsd_new.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd_new.dwWidth = ddsd_existing.dwWidth;
ddsd_new.dwHeight = ddsd_existing.dwHeight;
@ -1393,28 +1423,44 @@ static void test_depth_blit(void)
fx.dwSize = sizeof(fx);
U5(fx).dwFillDepth = 0;
hr = IDirectDrawSurface_Blt(ds2, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to clear the source z buffer, hr %#x.\n", hr);
ok(hr == D3D_OK || broken(is_software_device_type(device_guid)
&& hr == 0x8876086c /* D3DERR_INVALIDCALL */), "Got unexpected hr %#x.\n", hr);
if (hr != D3D_OK)
depth_fill_broken = TRUE;
/* This clears the Z buffer with 1.0 */
hr = IDirect3DViewport2_Clear(viewport, 1, &d3drect, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear the color and z buffers, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_GetRenderTarget(device, &rt);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 80, 60);
/* For some reason clears and colour fill blits randomly fail with software render target. */
ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color),
"Got unexpected colour 0x%08x.\n", color);
if (!color)
{
fill_surface(rt, 0xffff0000);
color = get_surface_color(rt, 80, 60);
ok(color == 0x00ff0000, "Got unexpected colour 0x%08x.\n", color);
}
SetRect(&dst_rect, 0, 0, 320, 240);
hr = IDirectDrawSurface_Blt(ds1, &dst_rect, ds2, NULL, DDBLT_WAIT, NULL);
ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface_Release(ds3);
IDirectDrawSurface_Release(ds2);
IDirectDrawSurface_Release(ds1);
hr = IDirect3DDevice2_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to start a scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_LVERTEX, quad1, 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 a scene, 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);
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
@ -1422,7 +1468,7 @@ static void test_depth_blit(void)
unsigned int x = 80 * ((2 * j) + 1);
unsigned int y = 60 * ((2 * i) + 1);
color = get_surface_color(rt, x, y);
ok(compare_color(color, expected_colors[i][j], 1),
ok(compare_color(color, expected_colors[i][j], 1) || broken(depth_fill_broken && color == 0x0000ff00),
"Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
}
}
@ -5491,29 +5537,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;
@ -15291,7 +15314,7 @@ START_TEST(ddraw2)
test_coop_level_d3d_state();
test_surface_interface_mismatch();
test_coop_level_threaded();
test_depth_blit();
run_for_each_device_type(test_depth_blit);
test_texture_load_ckey();
test_viewport_object();
test_zenable();

View File

@ -361,6 +361,29 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface4 *surface, UINT x, UINT y)
return color;
}
static void fill_surface(IDirectDrawSurface4 *surface, D3DCOLOR color)
{
DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)};
HRESULT hr;
unsigned int x, y;
DWORD *ptr;
hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL);
ok(hr == DD_OK, "Got unexpected 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 = IDirectDrawSurface4_Unlock(surface, NULL);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
}
static void check_rect(IDirectDrawSurface4 *surface, RECT r, const char *message)
{
LONG x_coords[2][2] =
@ -427,7 +450,7 @@ static IDirectDraw4 *create_ddraw(void)
return ddraw4;
}
static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid)
{
IDirectDrawSurface4 *surface, *ds;
IDirect3DDevice3 *device = NULL;
@ -447,6 +470,8 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
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;
@ -475,7 +500,7 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
}
memset(&z_fmt, 0, sizeof(z_fmt));
hr = IDirect3D3_EnumZBufferFormats(d3d3, &IID_IDirect3DHALDevice, enum_z_fmt, &z_fmt);
hr = IDirect3D3_EnumZBufferFormats(d3d3, device_guid, enum_z_fmt, &z_fmt);
if (FAILED(hr) || !z_fmt.dwSize)
{
IDirect3D3_Release(d3d3);
@ -487,6 +512,9 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
if (is_software_device_type(device_guid))
surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
U4(surface_desc).ddpfPixelFormat = z_fmt;
surface_desc.dwWidth = 640;
surface_desc.dwHeight = 480;
@ -509,7 +537,7 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
return NULL;
}
hr = IDirect3D3_CreateDevice(d3d3, &IID_IDirect3DHALDevice, surface, &device, NULL);
hr = IDirect3D3_CreateDevice(d3d3, device_guid, surface, &device, NULL);
IDirect3D3_Release(d3d3);
IDirectDrawSurface4_Release(surface);
if (FAILED(hr))
@ -518,6 +546,11 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
return device;
}
static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
{
return create_device_ex(window, coop_level, &IID_IDirect3DHALDevice);
}
static IDirect3DViewport3 *create_viewport(IDirect3DDevice3 *device, UINT x, UINT y, UINT w, UINT h)
{
IDirect3DViewport3 *viewport;
@ -1429,7 +1462,7 @@ static void test_coop_level_threaded(void)
IDirectDraw4_Release(ddraw);
}
static void test_depth_blit(void)
static void test_depth_blit(const GUID *device_guid)
{
static struct
{
@ -1466,7 +1499,7 @@ static void test_depth_blit(void)
D3DRECT d3drect;
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);
@ -1474,9 +1507,9 @@ static void test_depth_blit(void)
}
hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
ok(SUCCEEDED(hr), "Failed to get Direct3D3 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 DirectDraw4 interface, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirect3D3_Release(d3d);
ds1 = get_depth_stencil(device);
@ -1486,9 +1519,11 @@ static void test_depth_blit(void)
memset(&ddsd_existing, 0, sizeof(ddsd_existing));
ddsd_existing.dwSize = sizeof(ddsd_existing);
hr = IDirectDrawSurface4_GetSurfaceDesc(ds1, &ddsd_existing);
ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ddsd_new.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd_new.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
if (is_software_device_type(device_guid))
ddsd_new.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
ddsd_new.dwWidth = ddsd_existing.dwWidth;
ddsd_new.dwHeight = ddsd_existing.dwHeight;
U4(ddsd_new).ddpfPixelFormat = U4(ddsd_existing).ddpfPixelFormat;
@ -1565,27 +1600,41 @@ static void test_depth_blit(void)
memset(&fx, 0, sizeof(fx));
fx.dwSize = sizeof(fx);
hr = IDirectDrawSurface4_Blt(ds2, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to clear the source z buffer, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 1, &d3drect, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear the color and z buffers, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 80, 60);
/* For some reason clears and colour fill blits randomly fail with software render target. */
ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color),
"Got unexpected colour 0x%08x.\n", color);
if (!color)
{
fill_surface(rt, 0xffff0000);
color = get_surface_color(rt, 80, 60);
ok(color == 0x00ff0000, "Got unexpected colour 0x%08x.\n", color);
}
SetRect(&dst_rect, 0, 0, 320, 240);
hr = IDirectDrawSurface4_Blt(ds1, &dst_rect, ds2, NULL, DDBLT_WAIT, NULL);
ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface4_Release(ds3);
IDirectDrawSurface4_Release(ds2);
IDirectDrawSurface4_Release(ds1);
hr = IDirect3DDevice3_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to start a scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE,
quad1, 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 a scene, 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);
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
@ -7151,29 +7200,6 @@ static void test_surface_discard(void)
DestroyWindow(window);
}
static void fill_surface(IDirectDrawSurface4 *surface, D3DCOLOR color)
{
DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)};
HRESULT hr;
unsigned int x, y;
DWORD *ptr;
hr = IDirectDrawSurface4_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 = IDirectDrawSurface4_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;
@ -18326,7 +18352,7 @@ START_TEST(ddraw4)
test_coop_level_d3d_state();
test_surface_interface_mismatch();
test_coop_level_threaded();
test_depth_blit();
run_for_each_device_type(test_depth_blit);
test_texture_load_ckey();
test_viewport_object();
test_zenable();

View File

@ -388,6 +388,29 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface7 *surface, UINT x, UINT y)
return color;
}
static void fill_surface(IDirectDrawSurface7 *surface, D3DCOLOR color)
{
DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)};
HRESULT hr;
unsigned int x, y;
DWORD *ptr;
hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL);
ok(hr == DD_OK, "Got unexpected 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 = IDirectDrawSurface7_Unlock(surface, NULL);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
}
#define check_rect(a, b, c) check_rect_(__LINE__, a, b, c)
static void check_rect_(unsigned int line, IDirectDrawSurface7 *surface, RECT r, const char *message)
{
@ -459,7 +482,7 @@ static HRESULT WINAPI enum_devtype_cb(char *desc_str, char *name, D3DDEVICEDESC7
return DDENUMRET_OK;
}
static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid)
{
IDirectDrawSurface7 *surface, *ds;
IDirect3DDevice7 *device = NULL;
@ -468,8 +491,6 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
IDirectDraw7 *ddraw;
IDirect3D7 *d3d7;
HRESULT hr;
BOOL hal_ok = FALSE;
const GUID *devtype = &IID_IDirect3DHALDevice;
if (!(ddraw = create_ddraw()))
return NULL;
@ -481,6 +502,8 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
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;
@ -508,12 +531,8 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
return NULL;
}
hr = IDirect3D7_EnumDevices(d3d7, enum_devtype_cb, &hal_ok);
ok(SUCCEEDED(hr), "Failed to enumerate devices, hr %#x.\n", hr);
if (hal_ok) devtype = &IID_IDirect3DTnLHalDevice;
memset(&z_fmt, 0, sizeof(z_fmt));
hr = IDirect3D7_EnumZBufferFormats(d3d7, devtype, enum_z_fmt, &z_fmt);
hr = IDirect3D7_EnumZBufferFormats(d3d7, device_guid, enum_z_fmt, &z_fmt);
if (FAILED(hr) || !z_fmt.dwSize)
{
IDirect3D7_Release(d3d7);
@ -525,6 +544,8 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
if (is_software_device_type(device_guid))
surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
U4(surface_desc).ddpfPixelFormat = z_fmt;
surface_desc.dwWidth = 640;
surface_desc.dwHeight = 480;
@ -547,7 +568,7 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
return NULL;
}
hr = IDirect3D7_CreateDevice(d3d7, devtype, surface, &device);
hr = IDirect3D7_CreateDevice(d3d7, device_guid, surface, &device);
IDirect3D7_Release(d3d7);
IDirectDrawSurface7_Release(surface);
if (FAILED(hr))
@ -556,6 +577,31 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
return device;
}
static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
{
const GUID *device_guid = &IID_IDirect3DHALDevice;
IDirectDraw7 *ddraw;
BOOL hal_ok = FALSE;
IDirect3D7 *d3d7;
HRESULT hr;
if (!(ddraw = create_ddraw()))
return NULL;
hr = IDirectDraw7_QueryInterface(ddraw, &IID_IDirect3D7, (void **)&d3d7);
IDirectDraw7_Release(ddraw);
if (FAILED(hr))
return NULL;
hr = IDirect3D7_EnumDevices(d3d7, enum_devtype_cb, &hal_ok);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
if (hal_ok)
device_guid = &IID_IDirect3DTnLHalDevice;
IDirect3D7_Release(d3d7);
return create_device_ex(window, coop_level, device_guid);
}
struct message
{
UINT message;
@ -1391,7 +1437,7 @@ static void test_coop_level_threaded(void)
IDirectDraw7_Release(ddraw);
}
static void test_depth_blit(void)
static void test_depth_blit(const GUID *device_guid)
{
IDirect3DDevice7 *device;
static struct
@ -1426,7 +1472,7 @@ static void test_depth_blit(void)
HWND window;
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);
@ -1446,9 +1492,11 @@ static void test_depth_blit(void)
memset(&ddsd_existing, 0, sizeof(ddsd_existing));
ddsd_existing.dwSize = sizeof(ddsd_existing);
hr = IDirectDrawSurface7_GetSurfaceDesc(ds1, &ddsd_existing);
ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ddsd_new.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd_new.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
if (is_software_device_type(device_guid))
ddsd_new.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
ddsd_new.dwWidth = ddsd_existing.dwWidth;
ddsd_new.dwHeight = ddsd_existing.dwHeight;
U4(ddsd_new).ddpfPixelFormat = U4(ddsd_existing).ddpfPixelFormat;
@ -1521,27 +1569,41 @@ static void test_depth_blit(void)
memset(&fx, 0, sizeof(fx));
fx.dwSize = sizeof(fx);
hr = IDirectDrawSurface7_Blt(ds2, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx);
ok(SUCCEEDED(hr), "Failed to clear the source z buffer, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear the color and z buffers, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 80, 60);
/* For some reason clears and colour fill blits randomly fail with software render target. */
ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color),
"Got unexpected colour 0x%08x.\n", color);
if (!color)
{
fill_surface(rt, 0xffff0000);
color = get_surface_color(rt, 80, 60);
ok(color == 0x00ff0000, "Got unexpected colour 0x%08x.\n", color);
}
SetRect(&dst_rect, 0, 0, 320, 240);
hr = IDirectDrawSurface7_Blt(ds1, &dst_rect, ds2, NULL, DDBLT_WAIT, NULL);
ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface7_Release(ds3);
IDirectDrawSurface7_Release(ds2);
IDirectDrawSurface7_Release(ds1);
hr = IDirect3DDevice7_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to start scene, hr %#x.\n", hr);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE,
quad1, 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);
hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
@ -1550,7 +1612,8 @@ static void test_depth_blit(void)
unsigned int y = 60 * ((2 * i) + 1);
color = get_surface_color(rt, x, y);
ok(compare_color(color, expected_colors[i][j], 1),
"Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
"Expected color 0x%08x at %u,%u, got 0x%08x, software device %#x.\n",
expected_colors[i][j], x, y, color, is_software_device_type(device_guid));
}
}
@ -6953,29 +7016,6 @@ static void test_surface_discard(void)
DestroyWindow(window);
}
static void fill_surface(IDirectDrawSurface7 *surface, D3DCOLOR color)
{
DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)};
HRESULT hr;
unsigned int x, y;
DWORD *ptr;
hr = IDirectDrawSurface7_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 = IDirectDrawSurface7_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;
@ -18601,7 +18641,7 @@ START_TEST(ddraw7)
test_coop_level_d3d_state();
test_surface_interface_mismatch();
test_coop_level_threaded();
test_depth_blit();
run_for_each_device_type(test_depth_blit);
test_texture_load_ckey();
test_zenable();
test_ck_rgba();