[PATCH 1/4] d3d8/tests: Port the filling convention test to d3d8.

Stefan Dösinger stefan at codeweavers.com
Mon Nov 8 07:38:58 CST 2021


Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
---
 dlls/d3d8/tests/visual.c | 483 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 483 insertions(+)

diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c
index df4dd0029a6..29baf07398c 100644
--- a/dlls/d3d8/tests/visual.c
+++ b/dlls/d3d8/tests/visual.c
@@ -11292,6 +11292,488 @@ static void test_dynamic_map_synchronization(void)
     DestroyWindow(window);
 }
 
+static void test_filling_convention(void)
+{
+    static const DWORD colour_bottom = 0x00ffff00;
+    static const DWORD colour_clear = 0x000000ff;
+    static const DWORD colour_right = 0x00000000;
+    static const DWORD colour_left = 0x00ff0000;
+    static const DWORD colour_top = 0x0000ff00;
+    IDirect3DSurface8 *rt, *backbuffer, *cur;
+    struct surface_readback rb;
+    IDirect3DDevice8 *device;
+    unsigned int i, j, x, y;
+    DWORD colour, expected;
+    DWORD shader = 0;
+    IDirect3D8 *d3d;
+    ULONG refcount;
+    D3DCAPS8 caps;
+    HWND window;
+    HRESULT hr;
+    BOOL todo;
+
+    static const unsigned int vp_size = 8;
+    const D3DVIEWPORT8 vp = { 0, 0, vp_size, vp_size, 0.0, 1.0 };
+    static const DWORD vs_code[] =
+    {
+        0xfffe0101,                                             /* vs_1_1               */
+        0x00000001, 0xc00f0000, 0x90e40000,                     /* mov oPos, v0         */
+        0x00000001, 0xd00f0000, 0x90e40005,                     /* mov oD0, v5          */
+        0x0000ffff                                              /* end                  */
+    };
+    static const DWORD decl[] =
+    {
+        D3DVSD_STREAM(0),
+        D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
+        D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
+        D3DVSD_END()
+    };
+
+    /* This test data follows the examples in MSDN's
+     * "Rasterization Rules (Direct3D 9)" article. */
+    static const float eps = 1.0f / 512.0f;
+    const struct
+    {
+        struct vec3 position;
+        DWORD diffuse;
+    }
+    center_tris[] =
+    {
+        /* left */
+        {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_left},
+        {{-2.5f / 4.0f,  2.5f / 4.0f, 0.0f}, colour_left},
+        {{-1.5f / 4.0f,  0.5f / 4.0f, 0.0f}, colour_left},
+
+        /* top */
+        {{-1.5f / 4.0f,  0.5f / 4.0f, 0.0f}, colour_top},
+        {{-2.5f / 4.0f,  2.5f / 4.0f, 0.0f}, colour_top},
+        {{-0.5f / 4.0f,  2.5f / 4.0f, 0.0f}, colour_top},
+
+        /* right */
+        {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_right},
+        {{-1.5f / 4.0f,  0.5f / 4.0f, 0.0f}, colour_right},
+        {{-0.5f / 4.0f,  2.5f / 4.0f, 0.0f}, colour_right},
+
+        /* bottom */
+        {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
+        {{-1.5f / 4.0f,  0.5f / 4.0f, 0.0f}, colour_bottom},
+        {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
+
+    },
+    edge_tris[] =
+    {
+        /* left */
+        {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
+        {{-2.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_left},
+        {{-1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_left},
+
+        /* top */
+        {{-1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_top},
+        {{-2.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_top},
+        {{ 0.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_top},
+
+        /* right */
+        {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
+        {{-1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_right},
+        {{ 0.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_right},
+
+        /* bottom */
+        {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{-1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
+    },
+    nudge_right_tris[] =
+    {
+        /* left */
+        {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
+        {{eps - 2.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_left},
+        {{eps - 1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_left},
+
+        /* top */
+        {{eps - 1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_top},
+        {{eps - 2.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_top},
+        {{eps - 0.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_top},
+
+        /* right */
+        {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
+        {{eps - 1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_right},
+        {{eps - 0.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_right},
+
+        /* bottom */
+        {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{eps - 1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
+    },
+    nudge_left_tris[] =
+    {
+        {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
+        {{-eps - 2.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_left},
+        {{-eps - 1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_left},
+
+        /* top */
+        {{-eps - 1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_top},
+        {{-eps - 2.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_top},
+        {{-eps - 0.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_top},
+
+        /* right */
+        {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
+        {{-eps - 1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_right},
+        {{-eps - 0.0f / 4.0f,  3.0f / 4.0f, 0.0f}, colour_right},
+
+        /* bottom */
+        {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{-eps - 1.0f / 4.0f,  1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
+    },
+    nudge_top_tris[] =
+    {
+        /* left */
+        {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_left},
+        {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_left},
+        {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_left},
+
+        /* top */
+        {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_top},
+        {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
+        {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
+
+        /* right */
+        {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_right},
+        {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_right},
+        {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_right},
+
+        /* bottom */
+        {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
+    },
+    nudge_bottom_tris[] =
+    {
+        /* left */
+        {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_left},
+        {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_left},
+        {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_left},
+
+        /* top */
+        {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_top},
+        {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
+        {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
+
+        /* right */
+        {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_right},
+        {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_right},
+        {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_right},
+
+        /* bottom */
+        {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
+        {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
+    };
+
+    const struct
+    {
+        struct vec4 position;
+        DWORD diffuse;
+    }
+    center_tris_t[] =
+    {
+        /* left */
+        {{ 1.5f,  1.5f, 0.0f, 1.0f}, colour_left},
+        {{ 2.5f,  3.5f, 0.0f, 1.0f}, colour_left},
+        {{ 1.5f,  5.5f, 0.0f, 1.0f}, colour_left},
+
+        /* top */
+        {{ 1.5f,  1.5f, 0.0f, 1.0f}, colour_top},
+        {{ 3.5f,  1.5f, 0.0f, 1.0f}, colour_top},
+        {{ 2.5f,  3.5f, 0.0f, 1.0f}, colour_top},
+
+        /* right */
+        {{ 3.5f,  1.5f, 0.0f, 1.0f}, colour_right},
+        {{ 3.5f,  5.5f, 0.0f, 1.0f}, colour_right},
+        {{ 2.5f,  3.5f, 0.0f, 1.0f}, colour_right},
+
+        /* bottom */
+        {{ 2.5f,  3.5f, 0.0f, 1.0f}, colour_bottom},
+        {{ 3.5f,  5.5f, 0.0f, 1.0f}, colour_bottom},
+        {{ 1.5f,  5.5f, 0.0f, 1.0f}, colour_bottom},
+    },
+    edge_tris_t[] =
+    {
+        /* left */
+        {{ 2.0f,  1.0f, 0.0f, 1.0f}, colour_left},
+        {{ 3.0f,  3.0f, 0.0f, 1.0f}, colour_left},
+        {{ 2.0f,  5.0f, 0.0f, 1.0f}, colour_left},
+
+        /* top */
+        {{ 2.0f,  1.0f, 0.0f, 1.0f}, colour_top},
+        {{ 4.0f,  1.0f, 0.0f, 1.0f}, colour_top},
+        {{ 3.0f,  3.0f, 0.0f, 1.0f}, colour_top},
+
+        /* right */
+        {{ 4.0f,  1.0f, 0.0f, 1.0f}, colour_right},
+        {{ 4.0f,  5.0f, 0.0f, 1.0f}, colour_right},
+        {{ 3.0f,  3.0f, 0.0f, 1.0f}, colour_right},
+
+        /* bottom */
+        {{ 3.0f,  3.0f, 0.0f, 1.0f}, colour_bottom},
+        {{ 4.0f,  5.0f, 0.0f, 1.0f}, colour_bottom},
+        {{ 2.0f,  5.0f, 0.0f, 1.0f}, colour_bottom},
+    };
+
+    const struct
+    {
+        const void *geometry;
+        size_t stride;
+        DWORD fvf;
+        const char *expected[8];
+    }
+    tests[] =
+    {
+        {
+            center_tris,
+            sizeof(center_tris[0]),
+            D3DFVF_XYZ | D3DFVF_DIFFUSE,
+            {
+                "        ",
+                "        ",
+                "  TT    ",
+                "  LR    ",
+                "  LR    ",
+                "  BB    ",
+                "        ",
+                "        "
+            }
+        },
+        {
+            edge_tris,
+            sizeof(edge_tris[0]),
+            D3DFVF_XYZ | D3DFVF_DIFFUSE,
+            {
+                "        ",
+                "  TT    ",
+                "  LT    ",
+                "  LR    ",
+                "  LB    ",
+                "        ",
+                "        ",
+                "        "
+            }
+        },
+        {
+            nudge_right_tris,
+            sizeof(nudge_right_tris[0]),
+            D3DFVF_XYZ | D3DFVF_DIFFUSE,
+            {
+                "        ",
+                "   TT   ",
+                "   TR   ",
+                "   LR   ",
+                "   BR   ",
+                "        ",
+                "        ",
+                "        "
+            }
+        },
+        {
+            nudge_left_tris,
+            sizeof(nudge_left_tris[0]),
+            D3DFVF_XYZ | D3DFVF_DIFFUSE,
+            {
+                "        ",
+                "  TT    ",
+                "  LT    ",
+                "  LR    ",
+                "  LB    ",
+                "        ",
+                "        ",
+                "        "
+            }
+        },
+        {
+            nudge_top_tris,
+            sizeof(nudge_top_tris[0]),
+            D3DFVF_XYZ | D3DFVF_DIFFUSE,
+            {
+                "        ",
+                "  LT    ",
+                "  LT    ",
+                "  LB    ",
+                "  LB    ",
+                "        ",
+                "        ",
+                "        "
+            }
+        },
+        {
+            nudge_bottom_tris,
+            sizeof(nudge_bottom_tris[0]),
+            D3DFVF_XYZ | D3DFVF_DIFFUSE,
+            {
+                "        ",
+                "        ",
+                "  LT    ",
+                "  Lt    ",
+                "  LB    ",
+                "  lB    ",
+                "        ",
+                "        "
+            }
+        },
+        {
+            center_tris_t,
+            sizeof(center_tris_t[0]),
+            D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
+            {
+                "        ",
+                "        ",
+                "  TT    ",
+                "  LR    ",
+                "  LR    ",
+                "  BB    ",
+                "        ",
+                "        "
+            }
+        },
+        {
+            edge_tris_t,
+            sizeof(edge_tris_t[0]),
+            D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
+            {
+                "        ",
+                "  TT    ",
+                "  LT    ",
+                "  LR    ",
+                "  LB    ",
+                "        ",
+                "        ",
+                "        "
+            }
+        },
+    };
+
+    window = create_window();
+    d3d = Direct3DCreate8(D3D_SDK_VERSION);
+    ok(!!d3d, "Failed to create a D3D object.\n");
+
+    if (!(device = create_device(d3d, window, window, TRUE)))
+    {
+        skip("Failed to create a 3D device.\n");
+        IDirect3D8_Release(d3d);
+        DestroyWindow(window);
+        return;
+    }
+
+    hr = IDirect3DDevice8_CreateRenderTarget(device, vp_size, vp_size,
+            D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, FALSE, &rt);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
+    {
+        hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &shader, 0);
+        ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    }
+    else
+        skip("Skipping vertex shader codepath in filling convention test.\n");
+
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    for (i = 0; i < ARRAY_SIZE(tests); ++i)
+    {
+        /* Run tests with shader and fixed function vertex processing if shaders are
+         * supported. There's no point in running the XYZRHW tests with a VS though. */
+        if (shader && ((tests[i].fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZ))
+            j = 0;
+        else
+            j = 2;
+
+        for (; j < 4; ++j)
+        {
+            cur = (j & 1) ? rt : backbuffer;
+
+            hr = IDirect3DDevice8_SetVertexShader(device, (j & 2) ? tests[i].fvf : shader);
+            ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+            hr = IDirect3DDevice8_SetRenderTarget(device, cur, NULL);
+            ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+            hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, colour_clear, 0.0f, 0);
+            ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+            hr = IDirect3DDevice8_SetViewport(device, &vp);
+            ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+            hr = IDirect3DDevice8_BeginScene(device);
+            ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+            hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, tests[i].geometry, tests[i].stride);
+            ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+            hr = IDirect3DDevice8_EndScene(device);
+            ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+            get_rt_readback(cur, &rb);
+            for (y = 0; y < 8; y++)
+            {
+                for (x = 0; x < 8; x++)
+                {
+                    todo = FALSE;
+                    switch (tests[i].expected[y][x])
+                    {
+                        case 'l': todo = TRUE;
+                        case 'L':
+                            expected = colour_left;
+                            break;
+                        case 't': todo = TRUE;
+                        case 'T':
+                            expected = colour_top;
+                            break;
+                        case 'r': todo = TRUE;
+                        case 'R':
+                            expected = colour_right;
+                            break;
+                        case 'b': todo = TRUE;
+                        case 'B':
+                            expected = colour_bottom;
+                            break;
+                        case ' ':
+                            expected = colour_clear;
+                            break;
+                        default:
+                            ok(0, "Unexpected entry in expected test char\n");
+                            expected = 0xdeadbeef;
+                    }
+                    colour = get_readback_color(&rb, x, y);
+                    /* The nudge-to-bottom test fails on cards that give us a bottom-left
+                     * filling convention. The cause isn't the bottom part of the filling
+                     * convention, but because wined3d will nudge geometry to the left to
+                     * keep diagonals (the 'R' in test case 'edge_tris') intact. */
+                    todo_wine_if(todo && !color_match(colour, expected, 1))
+                        ok(color_match(colour, expected, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
+                                colour, x, y, i, j);
+                }
+            }
+            release_surface_readback(&rb);
+
+            /* IDirect3DDevice8::CopyRects can't stretch, so don't bother making the offscreen surface
+             * visible. Use the d3d9 test if you need to see visual output. */
+            hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
+            ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+        }
+    }
+
+    if (shader)
+        IDirect3DDevice8_DeleteVertexShader(device, shader);
+    IDirect3DSurface8_Release(backbuffer);
+    IDirect3DSurface8_Release(rt);
+    refcount = IDirect3DDevice8_Release(device);
+    ok(!refcount, "Device has %u references left.\n", refcount);
+    IDirect3D8_Release(d3d);
+    DestroyWindow(window);
+}
+
 START_TEST(visual)
 {
     D3DADAPTER_IDENTIFIER8 identifier;
@@ -11371,4 +11853,5 @@ START_TEST(visual)
     test_desktop_window();
     test_sample_mask();
     test_dynamic_map_synchronization();
+    test_filling_convention();
 }
-- 
2.32.0




More information about the wine-devel mailing list