From: Paul Gofman Subject: [PATCH v2 4/6] ddraw/tests: Run test_depth_blit() for each device type. Message-Id: <20210225232014.988118-4-pgofman@codeweavers.com> Date: Fri, 26 Feb 2021 02:20:12 +0300 In-Reply-To: <20210225232014.988118-1-pgofman@codeweavers.com> References: <20210225232014.988118-1-pgofman@codeweavers.com> Signed-off-by: Paul Gofman --- dlls/ddraw/tests/ddraw2.c | 98 ++++++++++++++++++----------- dlls/ddraw/tests/ddraw4.c | 106 +++++++++++++++++++------------ dlls/ddraw/tests/ddraw7.c | 129 +++++++++++++++++++++++++------------- 3 files changed, 211 insertions(+), 122 deletions(-) diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index b882589f2ad..a04b1a2967f 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -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 == DD_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 == DD_OK || broken(is_software_device_type(device_guid) + && hr == 0x8876086c /* D3DERR_INVALIDCALL */), "Got unexpected hr %#x.\n", hr); + if (hr != DD_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 == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice2_GetRenderTarget(device, &rt); + ok(hr == DD_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 %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\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 == DD_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 == DD_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 == DD_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 == DD_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); } } @@ -5040,7 +5086,8 @@ static void test_rt_caps(const GUID *device_guid) todo_wine_if(test_data[i].caps_out[0] == ~0u && surface_desc.ddsCaps.dwCaps != expected_caps) ok(surface_desc.ddsCaps.dwCaps == expected_caps - || surface_desc.ddsCaps.dwCaps == test_data[i].caps_out[0], + || surface_desc.ddsCaps.dwCaps == test_data[i].caps_out[0] + || test_data[i].caps_out[0] == ~0u, "Got unexpected caps %#x, test %u, software_device %u.\n", surface_desc.ddsCaps.dwCaps, i, software_device); } @@ -5515,29 +5562,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; @@ -15315,7 +15339,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(); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 42936fd7c74..569af353397 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -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 == DD_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 == DD_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 == DD_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 == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice3_GetRenderTarget(device, &rt); + ok(hr == DD_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 == DD_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 %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\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 == DD_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 == DD_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 == DD_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 == DD_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) @@ -7199,29 +7248,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; @@ -18374,7 +18400,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(); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 7e83d26d6db..639b3ca6252 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -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 == DD_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 == DD_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 == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice7_GetRenderTarget(device, &rt); + ok(hr == DD_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 %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\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 == DD_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 == DD_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 == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_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,7 @@ 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)); } } @@ -7000,29 +7062,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; @@ -18648,7 +18687,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(); -- 2.29.2