[PATCH 1/4] d3d9/tests: Test sample and texture dimensions mismatch.

Paul Gofman gofmanp at gmail.com
Wed Jul 3 09:56:39 CDT 2019


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
 dlls/d3d9/tests/visual.c | 240 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 240 insertions(+)

diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index f51e334a68..45c6e03dd9 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -26249,6 +26249,245 @@ static void test_desktop_window(void)
     IDirect3D9_Release(d3d);
 }
 
+static void test_mismatched_sample_types_fill_texture(DWORD *bits, unsigned int pitch, D3DCOLOR colour,
+        unsigned int size)
+{
+    unsigned int x, y;
+
+    for (y = 0; y < size; ++y)
+    {
+        DWORD *ptr = (DWORD *)(((BYTE *)bits) + (y * pitch));
+
+        for (x = 0; x < size; ++x)
+            *ptr++ = colour;
+    }
+}
+
+static void test_mismatched_sample_types(void)
+{
+    /* MSDN suggests that sampling a texture with fewer dimensions than sampler has
+     * is allowed while the opposite is not.
+     * AMD, Intel, WARP return sampled texture values in both cases. The use of W
+     * coordinate when sampling 3d texture with 2d sampler looks not entirely consistent.
+     * Nvidia returns zero texture values for both cases while that is different
+     * from unbound texture result (0, 0, 0, 1): it is (0, 0, 0, 0) for RGBA texture or,
+     * in a general case, result of a fixup of zero texture color, e. g., (0, 0, 1, 1)
+     * for D3DFMT_G16R16 texture. */
+
+    IDirect3DVertexDeclaration9 *vertex_declaration;
+    static IDirect3DPixelShader9 *ps_2d, *ps_3d;
+    static IDirect3DVolumeTexture9 *volume;
+    IDirect3DVertexShader9 *vertex_shader;
+    static IDirect3DTexture9 *tex_2d;
+    D3DLOCKED_RECT locked_rect;
+    D3DLOCKED_BOX locked_box;
+    IDirect3DDevice9 *device;
+    IDirect3D9 *d3d;
+    D3DCOLOR colour;
+    unsigned int i;
+    ULONG refcount;
+    D3DCAPS9 caps;
+    HWND window;
+    HRESULT hr;
+
+    static const D3DVERTEXELEMENT9 decl_elements[] =
+    {
+        {0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+        {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+        D3DDECL_END()
+    };
+    static const struct
+    {
+        struct vec3 position;
+        struct vec3 t0;
+    }
+    quad[] =
+    {
+        {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f, 0.0f}},
+        {{-1.0f,  1.0f, 0.1f}, {0.0f, 1.0f, 0.5f}},
+        {{ 1.0f, -1.0f, 0.1f}, {1.0f, 0.0f, 0.5f}},
+        {{ 1.0f,  1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}},
+    };
+
+    static const DWORD vs_code[] =
+    {
+        0xfffe0300,                                     /* vs_3_0                 */
+        0x0200001f, 0x80000000, 0x900f0000,             /* dcl_position v0        */
+        0x0200001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1       */
+        0x0200001f, 0x80000000, 0xe00f0000,             /* dcl_position o0        */
+        0x0200001f, 0x80000005, 0xe00f0001,             /* dcl_texcoord0 o1       */
+        0x02000001, 0xe00f0000, 0x90e40000,             /* mov o0, v0             */
+        0x02000001, 0xe00f0001, 0x90e40001,             /* mov o1, v1             */
+        0x0000ffff,                                     /* end                    */
+    };
+
+    static const DWORD ps_header[] =
+    {
+        0xffff0300,                                     /* ps_3_0                 */
+        0x05000051, 0xa00f0000, 0x3f333333, 0x3f4ccccd, 0x3f666666, 0x00000000,
+                /* def c0, 0.7, 0.8, 0.9, 0.0 */
+    };
+    static const DWORD ps_footer[] =
+    {
+        0x03000042, 0x800f0001, 0x90e40000, 0xa0e40800, /* texld r1, v0, s0       */
+        0x02020029, 0x80ff0001, 0xa0ff0000,             /* if_eq r1.w, c0.w       */
+        0x02000001, 0x800f0001, 0xa0e40000,             /* mov r1, c0             */
+        0x0000002b,                                     /* endif                  */
+        0x02000001, 0x800f0800, 0x80e40001,             /* mov oC0, r1            */
+        0x0000ffff,                                     /* end                    */
+    };
+
+    #define TEST_MISMATCHED_SAMPLE_BODY_WORDS 6
+
+    static const DWORD ps_tex_2d[TEST_MISMATCHED_SAMPLE_BODY_WORDS] =
+    {
+        0x0200001f, 0x80000005, 0x90030000,             /* dcl_texcoord0 v0.xy    */
+        0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0              */
+    };
+    static const DWORD ps_tex_3d[TEST_MISMATCHED_SAMPLE_BODY_WORDS] =
+    {
+        0x0200001f, 0x80000005, 0x90070000,             /* dcl_texcoord0 v0.xyz   */
+        0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0          */
+    };
+
+    static DWORD ps_code[ARRAY_SIZE(ps_header) + TEST_MISMATCHED_SAMPLE_BODY_WORDS + ARRAY_SIZE(ps_footer)];
+
+    static const struct
+    {
+        const char *name;
+        IDirect3DBaseTexture9 **texture;
+        IDirect3DPixelShader9 **pixel_shader;
+        D3DCOLOR expected_colour;
+        D3DCOLOR expected_broken;
+        BOOL todo;
+        D3DCOLOR expected_broken2;
+    }
+    tests[] =
+    {
+        {"2d_2d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_2d, 0x00707070},
+        {"3d_3d", (IDirect3DBaseTexture9 **)&volume, &ps_3d, 0x00303030},
+        {"2d_3d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_3d, 0x00707070, 0x00b2cce5, TRUE},
+        {"3d_2d", (IDirect3DBaseTexture9 **)&volume, &ps_2d, 0x00303030, 0x00b2cce5, TRUE, 0x00202020},
+    };
+
+    window = create_window();
+    ok(!!window, "Failed to create a window.\n");
+
+    d3d = Direct3DCreate9(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 D3D device, skipping tests.\n");
+        IDirect3D9_Release(d3d);
+        DestroyWindow(window);
+        return;
+    }
+
+    hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
+    {
+        skip("No shader model 3 support, skipping tests.\n");
+        goto done;
+    }
+    if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
+    {
+        skip("No volume texture support, skipping tests.\n");
+        goto done;
+    }
+
+    hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
+            D3DPOOL_MANAGED, &volume, NULL);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &locked_box, NULL, 0);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    test_mismatched_sample_types_fill_texture(locked_box.pBits, locked_box.RowPitch, 0x20202020, 2);
+    test_mismatched_sample_types_fill_texture((DWORD *)((BYTE *)locked_box.pBits + locked_box.SlicePitch),
+            locked_box.RowPitch, 0x40404040, 2);
+    hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
+            D3DPOOL_MANAGED, &tex_2d, NULL);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DTexture9_LockRect(tex_2d, 0, &locked_rect, NULL, 0);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    test_mismatched_sample_types_fill_texture(locked_rect.pBits, locked_rect.Pitch, 0x70707070, 2);
+    hr = IDirect3DTexture9_UnlockRect(tex_2d, 0);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertex_shader);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    memcpy(ps_code, ps_header, sizeof(ps_header));
+    memcpy(ps_code + ARRAY_SIZE(ps_header) + TEST_MISMATCHED_SAMPLE_BODY_WORDS, ps_footer, sizeof(ps_footer));
+
+    memcpy(ps_code + ARRAY_SIZE(ps_header), ps_tex_2d,
+            sizeof(*ps_code) * TEST_MISMATCHED_SAMPLE_BODY_WORDS);
+    hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps_2d);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    memcpy(ps_code + ARRAY_SIZE(ps_header), ps_tex_3d,
+            sizeof(*ps_code) * TEST_MISMATCHED_SAMPLE_BODY_WORDS);
+    hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps_3d);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    for (i = 0; i < ARRAY_SIZE(tests); ++i)
+    {
+        hr = IDirect3DDevice9_BeginScene(device);
+        ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+        hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80808080, 0.0f, 0);
+        ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+        hr = IDirect3DDevice9_SetTexture(device, 0, *tests[i].texture);
+        ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+        hr = IDirect3DDevice9_SetPixelShader(device, *tests[i].pixel_shader);
+        ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+        hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+        ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+        hr = IDirect3DDevice9_EndScene(device);
+        ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+        colour = getPixelColor(device, 320, 240);
+
+        todo_wine_if(tests[i].todo) ok(color_match(colour, tests[i].expected_colour, 1)
+                || broken(tests[i].expected_broken && color_match(colour, tests[i].expected_broken, 1))
+                || broken(tests[i].expected_broken2 && color_match(colour, tests[i].expected_broken2, 1)),
+                "test %s, expected 0x%08x, got 0x%08x.\n",
+                tests[i].name, tests[i].expected_colour, colour);
+    }
+    hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+    IDirect3DPixelShader9_Release(ps_2d);
+    IDirect3DPixelShader9_Release(ps_3d);
+
+    IDirect3DVertexShader9_Release(vertex_shader);
+    IDirect3DVertexDeclaration9_Release(vertex_declaration);
+    IDirect3DVolumeTexture9_Release(volume);
+    IDirect3DTexture9_Release(tex_2d);
+
+done:
+    refcount = IDirect3DDevice9_Release(device);
+    ok(!refcount, "Device has %u references left.\n", refcount);
+    IDirect3D9_Release(d3d);
+    DestroyWindow(window);
+}
+
 START_TEST(visual)
 {
     D3DADAPTER_IDENTIFIER9 identifier;
@@ -26393,4 +26632,5 @@ START_TEST(visual)
     test_sysmem_draw();
     test_nrm_instruction();
     test_desktop_window();
+    test_mismatched_sample_types();
 }
-- 
2.21.0




More information about the wine-devel mailing list