[PATCH v2 1/4] d3d9/tests: Add Fetch4 tests
Daniel Ansorregui
mailszeros at gmail.com
Tue Jan 8 15:46:25 CST 2019
- Test texld/texldp/texldd/texldb/texldl in PS and FFP
- Test supported/unsupported texture formats on FFP/texld/texldp
- Test 3dtextures (Disabled due to FIXME in wine)
- Test depth textures on PS (FFP is broken on windows)
Signed-off-by: Daniel Ansorregui <mailszeros at gmail.com>
---
dlls/d3d9/tests/visual.c | 568 +++++++++++++++++++++++++++++++++++++++
1 file changed, 568 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 51229f2b82..a3eb30725e 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -15104,6 +15104,573 @@ done:
DestroyWindow(window);
}
+static void fetch4_test(void)
+{
+ static const DWORD vs_code[] =
+ {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
+ 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
+ 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord o1 */
+ 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
+ 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
+ 0x0000ffff
+ };
+ static const DWORD ps_code_texld[] =
+ {
+ /* Test texld */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff /* end */
+ };
+ static const DWORD ps_code_texldp[] =
+ {
+ /* Test texldp : It should not apply any projection with Fetch4. Same result as texld */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f000000, 0x3f000000, /* def c0, 0.0, 0.0, 0.5, 0.5 */
+ 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
+ 0x03010042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldp r0, r0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+ static const DWORD ps_code_texldd[] =
+ {
+ /* Test texldd : Fetch4 uses the same D3D state as LOD bias, therefore disables LOD.
+ * Sampling LOD gradient should be ignored. Same result as texld */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
+ 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
+ 0x02000001, 0x800f0002, 0xa0e40000, /* mov r2, c0 */
+ 0x0500005d, 0x800f0000, 0x90e40000, 0xa0e40800, 0xa0e40000, 0x80e40002, /* texldd r0, v0, s0, c0, r2 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+ static const DWORD ps_code_texldb[] =
+ {
+ /* Test texldb : Fetch4 uses the same D3D state as LOD bias, therefore disables LOD.
+ * Same result as texld */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x40a00000, 0x40a00000, /* def c0, 0.0, 0.0, 5.0, 5.0 */
+ 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
+ 0x03020042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldb r0, r0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+ static const DWORD ps_code_texldl[] =
+ {
+ /* Test texldl : Fetch4 uses the same D3D state as LOD bias, therefore disables LOD.
+ * The explicit LOD level is then ignored. Same result as texld */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f000000, 0x3f000000, /* def c0, 0.0, 0.0, 0.5, 0.5 */
+ 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
+ 0x0300005f, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldl r0, r0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+ static const DWORD ps_code_3d[] =
+ {
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
+ 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff /* end */
+ };
+
+ static const struct
+ {
+ struct vec3 position;
+ struct vec3 texcoord;
+ }
+ quad[] =
+ {
+ /* Tilted on Z axis to get a depth gradient in the depth test */
+ /* NOTE: Using 0.55f-0.6f to avoid rounding errors on depth tests */
+ {{-1.0f, 1.0f, 1.0f}, {0.0f,0.0f,0.6f} },
+ {{ 1.0f, 1.0f, 0.0f}, {1.0f,0.0f,0.6f} },
+ {{-1.0f,-1.0f, 0.0f}, {0.0f,1.0f,0.6f} },
+ {{ 1.0f,-1.0f, 0.0f}, {1.0f,1.0f,0.6f} }
+ };
+
+ static const struct
+ {
+ UINT x, y;
+ D3DCOLOR color;
+ }
+ expected_colors[] =
+ {
+ { 40, 30, 0x23102013},{160, 30, 0x22132312},{320, 30, 0x21122211},
+ {480, 30, 0x20112110},{600, 30, 0x23102013},
+ { 40,120, 0x13011002},{160,120, 0x120213f2},{320,120, 0x11f212f1},
+ {480,120, 0x10f11101},{600,120, 0x13011002},
+ { 40,240, 0x02030104},{160,240, 0xf20402f4},{320,240, 0xf1f4f2f3},
+ {480,240, 0x01f3f103},{600,240, 0x02030104},
+ { 40,360, 0x04200323},{160,360, 0xf4230422},{320,360, 0xf322f421},
+ {480,360, 0x0321f320},{600,360, 0x04200323},
+ { 40,450, 0x23102013},{160,450, 0x22132312},{320,450, 0x21122211},
+ {480,450, 0x20112110},{600,450, 0x23102013},
+ };
+
+ static const DWORD fetch4_data[] = {0x10111213, 0x01f1f202, 0x03f3f404, 0x20212223};
+
+ static struct
+ {
+ IDirect3DVertexShader9 *vs;
+ IDirect3DPixelShader9 *ps;
+ const DWORD *ps_code;
+ const char *name;
+ }
+ shaders[] =
+ {
+ {NULL, NULL, NULL, "Fixed Function Pipeline"},
+ {NULL, NULL, ps_code_texld, "texld"},
+ {NULL, NULL, ps_code_texldp, "texldp"},
+ {NULL, NULL, ps_code_texldd, "texldd"},
+ {NULL, NULL, ps_code_texldb, "texldb"},
+ {NULL, NULL, ps_code_texldl, "texldl"},
+ };
+
+ static const struct
+ {
+ D3DFORMAT format; /* The format of the texture */
+ DWORD data; /* The data we will write to the first line */
+ D3DCOLOR expected_color[3]; /* Test FFP, texld and texldp as in "shaders" struct */
+ UINT x, y; /* Where we expect the color to be */
+ BOOL disable_alpha_wine; /* Do not check alpha color on wine (A8 is known to be broken) */
+ }
+ format_tests[] =
+ {
+ /* Enabled formats */
+ {D3DFMT_L8, 0xff804010, {0x00400010, 0x00400010, 0x00400010}, 40, 30, FALSE},
+ {D3DFMT_L16, 0xff804010, {0x00ff0040, 0x00ff0040, 0x00ff0040}, 40, 30, FALSE},
+ {D3DFMT_R16F, 0x38003c00, {0x008000ff, 0x008000ff, 0x008000ff}, 40, 30, FALSE},
+ {D3DFMT_R32F, 0x3f000000, {0x00000080, 0x00000080, 0x00000080}, 40, 30, FALSE},
+
+ /* Disabled formats */
+ {D3DFMT_A8, 0xff804010, {0x00000000, 0x00000000, 0x00000000}, 40, 30, TRUE},
+ {D3DFMT_A8R8G8B8, 0xff804010, {0x64321906, 0x64321906, 0x562b1605}, 40, 30, FALSE},
+ };
+
+ static const struct
+ {
+ D3DCOLOR color[2]; /* FETCH4 off and on */
+ UINT x, y;
+ }
+ expected_depth[][4] =
+ {
+ {
+ /* This is the expected result for shadow samplers */
+ {{0x8f8f8f8f,0x8f8f8f8f}, 20, 15},
+ {{0xbfbfbfbf,0xbfbfbfbf},240, 15},
+ {{0x60606060,0x60606060}, 20,240},
+ {{0x40404040,0x40404040},240,120},
+ },
+ {
+ /* This is the expected result with DF16 */
+ {{0xff9b00ff,0x202000ff}, 20, 15},
+ {{0xff8300ff,0x00bf009f},240, 15},
+ {{0xff6c00ff,0x9f000080}, 20,240},
+ {{0xff8000ff,0x80809f60},240,120},
+ },
+ {
+ /* This is the expected result with DF24 */
+ {{0xff9bffff,0x202000ff}, 20, 15},
+ {{0xff83ffff,0x00bf009f},240, 15},
+ {{0xff6cffff,0x9f000080}, 20,240},
+ {{0xff80ffff,0x80809f60},240,120},
+ }
+ };
+
+ static const struct
+ {
+ D3DFORMAT format;
+ const char *name;
+ UINT index;
+ }
+ depth_tests[] =
+ {
+ {D3DFMT_D16_LOCKABLE, "D16_LOCKABLE", 0},
+ {D3DFMT_D32, "D32", 0},
+ {D3DFMT_D15S1, "D15S1", 0},
+ {D3DFMT_D24S8, "D24S8", 0},
+ {D3DFMT_D24X8, "D24X8", 0},
+ {D3DFMT_D24X4S4, "D24X4S4", 0},
+ {D3DFMT_D16, "D16", 0},
+ {D3DFMT_D32F_LOCKABLE, "D32F_LOCKABLE", 0},
+ {D3DFMT_D24FS8, "D24FS8", 0},
+ {MAKEFOURCC('D','F','1','6'), "DF16", 1},
+ {MAKEFOURCC('D','F','2','4'), "DF24", 2},
+ };
+
+ IDirect3DSurface9 *original_ds, *original_rt, *rt;
+ IDirect3DVolumeTexture9 *texture3D;
+ IDirect3DPixelShader9 *ps_3d;
+ struct surface_readback rb;
+ IDirect3DVertexShader9 *vs;
+ IDirect3DTexture9 *texture;
+ IDirect3DDevice9 *device;
+ D3DLOCKED_RECT lr;
+ D3DLOCKED_BOX lb;
+ IDirect3D9 *d3d;
+ ULONG refcount;
+ D3DCAPS9 caps;
+ UINT i, j, k;
+ HWND window;
+ HRESULT hr;
+
+ window = create_window();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('D','F','2','4'))))
+ {
+ skip("No DF24 support, skipping FETCH4 test.\n");
+ goto done;
+ }
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
+ if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
+ {
+ skip("No pixel shader 3.0 support, skipping FETCH4 test.\n");
+ IDirect3DDevice9_Release(device);
+ goto done;
+ }
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
+ ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
+ ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_CreateRenderTarget(device, 8, 8, D3DFMT_A8R8G8B8,
+ D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
+ ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
+
+ /* Create our texture for FETCH4 shader testing */
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
+ ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
+ hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
+ ok(hr == D3D_OK, "Failed to lock texture, hr %#x.\n", hr);
+ for (i = 0; i < ARRAY_SIZE(fetch4_data); ++i)
+ memcpy((BYTE *)lr.pBits + i*lr.Pitch, &fetch4_data[i], sizeof(fetch4_data[i]));
+ hr = IDirect3DTexture9_UnlockRect(texture, 0);
+ ok(hr == D3D_OK, "Failed to unlock texture, hr %#x.\n", hr);
+
+ /* Create vertex shader */
+ hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
+ ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
+ /* Prepare the pixel shaders */
+ for (i = 0; i < ARRAY_SIZE(shaders); ++i)
+ {
+ if (shaders[i].ps_code)
+ {
+ hr = IDirect3DDevice9_CreatePixelShader(device, shaders[i].ps_code, &shaders[i].ps);
+ ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
+ /* Copy vertex shader pointer if a PS is present */
+ shaders[i].vs = vs;
+ }
+ }
+ hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_3d, &ps_3d);
+ ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
+ ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
+ ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
+ ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
+ ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+ ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
+ ok(hr == D3D_OK, "Failed to set texture, hr %#x.\n", hr);
+
+ /* According to the spec, FETCH4 is enabled when D3DSAMP_MIPMAPLODBIAS == GET4
+ and also D3DSAMP_MAGFILTER == D3DTEXF_POINT. But apparently only GET4 is needed
+ So the tests exercices that only GET4 is required, and any other parameter will work */
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','4'));
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+
+ /***********************************************************************
+ * Tests for FFP/PS correctness when using L8 texture with fetch4. *
+ ***********************************************************************/
+
+ /* Render with fetch4 and test if we obtain proper results for all sampler FFP/PS instructions */
+ for (i = 0; i < ARRAY_SIZE(shaders); ++i)
+ {
+ hr = IDirect3DDevice9_SetVertexShader(device, shaders[i].vs);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, shaders[i].ps);
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+
+ get_rt_readback(original_rt, &rb);
+ for (j = 0; j < ARRAY_SIZE(expected_colors); ++j)
+ {
+ D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
+ ok(color_match(color, expected_colors[j].color, 1),
+ "Test %s Expected color 0x%08x at (%u, %u), got 0x%08x.\n", shaders[i].name,
+ expected_colors[j].color, expected_colors[j].x, expected_colors[j].y, color);
+ }
+ release_surface_readback(&rb);
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
+ }
+
+ /***************************************************************************
+ * Tests for fetch4 enable/disable with different texture formats in FFP/PS. *
+ ***************************************************************************/
+
+ /* Create the textures to test FETCH4 does work/not work there as expected */
+ for (i = 0; i < ARRAY_SIZE(format_tests); ++i)
+ {
+ IDirect3DTexture9 *tex;
+ hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, format_tests[i].format,
+ D3DPOOL_MANAGED, &tex, NULL);
+ ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
+ hr = IDirect3DTexture9_LockRect(tex, 0, &lr, NULL, 0);
+ ok(hr == D3D_OK, "Failed to lock texture, hr %#x.\n", hr);
+ memcpy(lr.pBits, &format_tests[i].data, 4);
+ hr = IDirect3DTexture9_UnlockRect(tex, 0);
+ ok(hr == D3D_OK, "Failed to unlock texture, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex);
+ ok(hr == D3D_OK, "Failed to set texture, hr %#x.\n", hr);
+
+ /* Test if FETCH4 is enabled/disabled when different textures are used with FFP/texld/texldp */
+ for (j = 0; j < ARRAY_SIZE(format_tests[i].expected_color); ++j)
+ {
+ hr = IDirect3DDevice9_SetVertexShader(device, shaders[j].vs);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, shaders[j].ps);
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+
+ get_rt_readback(original_rt, &rb);
+ D3DCOLOR color = get_readback_color(&rb, format_tests[i].x, format_tests[i].y);
+ D3DCOLOR expected_color = format_tests[i].expected_color[j];
+ /* FIXME: A8 gives different results, therefore we do not test alpha channel
+ * Fetch4 affects all 4 channels, and the test will catch errors anyway */
+ ok(color_match(color & 0x00ffffff, expected_color & 0x00ffffff, 1),
+ "Test %d,%s expected color 0x%08x at (%u, %u), got 0x%08x.\n", i, shaders[j].name,
+ expected_color & 0x00ffffff, format_tests[i].x, format_tests[i].y, color & 0x00ffffff);
+ /* If the format gives proper alpha result, test the full color */
+ todo_wine_if(format_tests[i].disable_alpha_wine) ok(color_match(color, expected_color, 1),
+ "Test %d,%s expected color 0x%08x at (%u, %u), got 0x%08x.\n", i, shaders[j].name,
+ expected_color, format_tests[i].x, format_tests[i].y, color);
+ release_surface_readback(&rb);
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
+ }
+ IDirect3DTexture9_Release(tex);
+ }
+
+ /**************************************************
+ * Tests that fetch4 works with 3D textures. *
+ **************************************************/
+
+ /* Create volume (3D) texture */
+ IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture3D, NULL );
+ ok(hr == D3D_OK, "Failed to create volume texture, hr %#x.\n", hr);
+ hr = IDirect3DVolumeTexture9_LockBox(texture3D, 0, &lb, NULL, 0);
+ ok(hr == D3D_OK, "Failed to lock texture3D, hr %#x.\n", hr);
+ for (i = 0; i < ARRAY_SIZE(fetch4_data); ++i)
+ {
+ memcpy((BYTE *)lb.pBits + i*lb.RowPitch, &fetch4_data[i], sizeof(fetch4_data[i]));
+ /* Shift the lower level, to keep it different */
+ memcpy((BYTE *)lb.pBits + i*lb.RowPitch + lb.SlicePitch, &fetch4_data[(i+1)%4], sizeof(fetch4_data[i]));
+ }
+ hr = IDirect3DVolumeTexture9_UnlockBox(texture3D, 0);
+ ok(hr == D3D_OK, "Failed to unlock texture3D, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture3D);
+ ok(hr == D3D_OK, "Failed to set texture3D, hr %#x.\n", hr);
+
+ /* Test FFP and texld with dcl_volume (ps_3d) */
+ for (i = 0; i < 2; ++i)
+ {
+ hr = IDirect3DDevice9_SetVertexShader(device, i ? vs : NULL);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, i ? ps_3d : NULL);
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+ get_rt_readback(original_rt, &rb);
+ for (j = 0; j < ARRAY_SIZE(expected_colors); ++j)
+ {
+ D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
+ /* FIXME: Fetch4 on 3D texture is like sampling a 2DArray at .xy0 with Fetch4 enabled
+ * Currently unimplemented on wine due to lack of GL functionality to cast 3D->2DArray
+ * Wine produces same results as if fetch4 is not enabled. Passes on w10 */
+ todo_wine ok(color_match(color, expected_colors[j].color, 1),
+ "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
+ expected_colors[j].color, expected_colors[j].x, expected_colors[j].y, color);
+ }
+ release_surface_readback(&rb);
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
+ }
+
+ /********************************************************
+ * Tests for fetch4 enable/disable with depth textures. *
+ ********************************************************/
+
+ for (i = 0; i < ARRAY_SIZE(depth_tests); ++i)
+ {
+ D3DFORMAT format = depth_tests[i].format;
+ IDirect3DTexture9 *depth_texture;
+ IDirect3DSurface9 *ds;
+
+ if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
+ continue;
+
+ hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1,
+ D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &depth_texture, NULL);
+ ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
+ hr = IDirect3DTexture9_GetSurfaceLevel(depth_texture, 0, &ds);
+ ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
+ ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
+ ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, NULL);
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
+ ok(hr == D3D_OK, "Failed to set texture3D, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0,
+ D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','1'));
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+
+ /* Setup the depth/stencil surface. */
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
+
+ /* Render to the depth surface */
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
+ ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
+ IDirect3DSurface9_Release(ds);
+ hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
+ ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)depth_texture);
+ ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
+
+ /* Set a shader for depth sampling, otherwise windows does not show anything */
+ hr = IDirect3DDevice9_SetVertexShader(device, vs);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, shaders[1].ps); /* same as texld */
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+
+ for (j = 0; j < 2; ++j){
+ hr = IDirect3DDevice9_SetSamplerState(device, 0,
+ D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T', j ? '4' : '1' ));
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+
+ /* Do the actual shadow mapping. */
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+
+ get_rt_readback(original_rt, &rb);
+ for (k = 0; k < ARRAY_SIZE(expected_depth[depth_tests[i].index]); ++k)
+ {
+ UINT x = expected_depth[depth_tests[i].index][k].x;
+ UINT y = expected_depth[depth_tests[i].index][k].y;
+ D3DCOLOR expected_color = expected_depth[depth_tests[i].index][k].color[j];
+ D3DCOLOR color = get_readback_color(&rb, x, y);
+ /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
+ * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
+ * Accept alpha mismatches as broken but make sure to check the color channels. */
+ ok(color_match(color, expected_color, 2)
+ || broken(color_match(color & 0x00ffffff, expected_color & 0x00ffffff, 0)),
+ "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
+ expected_color, x, y, depth_tests[i].name, color);
+ }
+ release_surface_readback(&rb);
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
+ }
+
+ hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
+ ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
+ IDirect3DTexture9_Release(depth_texture);
+ }
+
+ IDirect3DVolumeTexture9_Release(texture3D);
+ IDirect3DTexture9_Release(texture);
+ for (i = 0; i < ARRAY_SIZE(shaders); ++i)
+ if (shaders[i].ps)
+ IDirect3DPixelShader9_Release(shaders[i].ps);
+ IDirect3DPixelShader9_Release(ps_3d);
+ IDirect3DVertexShader9_Release(vs);
+ IDirect3DSurface9_Release(rt);
+ IDirect3DSurface9_Release(original_ds);
+ IDirect3DSurface9_Release(original_rt);
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+done:
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
static void shadow_test(void)
{
static const DWORD ps_code[] =
@@ -24480,6 +25047,7 @@ START_TEST(visual)
depth_buffer2_test();
depth_blit_test();
intz_test();
+ fetch4_test();
shadow_test();
fp_special_test();
depth_bounds_test();
--
2.17.1
More information about the wine-devel
mailing list