[PATCH v2 06/10] ddraw/tests: Run test_depth_blit() for each device type.

Paul Gofman pgofman at codeweavers.com
Tue Mar 9 03:56:43 CST 2021


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
v2:
    - no changes.

 dlls/ddraw/tests/ddraw2.c |  95 +++++++++++++++++-----------
 dlls/ddraw/tests/ddraw4.c | 106 +++++++++++++++++++------------
 dlls/ddraw/tests/ddraw7.c | 129 +++++++++++++++++++++++++-------------
 3 files changed, 209 insertions(+), 121 deletions(-)

diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 98beaaf8cba..3bb3407c5c3 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);
         }
     }
@@ -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();
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 1801ef2d2e2..e7d61da1b14 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)
@@ -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();
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index cba5cb4be2a..c0cbd077ae4 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));
         }
     }
 
@@ -6953,29 +7015,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 +18640,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




More information about the wine-devel mailing list