[PATCH 2/5] ddraw/tests: Add a DDBLT_COLORFILL test.

Stefan Dösinger stefan at codeweavers.com
Mon Mar 16 08:48:53 CDT 2015


A port to ddraw1-4 will follow. There are no surprises in earlier
versions.
---
 dlls/ddraw/tests/ddraw7.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 340 insertions(+)

diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 13eb004..d08dd8e 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -8520,6 +8520,345 @@ done:
     DestroyWindow(window);
 }
 
+static void test_color_fill(void)
+{
+    HRESULT hr;
+    IDirect3DDevice7 *device;
+    IDirect3D7 *d3d;
+    IDirectDraw7 *ddraw;
+    IDirectDrawSurface7 *surface, *surface2;
+    DDSURFACEDESC2 surface_desc;
+    DDPIXELFORMAT z_fmt;
+    ULONG refcount;
+    HWND window;
+    unsigned int i;
+    DDBLTFX fx;
+    RECT rect = {5, 5, 7, 7};
+    DWORD *color;
+    DWORD supported_fmts = 0, num_fourcc_codes, *fourcc_codes;
+    DDCAPS hal_caps;
+    static const struct
+    {
+        DWORD caps, caps2;
+        HRESULT hr;
+        const char *name;
+        DWORD result;
+        BOOL check_result;
+        DDPIXELFORMAT format;
+    }
+    tests[] =
+    {
+        {
+            DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY, 0,
+            DD_OK, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
+                {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
+            }
+        },
+        {
+            DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY, 0,
+            DD_OK, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
+                {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
+            }
+        },
+        {
+            DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, 0,
+            DD_OK, "vidmem texture RGB", 0xdeadbeef, TRUE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
+                {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
+            }
+        },
+        {
+            DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, 0,
+            DD_OK, "sysmem texture RGB", 0xdeadbeef, TRUE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
+                {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
+            }
+        },
+        {
+            DDSCAPS_TEXTURE, DDSCAPS2_TEXTUREMANAGE,
+            DD_OK, "managed texture RGB", 0xdeadbeef, TRUE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
+                {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
+            }
+        },
+        {
+            DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY, 0,
+            DDERR_INVALIDPARAMS, "vidmem zbuffer", 0, FALSE,
+            {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
+        },
+        {
+            DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY, 0,
+            DDERR_INVALIDPARAMS, "sysmem zbuffer", 0, FALSE,
+            {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
+        },
+        {
+            /* Colorfill on YUV surfaces always returns DD_OK, but the content is
+             * different afterwards. DX9+ GPUs set one of the two luminance values
+             * in each block, but AMD and Nvidia GPUs disagree on which luminance
+             * value they set. r200 (dx8) just sets the entire block to the clear
+             * value. */
+            DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY, 0,
+            DD_OK, "vidmem offscreenplain YUY2", 0, FALSE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y', 'U', 'Y', '2'),
+                {0}, {0}, {0}, {0}, {0}
+            }
+        },
+        {
+            DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY, 0,
+            DD_OK, "vidmem offscreenplain UYVY", 0, FALSE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U', 'Y', 'V', 'Y'),
+                {0}, {0}, {0}, {0}, {0}
+            }
+        },
+        {
+            DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY, 0,
+            DD_OK, "vidmem overlay YUY2", 0, FALSE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y', 'U', 'Y', '2'),
+                {0}, {0}, {0}, {0}, {0}
+            }
+        },
+        {
+            DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY, 0,
+            DD_OK, "vidmem overlay UYVY", 0, FALSE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U', 'Y', 'V', 'Y'),
+                {0}, {0}, {0}, {0}, {0}
+            }
+        },
+        {
+            DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, 0,
+            E_NOTIMPL, "vidmem texture DXT1", 0, FALSE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'),
+                {0}, {0}, {0}, {0}, {0}
+            }
+        },
+        {
+            DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, 0,
+            E_NOTIMPL, "sysmem texture DXT1", 0, FALSE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'),
+                {0}, {0}, {0}, {0}, {0}
+            }
+        },
+        {
+            /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
+             * surface works, presumably because it is handled by the runtime instead of
+             * the driver. */
+            DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY, 0,
+            DD_OK, "vidmem offscreenplain P8", 0xefefefef, FALSE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_PALETTEINDEXED8, 0,
+                {8}, {0}, {0}, {0}, {0}
+            }
+        },
+        {
+            DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY, 0,
+            DD_OK, "sysmem offscreenplain P8", 0xefefefef, TRUE,
+            {
+                sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_PALETTEINDEXED8, 0,
+                {8}, {0}, {0}, {0}, {0}
+            }
+        },
+    };
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+
+    if (!(device = create_device(window, DDSCL_NORMAL)))
+    {
+        skip("Failed to create a 3D device, skipping test.\n");
+        DestroyWindow(window);
+        return;
+    }
+
+    hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
+    ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
+    hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
+    ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
+
+    memset(&z_fmt, 0, sizeof(z_fmt));
+    IDirect3D7_EnumZBufferFormats(d3d, &IID_IDirect3DHALDevice, enum_z_fmt, &z_fmt);
+    if (!z_fmt.dwSize)
+        skip("No Z buffer formats supported, skipping Z buffer colorfill test.\n");
+
+    IDirect3DDevice7_EnumTextureFormats(device, test_block_formats_creation_cb, &supported_fmts);
+    if (!(supported_fmts & SUPPORT_DXT1))
+        skip("DXT1 textures not supported, skipping DXT1 colorfill test.\n");
+
+    IDirect3D7_Release(d3d);
+
+    hr = IDirectDraw7_GetFourCCCodes(ddraw, &num_fourcc_codes, NULL);
+    ok(SUCCEEDED(hr), "Failed to get fourcc codes %#x.\n", hr);
+    fourcc_codes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+            num_fourcc_codes * sizeof(*fourcc_codes));
+    if (!fourcc_codes)
+        goto done;
+    hr = IDirectDraw7_GetFourCCCodes(ddraw, &num_fourcc_codes, fourcc_codes);
+    ok(SUCCEEDED(hr), "Failed to get fourcc codes %#x.\n", hr);
+    for (i = 0; i < num_fourcc_codes; i++)
+    {
+        if (fourcc_codes[i] == MAKEFOURCC('Y', 'U', 'Y', '2'))
+            supported_fmts |= SUPPORT_YUY2;
+        else if (fourcc_codes[i] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
+            supported_fmts |= SUPPORT_UYVY;
+    }
+    HeapFree(GetProcessHeap(), 0, fourcc_codes);
+
+    memset(&hal_caps, 0, sizeof(hal_caps));
+    hal_caps.dwSize = sizeof(hal_caps);
+    hr = IDirectDraw7_GetCaps(ddraw, &hal_caps, NULL);
+    ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
+
+    if (!(supported_fmts & (SUPPORT_YUY2 | SUPPORT_UYVY)) || !(hal_caps.dwCaps & DDCAPS_OVERLAY))
+        skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
+
+    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+    {
+        /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
+        memset(&fx, 0, sizeof(fx));
+        fx.dwSize = sizeof(fx);
+        fx.dwFillColor = 0xdeadbeef;
+
+        memset(&surface_desc, 0, sizeof(surface_desc));
+        surface_desc.dwSize = sizeof(surface_desc);
+        surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+        surface_desc.dwWidth = 64;
+        surface_desc.dwHeight = 64;
+        U4(surface_desc).ddpfPixelFormat = tests[i].format;
+        surface_desc.ddsCaps.dwCaps = tests[i].caps;
+        surface_desc.ddsCaps.dwCaps2 = tests[i].caps2;
+
+        if (tests[i].format.dwFourCC == MAKEFOURCC('D','X','T','1') && !(supported_fmts & SUPPORT_DXT1))
+            continue;
+        if (tests[i].format.dwFourCC == MAKEFOURCC('Y','U','Y','2') && !(supported_fmts & SUPPORT_YUY2))
+            continue;
+        if (tests[i].format.dwFourCC == MAKEFOURCC('U','Y','V','Y') && !(supported_fmts & SUPPORT_UYVY))
+            continue;
+        if (tests[i].caps & DDSCAPS_OVERLAY && !(hal_caps.dwCaps & DDCAPS_OVERLAY))
+            continue;
+
+        if (tests[i].caps & DDSCAPS_ZBUFFER)
+        {
+            if (!z_fmt.dwSize)
+                continue;
+
+            U4(surface_desc).ddpfPixelFormat = z_fmt;
+        }
+
+        hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
+        ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, surface %s.\n", hr, tests[i].name);
+
+        hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+        if (tests[i].format.dwFourCC)
+            todo_wine ok(hr == tests[i].hr, "Blt returned %#x, expected %#x, surface %s.\n",
+                    hr, tests[i].hr, tests[i].name);
+        else
+            ok(hr == tests[i].hr, "Blt returned %#x, expected %#x, surface %s.\n",
+                    hr, tests[i].hr, tests[i].name);
+
+        hr = IDirectDrawSurface7_Blt(surface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+        if (tests[i].format.dwFourCC)
+            todo_wine ok(hr == tests[i].hr, "Blt returned %#x, expected %#x, surface %s.\n",
+                    hr, tests[i].hr, tests[i].name);
+        else
+            ok(hr == tests[i].hr, "Blt returned %#x, expected %#x, surface %s.\n",
+                    hr, tests[i].hr, tests[i].name);
+
+        if (SUCCEEDED(hr) && tests[i].check_result)
+        {
+            memset(&surface_desc, 0, sizeof(surface_desc));
+            surface_desc.dwSize = sizeof(surface_desc);
+            hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, 0);
+            ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, surface %s.\n", hr, tests[i].name);
+            color = surface_desc.lpSurface;
+            ok(*color == tests[i].result, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
+                    *color, tests[i].result, tests[i].name);
+            hr = IDirectDrawSurface7_Unlock(surface, NULL);
+            ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, surface %s.\n", hr, tests[i].name);
+        }
+
+        IDirectDrawSurface7_Release(surface);
+    }
+
+    memset(&surface_desc, 0, sizeof(surface_desc));
+    surface_desc.dwSize = sizeof(surface_desc);
+    surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+    surface_desc.dwWidth = 64;
+    surface_desc.dwHeight = 64;
+    U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
+    U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB;
+    U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32;
+    U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
+    U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
+    U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff;
+    surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+    hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+    hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface2, NULL);
+    ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+    /* No DDBLTFX. */
+    hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, &rect, DDBLT_COLORFILL | DDBLT_WAIT, NULL);
+    ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+    /* Unused source rectangle. */
+    hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, &rect, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+
+    /* Unused source surface. */
+    hr = IDirectDrawSurface7_Blt(surface, NULL, surface2, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface7_Blt(surface, NULL, surface2, &rect, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+    /* Inverted destination or source rectangle. */
+    SetRect(&rect, 5, 7, 7, 5);
+    hr = IDirectDrawSurface7_Blt(surface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDRECT, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, &rect, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface7_Blt(surface, &rect, surface2, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface7_Blt(surface, NULL, surface2, &rect, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+    /* Negative rectangle. */
+    SetRect(&rect, -1, -1, 5, 5);
+    hr = IDirectDrawSurface7_Blt(surface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDRECT, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, &rect, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface7_Blt(surface, &rect, surface2, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface7_Blt(surface, &rect, surface2, &rect, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+    /* Out of bounds rectangle. */
+    SetRect(&rect, 0, 0, 65, 65);
+    hr = IDirectDrawSurface7_Blt(surface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+    ok(hr == DDERR_INVALIDRECT, "Got unexpected hr %#x.\n", hr);
+
+    IDirectDrawSurface7_Release(surface2);
+    IDirectDrawSurface7_Release(surface);
+
+done:
+    IDirectDraw7_Release(ddraw);
+    refcount = IDirect3DDevice7_Release(device);
+    ok(!refcount, "Device has %u references left.\n", refcount);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw7)
 {
     HMODULE module = GetModuleHandleA("ddraw.dll");
@@ -8610,4 +8949,5 @@ START_TEST(ddraw7)
     test_negative_fixedfunction_fog();
     test_table_fog_zw();
     test_signed_formats();
+    test_color_fill();
 }
-- 
2.3.2




More information about the wine-patches mailing list