[PATCH 4/5] d3d8/tests: Port fog_with_shader_test() from d3d9 tests.

Matteo Bruni mbruni at codeweavers.com
Thu Mar 8 11:22:18 CST 2012


---
 dlls/d3d8/tests/visual.c |  283 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 283 insertions(+), 0 deletions(-)

diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c
index d8e1ed2..068b559 100644
--- a/dlls/d3d8/tests/visual.c
+++ b/dlls/d3d8/tests/visual.c
@@ -629,6 +629,287 @@ static void fog_test(IDirect3DDevice8 *device)
     ok(hr == D3D_OK, "Turning off fog calculations returned %#08x\n", hr);
 }
 
+/* This tests fog in combination with shaders.
+ * What's tested: linear fog (vertex and table) with pixel shader
+ *                linear table fog with non foggy vertex shader
+ *                vertex fog with foggy vertex shader, non-linear
+ *                fog with shader, non-linear fog with foggy shader,
+ *                linear table fog with foggy shader */
+static void fog_with_shader_test(IDirect3DDevice8 *device)
+{
+    HRESULT hr;
+    DWORD color;
+    union
+    {
+        float f;
+        DWORD i;
+    } start, end;
+    unsigned int i, j;
+
+    /* Basic vertex shader without fog computation ("non foggy") */
+    static const DWORD vertex_shader_code1[] =
+    {
+        0xfffe0100,                                                             /* vs.1.0                       */
+        0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
+        0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
+        0x0000ffff
+    };
+    /* Basic vertex shader with reversed fog computation ("foggy") */
+    static const DWORD vertex_shader_code2[] =
+    {
+        0xfffe0100,                                                             /* vs.1.0                        */
+        0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
+        0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
+        0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
+        0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
+        0x0000ffff
+    };
+    /* Basic pixel shader */
+    static const DWORD pixel_shader_code[] =
+    {
+        0xffff0101,                                                             /* ps_1_1     */
+        0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0 */
+        0x0000ffff
+    };
+    static struct vertex quad[] =
+    {
+        {-1.0f, -1.0f,  0.0f, 0xffff0000},
+        {-1.0f,  1.0f,  0.0f, 0xffff0000},
+        { 1.0f, -1.0f,  0.0f, 0xffff0000},
+        { 1.0f,  1.0f,  0.0f, 0xffff0000},
+    };
+    static const DWORD decl[] =
+    {
+        D3DVSD_STREAM(0),
+        D3DVSD_REG(0, D3DVSDT_FLOAT3),  /* position, v0 */
+        D3DVSD_REG(1, D3DVSDT_D3DCOLOR),  /* diffuse color, v1 */
+        D3DVSD_END()
+    };
+    static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
+    /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
+    DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
+    DWORD pixel_shader[2] = {0, 0};
+
+    /* This reference data was collected on a nVidia GeForce 7600GS
+     * driver version 84.19 DirectX version 9.0c on Windows XP */
+    static const struct test_data_t
+    {
+        int vshader;
+        int pshader;
+        D3DFOGMODE vfog;
+        D3DFOGMODE tfog;
+        unsigned int color[11];
+    }
+    test_data[] =
+    {
+        /* Only pixel shader */
+        {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+
+        /* Vertex shader */
+        {1, 0, D3DFOG_NONE, D3DFOG_NONE,
+        {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
+         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
+        {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+
+        {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+
+        /* Vertex shader and pixel shader */
+        /* The next 4 tests would read the fog coord output, but it isn't available.
+         * The result is a fully fogged quad, no matter what the Z coord is. */
+        {1, 1, D3DFOG_NONE, D3DFOG_NONE,
+        {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
+        0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
+        {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
+        {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
+        0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
+        {1, 1, D3DFOG_EXP, D3DFOG_NONE,
+        {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
+        0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
+        {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
+        {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
+        0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
+
+        /* These use the Z coordinate with linear table fog */
+        {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+        {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+
+        /* Non-linear table fog without fog coord */
+        {1, 1, D3DFOG_NONE, D3DFOG_EXP,
+        {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
+        0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
+        {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
+        {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
+        0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
+
+        /* These tests fail on older Nvidia drivers */
+        /* Foggy vertex shader */
+        {2, 0, D3DFOG_NONE, D3DFOG_NONE,
+        {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
+        {2, 0, D3DFOG_EXP, D3DFOG_NONE,
+        {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
+        {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
+        {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
+        {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
+        {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
+
+        /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
+         * all using the fixed fog-coord linear fog */
+        {2, 1, D3DFOG_NONE, D3DFOG_NONE,
+        {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
+        {2, 1, D3DFOG_EXP, D3DFOG_NONE,
+        {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
+        {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
+        {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
+        {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
+        {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
+
+        /* These use table fog. Here the shader-provided fog coordinate is
+         * ignored and the z coordinate used instead */
+        {2, 1, D3DFOG_NONE, D3DFOG_EXP,
+        {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
+        0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
+        {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
+        {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
+        0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
+        {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
+        {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
+        0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
+    };
+
+    /* NOTE: changing these values will not affect the tests with foggy vertex shader,
+     * as the values are hardcoded in the shader constant */
+    start.f = 0.1f;
+    end.f = 0.9f;
+
+    hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
+    ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
+    ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
+    ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
+
+    /* Set shader constant value */
+    hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
+    ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
+    ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
+
+    /* Setup initial states: No lighting, fog on, fog color */
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+    ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
+    ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
+    ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
+
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
+    ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
+    ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
+
+    /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
+    ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
+    ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
+
+    for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
+    {
+        hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
+        ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
+        hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
+        ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
+        hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
+        ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
+        hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
+        ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
+
+        for(j = 0; j < 11; ++j)
+        {
+            /* Don't use the whole zrange to prevent rounding errors */
+            quad[0].z = 0.001f + j / 10.02f;
+            quad[1].z = 0.001f + j / 10.02f;
+            quad[2].z = 0.001f + j / 10.02f;
+            quad[3].z = 0.001f + j / 10.02f;
+
+            hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0f, 0);
+            ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
+
+            hr = IDirect3DDevice8_BeginScene(device);
+            ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
+
+            hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
+            ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
+
+            hr = IDirect3DDevice8_EndScene(device);
+            ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
+
+            /* As the red and green component are the result of blending use 5% tolerance on the expected value */
+            color = getPixelColor(device, 128, 240);
+            ok(color_match(color, test_data[i].color[j], 13),
+                    "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
+                    test_data[i].vshader, test_data[i].pshader,
+                    test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
+
+            IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
+        }
+    }
+
+    /* Reset states */
+    hr = IDirect3DDevice8_SetVertexShader(device, 0);
+    ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_SetPixelShader(device, 0);
+    ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
+    hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
+    ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
+
+    IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
+    IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
+    IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
+}
+
 static void present_test(IDirect3DDevice8 *device)
 {
     struct vertex quad[] =
@@ -2976,6 +3257,8 @@ START_TEST(visual)
     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
     {
         test_rcp_rsq(device_ptr);
+        if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
+            fog_with_shader_test(device_ptr);
     }
     else
     {
-- 
1.7.3.4




More information about the wine-patches mailing list