Hi Axel,
Thanks for testing with 3dmark06. I tried to run
it without luck yesterday, apparently there is some winetrick
that i am missing...
Regarding the linear sampler state. I havent
seen any case where setting the filters to LINEAR disables
fetch4. From the tests, it only changes slightly the results
on R500 AMD by changing the 0.5 texel offset.
My guess, is that all apps that use fetch4 have
that into account, and disable it with LODBIAS explicitly.
Sampling a 1x1 L8 texture with fetch4 will
return the same value on RGBA, which is similar to a normal
sample.
Regarding 3D textures, all implementations
behave differently. Since 3D textures have 8 texels, returning
the 4 texels used for linear sampling is quite ambiguous.
Intel decides to sample at .xy0 and ignore the Z
axis.
Some AMD devices disable fetch4, some others
sample at the nearest z coordinate.
In my opinion, we are hitting implementation
bugs/corner cases. It is simpler to just keep fetch4 off
there. Especially since implementing it is quite difficult.
The tests of 3D textures in wine are just
testing that fetch4 is off (no todo, it should be always off).
But on windows, it tests that some of the 4
possibles cases seen on AMD and intel is obtained.
How useful those tests are, i am not sure. I
just left them there for reference.
Maybe we should remove those tests on windows,
or even add todo in some of the cases for 3d. But in that
case, what implementation do we want to follow?
Best regards,
Daniel
Hi,
Apparently 3DMark06 believes somehow that LINEAR disables
FETCH4.
It sets MIPFILTER, MINFILTER and MAGFILTER to LINEAR,
and resets ADDRESSV, ADDRESSU and MIPMAPLODBIAS (1, 1, 0
respectively)
then behaves as if FETCH4 was disabled (it later disables it
definitely
with the MIPMAPLODBIAS setting).
I don't see any obvious visual glitch, though. The texture
sampled with
FETCH4 which isn't meant to be sampled with it (looking at
how the
shader values are used) is a D3DFMT_L8 of size 1x1...
I think all this points out that one has to be very careful
about FETCH4
corner cases.
Thus I would suggest adding more formats and checks to your
code, like
for example INTZ, ATI1, ATI2 ?
For the part "Currently unimplemented on wine due to lack of
GL
functionality to cast 3D->2DArray",
shouldn't the test be with a wine_todo rather than a isWin
check ?
Axel
On 01/02/2019 01:56, Daniel Ansorregui wrote:
> - Test texld/texldp/texldd/texldb/texldl in PS and FFP
> - Test supported/unsupported texture formats on
FFP/texld/texldp
> - Test 3dtextures (Disabled, each platform has
different results)
> - Test depth textures DF16/DF24 with fetch4 on PS (FFP
is broken on windows)
>
> Signed-off-by: Daniel Ansorregui <mailszeros@gmail.com>
> ---
> dlls/d3d9/tests/visual.c | 644
+++++++++++++++++++++++++++++++++++++++
> 1 file changed, 644 insertions(+)
>
> diff --git a/dlls/d3d9/tests/visual.c
b/dlls/d3d9/tests/visual.c
> index c06acb77d4..028fc23078 100644
> --- a/dlls/d3d9/tests/visual.c
> +++ b/dlls/d3d9/tests/visual.c
> @@ -15234,6 +15234,649 @@ 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 : AMD and Wine uses the
projection on Fetch4, Intel UHD 620 does not apply it */
> + 0xffff0300,
/* ps_3_0 */
> + 0x0200001f, 0x80000005, 0x900f0000,
/* dcl_texcoord v0 */
> + 0x0200001f, 0x90000000, 0xa00f0800,
/* dcl_2d s0 */
> + 0x05000051, 0xa00f0000, 0x00000000,
0x00000000, 0x00000000, 0x40000000, /* def c0, 0.0, 0.0,
0.0, 2.0 */
> + 0x02000001, 0x80030000, 0x90540000,
/* mov r0.xy, v0.xyyy */
> + 0x02000001, 0x800c0000, 0xa0fe0000,
/* mov r0.zw, c0.zwww */
> + 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 */
> + /* NOTE: Radeon HD 5700 driver 8.17.10.1404
disables Fetch4 on texldb */
> + 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 */
> + /* NOTE: Radeon HD 5700 driver 8.17.10.1404
disables Fetch4 on texldb */
> + 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 */
> + /* NOTE: Radeon HD 5700 driver 8.17.10.1404
disables Fetch4 on texldl */
> + 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[4], y[4]; /* Matrix Sampling
positions */
> + D3DCOLOR color_amd[16]; /* AMD original
implementation swizzle with -0.5 texel coord */
> + D3DCOLOR color_intel[16]; /* Intel UHD 620
implementation swizzle with no texel coord correction */
> + /* Wine follows the AMD immplementation, and
consider an error the Intel one results
> + * However, the test will accept as valid the
intel only if running on windows */
> + D3DCOLOR color_3d_fetch4_off[16];
> + D3DCOLOR color_fetch4_off[16];
> + }
> + expected_colors =
> + {
> + { 40, 200, 360, 520},
> + { 30, 150, 270, 390},
> + /* AMD implementation - Wine implementation */
> + {0x131202f2, 0x1211f2f1, 0x1110f101,
0x10130102,
> + 0x02f204f4, 0xf2f1f4f3, 0xf101f303,
0x01020304,
> + 0x04f42322, 0xf4f32221, 0xf3032120,
0x03042023,
> + 0x23221312, 0x22211211, 0x21201110,
0x20231013},
> + /* Intel UHD 620 implementation */
> + {0x23102013, 0x22132312, 0x21122211,
0x20112110,
> + 0x13011002, 0x120213f2, 0x11f212f1,
0x10f11101,
> + 0x02030104, 0xf20402f4, 0xf1f4f2f3,
0x01f3f103,
> + 0x04200323, 0xf4230422, 0xf322f421,
0x0321f320},
> + /* Fetch4 off on 3D textures */
> + {0xff020202, 0xfff2f2f2, 0xfff1f1f1,
0xff010101,
> + 0xff050505, 0xfff4f4f4, 0xfff3f3f3,
0xff030303,
> + 0xff232323, 0xff222222, 0xff212121,
0xff202020,
> + 0xff131313, 0xff121212, 0xff111111,
0xff101010},
> + /* Fetch4 off on 2D texture */
> + {0x13131313, 0x12121212, 0x11111111,
0x10101010,
> + 0x02020202, 0xf2f2f2f2, 0xf1f1f1f1,
0x01010101,
> + 0x04040404, 0xf4f4f4f4, 0xf3f3f3f3,
0x03030303,
> + 0x23232323, 0x22222222, 0x21212121,
0x20202020}
> + };
> +
> + static const DWORD fetch4_data[] = {0x10111213,
> + 0x01f1f202,
> + 0x03f3f404,
> + 0x20212223};
> +
> + static struct
> + {
> + IDirect3DVertexShader9 *vs;
> + IDirect3DPixelShader9 *ps;
> + const DWORD *ps_code;
> + const char *name;
> + BOOL projection; /* The results
should be projected (zoomed by 2) */
> + BOOL allow_off; /* Do not enforce
Fetch4 enabled on this one on Windows */
> + }
> + shaders[] =
> + {
> + {NULL, NULL, NULL, "FFP", FALSE,
FALSE},
> + {NULL, NULL, ps_code_texld, "texld", FALSE,
FALSE},
> + {NULL, NULL, ps_code_texldp, "texldp", TRUE,
FALSE},
> + {NULL, NULL, ps_code_texldd, "texldd", FALSE,
TRUE},
> + {NULL, NULL, ps_code_texldb, "texldb", FALSE,
TRUE},
> + {NULL, NULL, ps_code_texldl, "texldl", FALSE,
TRUE},
> + };
> +
> + static const struct
> + {
> + D3DFORMAT format; /* The format of
the texture */
> + DWORD data; /* The data we
will write to the first line */
> + UINT x, y; /* Where we expect
the color to be */
> + BOOL broken_wine; /* Do not check it
on wine because is known ot be broken */
> + D3DCOLOR color_amd[3]; /* Wine results.
Results on AMD swizzle + texture offset */
> + D3DCOLOR color_intel[3]; /* Results with
intel UHD 620, intel swizzle + no texel offset */
> + }
> + format_tests[] =
> + {
> + /* Enabled formats */
> + {D3DFMT_L8, 0xff804010, 360, 270,
FALSE,
> + {0x00004010, 0x00004010, 0x10400000},
> + {0x40001000, 0x40001000, 0x40001000}
> + },
> + {D3DFMT_L16, 0xff804010, 360, 270,
FALSE,
> + {0x0000ff40, 0x0000ff40, 0x40ff0000},
> + {0xff004000, 0xff004000, 0xff004000}
> + },
> + {D3DFMT_R16F, 0x38003c00, 360, 270,
FALSE,
> + {0x000080ff, 0x000080ff, 0xff800000},
> + {0x8000ff00, 0x8000ff00, 0x8000ff00}
> + },
> + {D3DFMT_R32F, 0x3f000000, 360, 270,
FALSE,
> + {0x00000080, 0x00000080, 0x80000000},
> + {0x00008000, 0x00008000, 0x00008000}
> + },
> +
> + /* Disabled format on Intel, enabled on AMD,
broken on wine
> + * since it is implemented with GL_ALPHA, and
fetch4 will fetch RED value */
> + {D3DFMT_A8, 0xff804010, 360, 270,
TRUE,
> + {0x00004010, 0x00004010, 0x10400000},
> + {0x00000000, 0x00000000, 0x00000000}
> + },
> +
> + /* Disabled format */
> + {D3DFMT_A8R8G8B8, 0xff804010, 360, 270,
FALSE,
> + {0x00000000, 0x00000000, 0xff804010},
> + {0x00000000, 0x00000000, 0xff804010}
> + },
> + };
> +
> + static const struct
> + {
> + D3DCOLOR color_off, color_amd, color_intel;
> + UINT x, y;
> + }
> + expected_depth[][4] =
> + {
> + {
> + /* This is the expected result for shadow
samplers */
> + {0xffffffff,0xffffffff,0xffffffff, 20,
15},
> + {0xffffffff,0xffffffff,0xffffffff,260,
15},
> + {0x00000000,0x00000000,0x00000000,
20,255},
> +
{0x00000000,0x00000000,0x00000000,260,135},
> + },
> + {
> + /* This is the expected result with DF16 */
> + {0xfffe0000,0xfedfdfbf,0x202000ff, 20,
15},
> + {0xff9f0000,0x9f7f7f5f,0x00bf009f,260,
15},
> + {0xff800000,0x7f5f5f3f,0x9f000080,
20,255},
> +
{0xff600000,0x5f3f3f1f,0x80809f60,260,135},
> + },
> + {
> + /* This is the expected result with DF24 */
> + {0xffff0000,0xffdfdfbf,0x202000ff, 20,
15},
> + {0xff9f0000,0x9f7f7f5f,0x00bf009f,260,
15},
> + {0xff800000,0x7f5f5f3f,0x9f000080,
20,255},
> +
{0xff600000,0x5f3f3f1f,0x80809f60,260,135},
> + }
> + };
> +
> + 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},
> + };
> +
> + const BOOL isWin = strcmp(winetest_platform,
"wine");
> +
> + 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 for it to get active.
> + * However, AMD HW r500 samples always as if POINT
(nearest filtering) is selected with FETCH4
> + * the driver later on corrected this by adding
-0.5 texel coord. */
> + 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_POINT);
> + 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_POINT);
> + 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.color_amd); ++j)
> + {
> + UINT x = expected_colors.x[j % 4];
> + UINT y = expected_colors.y[j / 4];
> + D3DCOLOR color =
get_readback_color(&rb, x, y);
> + D3DCOLOR color_amd =
expected_colors.color_amd[shaders[i].projection ? (j/4/2*4 +
(j%4)/2) : j];
> + D3DCOLOR color_intel =
expected_colors.color_intel[j];
> + ok(color_match(color, color_amd, 1)
> + || (isWin &&
(color_match(color, color_intel, 1) ||
shaders[i].allow_off)),
> + "Test %s Expected color 0x%08x at
(%u, %u), got 0x%08x.\n", shaders[i].name,
> + color_amd, x, 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].color_amd); ++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 color_amd =
format_tests[i].color_amd[j];
> + D3DCOLOR color_intel =
format_tests[i].color_intel[j];
> + todo_wine_if(format_tests[i].broken_wine)
ok(color_match(color, color_amd, 1)
> + || (isWin &&
color_match(color, color_intel, 1)),
> + "Test %d,%s expected color 0x%08x
at (%u, %u), got 0x%08x.\n", i, shaders[j].name,
> + color_amd, 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.color_amd); ++j)
> + {
> + UINT x = expected_colors.x[j % 4];
> + UINT y = expected_colors.y[j / 4];
> + D3DCOLOR color =
get_readback_color(&rb, x, y);
> + D3DCOLOR color_amd =
expected_colors.color_amd[j];
> + D3DCOLOR color_intel =
expected_colors.color_intel[j];
> + D3DCOLOR color_off =
expected_colors.color_3d_fetch4_off[j];
> + D3DCOLOR color_zround =
expected_colors.color_amd[(j+4) %
ARRAY_SIZE(expected_colors.color_amd)];
> + /* FIXME: Fetch4 on 3D textures have
different results based on the vendor/driver
> + * - AMD "HD 5700" rounds to nearest "z"
texel, and does fetch4 normally on .xy
> + * - AMD "R500" has fetch4 disabled
> + * - AMD "R580" has fetch4 enabled
sampling at .xy0
> + * - Intel UHD 620 sample with fetch4 at
.xy0
> + * Currently unimplemented on wine due to
lack of GL functionality to cast 3D->2DArray
> + * Wine produces same results as if fetch4
is not enabled (which probably is better)
> + * Test will pass on windows if either one
of the allowed results is returned */
> + if(isWin)
> + ok(color_match(color, color_zround, 2)
|| color_match(color, color_off, 2)
> + || color_match(color,
color_intel, 2) || color_match(color, color_amd, 2),
> + "Test 3D %s Expected colors
0x%08x || 0x%08x || 0x%08x || 0x%08x at (%u, %u), got
0x%08x.\n",
> + shaders[i].name, color_amd,
color_zround, color_off, color_intel, x, y, color);
> + else
> + ok(color_match(color, color_off, 2),
> + "Test 3D %s Expected color
0x%08x at (%u, %u), got 0x%08x.\n", shaders[i].name,
> + color_off, x, 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 color_off =
expected_depth[depth_tests[i].index][k].color_off;
> + D3DCOLOR color_amd =
expected_depth[depth_tests[i].index][k].color_amd;
> + D3DCOLOR color_intel =
expected_depth[depth_tests[i].index][k].color_intel;
> + D3DCOLOR color =
get_readback_color(&rb, x, y);
> + /* When Fetch4 is OFF, ignore G and B
channels on windows.
> + * Some implementations will copy
R=G=B, some will set them to 0 */
> + if(j == 0)
> + ok((isWin &&
color_match(color & 0xffff0000, color_off &
0xffff0000, 2))
> + || color_match(color,
color_off, 2),
> + "Test OFF Expected color
0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
> + color_off, x, y,
depth_tests[i].name, color);
> + else
> + ok(color_match(color, color_amd,
2)
> + || (isWin &&
color_match(color, color_intel, 2)),
> + "Test ON Expected colors
0x%08x || 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
> + color_amd, color_intel,
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[] =
> @@ -24660,6 +25303,7 @@ START_TEST(visual)
> depth_buffer2_test();
> depth_blit_test();
> intz_test();
> + fetch4_test();
> shadow_test();
> fp_special_test();
> depth_bounds_test();