[PATCH v2 1/2] wined3d: Handle degenerate viewport Z ranges.
Paul Gofman
gofmanp at gmail.com
Tue Nov 19 02:27:09 CST 2019
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48104
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
v2:
- rename helper function;
- reorder max_z estimation.
dlls/ddraw/tests/ddraw7.c | 191 +++++++++++++++++++++++----------
dlls/wined3d/device.c | 7 +-
dlls/wined3d/state.c | 15 ++-
dlls/wined3d/wined3d_private.h | 8 ++
4 files changed, 159 insertions(+), 62 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 143f6d4b6b..20b0e09a95 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -277,7 +277,8 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface7 *surface, UINT x, UINT y)
return color;
}
-static void check_rect(IDirectDrawSurface7 *surface, RECT r, const char *message)
+#define check_rect(a, b, c) check_rect_(__LINE__, a, b, c)
+static void check_rect_(unsigned int line, IDirectDrawSurface7 *surface, RECT r, const char *message)
{
LONG x_coords[2][2] =
{
@@ -308,7 +309,7 @@ static void check_rect(IDirectDrawSurface7 *surface, RECT r, const char *message
if (x < 0 || x >= 640 || y < 0 || y >= 480)
continue;
color = get_surface_color(surface, x, y);
- ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x.\n",
+ ok_(__FILE__, line)(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x.\n",
message, x, y, color, expected);
}
}
@@ -543,17 +544,17 @@ static void test_process_vertices(void)
}
hr = IDirect3DDevice7_GetDirect3D(device, &d3d7);
- ok(SUCCEEDED(hr), "Failed to get Direct3D7 interface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&vb_desc, 0, sizeof(vb_desc));
vb_desc.dwSize = sizeof(vb_desc);
vb_desc.dwFVF = D3DFVF_XYZ;
vb_desc.dwNumVertices = 4;
hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &src_vb, 0);
- ok(SUCCEEDED(hr), "Failed to create source vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_Lock(src_vb, 0, (void **)&src_data, NULL);
- ok(SUCCEEDED(hr), "Failed to lock source vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
src_data[0].x = 0.0f;
src_data[0].y = 0.0f;
src_data[0].z = 0.0f;
@@ -567,7 +568,7 @@ static void test_process_vertices(void)
src_data[3].y = -0.5f;
src_data[3].z = 0.25f;
hr = IDirect3DVertexBuffer7_Unlock(src_vb);
- ok(SUCCEEDED(hr), "Failed to unlock source vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&vb_desc, 0, sizeof(vb_desc));
vb_desc.dwSize = sizeof(vb_desc);
@@ -575,7 +576,7 @@ static void test_process_vertices(void)
vb_desc.dwNumVertices = 4;
/* MSDN says that the last parameter must be 0 - check that. */
hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &dst_vb1, 4);
- ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&vb_desc, 0, sizeof(vb_desc));
vb_desc.dwSize = sizeof(vb_desc);
@@ -583,7 +584,7 @@ static void test_process_vertices(void)
vb_desc.dwNumVertices = 5;
/* MSDN says that the last parameter must be 0 - check that. */
hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &dst_vb2, 12345678);
- ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&vp, 0, sizeof(vp));
vp.dwX = 64;
@@ -593,15 +594,15 @@ static void test_process_vertices(void)
vp.dvMinZ = 0.0f;
vp.dvMaxZ = 1.0f;
hr = IDirect3DDevice7_SetViewport(device, &vp);
- ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
- ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb2, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
- ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
- ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
ok(compare_vec4(&dst_data[0], +1.280e+2f, +1.280e+2f, +0.000e+0f, +1.000e+0f, 4096),
"Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
@@ -615,10 +616,10 @@ static void test_process_vertices(void)
"Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
- ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_Lock(dst_vb2, 0, (void **)&dst_data2, NULL);
- ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
/* Small thing without much practical meaning, but I stumbled upon it,
* so let's check for it: If the output vertex buffer has no RHW value,
* the RHW value of the last vertex is written into the next vertex. */
@@ -626,7 +627,62 @@ static void test_process_vertices(void)
"Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
dst_data2[4].x, dst_data2[4].y, dst_data2[4].z);
hr = IDirect3DVertexBuffer7_Unlock(dst_vb2);
- ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+ /* Test degenerate viewport z ranges. */
+ vp.dvMinZ = 0.0f;
+ vp.dvMaxZ = 0.0f;
+ hr = IDirect3DDevice7_SetViewport(device, &vp);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb2, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ ok(compare_vec4(&dst_data[0], +1.280e+2f, +1.280e+2f, +0.000e+0f, +1.000e+0f, 4096),
+ "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
+ dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
+ ok(compare_vec4(&dst_data[1], +1.920e+2f, +6.400e+1f, +1.000e-3f, +1.000e+0f, 4096),
+ "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
+ dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
+ ok(compare_vec4(&dst_data[2], +6.400e+1f, +1.920e+2f, +5.000e-4f, +1.000e+0f, 4096),
+ "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
+ dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
+ ok(compare_vec4(&dst_data[3], +1.600e+2f, +1.600e+2f, +2.500e-4f, +1.000e+0f, 4096),
+ "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
+ dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
+ hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+ vp.dvMinZ = 1.0f;
+ vp.dvMaxZ = 0.0f;
+ hr = IDirect3DDevice7_SetViewport(device, &vp);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb2, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ ok(compare_vec4(&dst_data[0], +1.280e+2f, +1.280e+2f, +1.000e+0f, +1.000e+0f, 4096),
+ "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
+ dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
+ ok(compare_vec4(&dst_data[1], +1.920e+2f, +6.400e+1f, +1.001e+0f, +1.000e+0f, 4096),
+ "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
+ dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
+ ok(compare_vec4(&dst_data[2], +6.400e+1f, +1.920e+2f, +1.0005e+0f, +1.000e+0f, 4096),
+ "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
+ dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
+ ok(compare_vec4(&dst_data[3], +1.600e+2f, +1.600e+2f, +1.00025e+0f, +1.000e+0f, 4096),
+ "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
+ dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
+ hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
/* Try a more complicated viewport, same vertices. */
memset(&vp, 0, sizeof(vp));
@@ -637,13 +693,13 @@ static void test_process_vertices(void)
vp.dvMinZ = -2.0f;
vp.dvMaxZ = 4.0f;
hr = IDirect3DDevice7_SetViewport(device, &vp);
- ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
- ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
- ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
ok(compare_vec4(&dst_data[0], +1.330e+2f, +7.000e+1f, -2.000e+0f, +1.000e+0f, 4096),
"Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
@@ -657,20 +713,20 @@ static void test_process_vertices(void)
"Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
- ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &world);
- ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &view);
- ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &proj);
- ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
- ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
- ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
ok(compare_vec4(&dst_data[0], +2.560e+2f, +7.000e+1f, -2.000e+0f, +3.333e-1f, 4096),
"Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
@@ -684,7 +740,7 @@ static void test_process_vertices(void)
"Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
- ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
IDirect3DVertexBuffer7_Release(dst_vb2);
IDirect3DVertexBuffer7_Release(dst_vb1);
@@ -14877,24 +14933,27 @@ static void test_viewport(void)
static struct
{
D3DVIEWPORT7 vp;
+ float expected_z;
RECT expected_rect;
const char *message;
}
tests[] =
{
- {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
- {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
- {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
- {{ 0, 0, 2000, 1600}, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"},
- {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
- {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
+ {{ 0, 0, 640, 480}, 0.001f, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
+ {{ 0, 0, 640, 480, 0.5f, 0.0f}, 0.501f,
+ {0, 120, 479, 359}, "Viewport (0, 0, 0.5) - (640, 480, 0.0)"},
+ {{ 0, 0, 320, 240}, 0.001f, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
+ {{ 0, 0, 1280, 960}, 0.001f, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
+ {{ 0, 0, 2000, 1600}, 0.001f, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"},
+ {{100, 100, 640, 480}, 0.001f, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
+ {{ 0, 0, 8192, 8192}, 0.001f, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
};
static struct vec3 quad[] =
{
- {-1.5f, -0.5f, 0.1f},
- {-1.5f, 0.5f, 0.1f},
- { 0.5f, -0.5f, 0.1f},
- { 0.5f, 0.5f, 0.1f},
+ {-1.5f, -0.5f, 1.0f},
+ {-1.5f, 0.5f, 1.0f},
+ { 0.5f, -0.5f, 1.0f},
+ { 0.5f, 0.5f, 1.0f},
};
static const struct vec2 rt_sizes[] =
{
@@ -14902,6 +14961,7 @@ static void test_viewport(void)
};
IDirectDrawSurface7 *rt, *ds;
DDSURFACEDESC2 surface_desc;
+ const float z_eps = 0.0001;
IDirect3DDevice7 *device;
IDirectDraw7 *ddraw;
DDPIXELFORMAT z_fmt;
@@ -14921,18 +14981,16 @@ static void test_viewport(void)
}
hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
- ok(SUCCEEDED(hr), "Failed to get Direct3D7 interface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
- ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
IDirect3D7_Release(d3d);
- hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE);
- ok(SUCCEEDED(hr), "Failed to disable depth test, hr %#x.\n", hr);
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
- ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetViewport(device, NULL);
- ok(hr == E_INVALIDARG, "Setting NULL viewport data returned unexpected hr %#x.\n", hr);
+ ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
ds = get_depth_stencil(device);
memset(&surface_desc, 0, sizeof(surface_desc));
@@ -14951,56 +15009,79 @@ static void test_viewport(void)
surface_desc.dwHeight = rt_sizes[i].y;
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &rt, NULL);
- ok(SUCCEEDED(hr), "Failed to create render target, hr %#x (i %u).\n", hr, i);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u).\n", hr, i);
surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
U4(surface_desc).ddpfPixelFormat = z_fmt;
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &ds, NULL);
- ok(SUCCEEDED(hr), "Failed to create depth buffer, hr %#x (i %u).\n", hr, i);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u).\n", hr, i);
hr = IDirectDrawSurface7_AddAttachedSurface(rt, ds);
- ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x (i %u).\n", hr, i);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u).\n", hr, i);
hr = IDirect3DDevice7_SetRenderTarget(device, rt, 0);
- ok(SUCCEEDED(hr), "Failed to set render target, hr %#x (i %u).\n", hr, i);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u).\n", hr, i);
}
else
{
hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
- ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u).\n", hr, i);
}
for (j = 0; j < ARRAY_SIZE(tests); ++j)
{
- hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);
- ok(SUCCEEDED(hr), "Failed to clear, hr %#x (i %u, j %u).\n", hr, i, j);
+ hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000,
+ tests[j].expected_z - z_eps, 0);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_GREATER);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, !i);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
hr = IDirect3DDevice7_SetViewport(device, &tests[j].vp);
if (tests[j].vp.dwX + tests[j].vp.dwWidth > rt_sizes[i].x
|| tests[j].vp.dwY + tests[j].vp.dwHeight > rt_sizes[i].y)
{
- ok(hr == E_INVALIDARG, "Setting the viewport returned unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+ ok(hr == E_INVALIDARG, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
continue;
}
else
{
- ok(SUCCEEDED(hr), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr, i, j);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
}
hr = IDirect3DDevice7_BeginScene(device);
- ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr, i, j);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ, quad, 4, 0);
- ok(SUCCEEDED(hr), "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
hr = IDirect3DDevice7_EndScene(device);
- ok(SUCCEEDED(hr), "Failed to end scene, hr %#x (i %u, j %u).\n", hr, i, j);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
check_rect(rt, tests[j].expected_rect, tests[j].message);
+
+ if (!i)
+ {
+ hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000,
+ tests[j].expected_z + z_eps, 0);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESS);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+
+ hr = IDirect3DDevice7_BeginScene(device);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ, quad, 4, 0);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+ hr = IDirect3DDevice7_EndScene(device);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
+
+ check_rect(rt, tests[j].expected_rect, tests[j].message);
+ }
}
hr = IDirectDrawSurface7_DeleteAttachedSurface(rt, 0, ds);
- ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x (i %u).\n", hr, i);
+ ok(hr == DD_OK, "Got unexpected hr %#x (i %u).\n", hr, i);
IDirectDrawSurface7_Release(ds);
-
IDirectDrawSurface7_Release(rt);
}
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 3049be69ef..d017a54245 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3573,6 +3573,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
struct lights_settings ls;
unsigned int vertex_size;
BOOL do_clip, lighting;
+ float min_z, max_z;
unsigned int i;
BYTE *dest_ptr;
HRESULT hr;
@@ -3656,6 +3657,8 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
init_transformed_lights(&ls, state, device->adapter->d3d_info.wined3d_creation_flags
& WINED3D_LEGACY_FFP_LIGHTING, lighting);
+ wined3d_viewport_get_z_range(&vp, &min_z, &max_z);
+
for (i = 0; i < dwCount; ++i)
{
const struct wined3d_stream_info_element *position_element = &stream_info->elements[WINED3D_FFP_POSITION];
@@ -3728,11 +3731,11 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
x *= vp.width / 2;
y *= vp.height / 2;
- z *= vp.max_z - vp.min_z;
+ z *= max_z - min_z;
x += vp.width / 2 + vp.x;
y += vp.height / 2 + vp.y;
- z += vp.min_z;
+ z += min_z;
rhw = 1 / rhw;
} else {
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 0f84cc22f7..87e1ca4bac 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4037,6 +4037,7 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
{
const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS];
+ float min_z, max_z;
if (gl_info->supported[ARB_VIEWPORT_ARRAY])
{
@@ -4048,8 +4049,9 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
get_viewports(context, state, state->viewport_count, vp);
for (i = 0; i < state->viewport_count; ++i)
{
- depth_ranges[i * 2] = vp[i].min_z;
- depth_ranges[i * 2 + 1] = vp[i].max_z;
+ wined3d_viewport_get_z_range(&vp[i], &min_z, &max_z);
+ depth_ranges[i * 2] = min_z;
+ depth_ranges[i * 2 + 1] = max_z;
viewports[i * 4] = vp[i].x;
viewports[i * 4 + 1] = vp[i].y;
@@ -4073,7 +4075,8 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
else
{
get_viewports(context, state, 1, vp);
- gl_info->gl_ops.gl.p_glDepthRange(vp[0].min_z, vp[0].max_z);
+ wined3d_viewport_get_z_range(&vp[0], &min_z, &max_z);
+ gl_info->gl_ops.gl.p_glDepthRange(min_z, max_z);
gl_info->gl_ops.gl.p_glViewport(vp[0].x, vp[0].y, vp[0].width, vp[0].height);
}
checkGLcall("setting clip space and viewport");
@@ -4090,6 +4093,7 @@ static void viewport_miscpart_cc(struct wined3d_context *context,
GLdouble depth_ranges[2 * WINED3D_MAX_VIEWPORTS];
GLfloat viewports[4 * WINED3D_MAX_VIEWPORTS];
unsigned int i, reset_count = 0;
+ float min_z, max_z;
get_viewports(context, state, state->viewport_count, vp);
@@ -4097,8 +4101,9 @@ static void viewport_miscpart_cc(struct wined3d_context *context,
for (i = 0; i < state->viewport_count; ++i)
{
- depth_ranges[i * 2] = vp[i].min_z;
- depth_ranges[i * 2 + 1] = vp[i].max_z;
+ wined3d_viewport_get_z_range(&vp[i], &min_z, &max_z);
+ depth_ranges[i * 2] = min_z;
+ depth_ranges[i * 2 + 1] = max_z;
viewports[i * 4] = vp[i].x + pixel_center_offset;
viewports[i * 4 + 1] = vp[i].y + pixel_center_offset;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8ca2e73703..4fca229b92 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -5345,6 +5345,14 @@ static inline BOOL wined3d_resource_check_fbo_attached(const struct wined3d_stat
return FALSE;
}
+static inline void wined3d_viewport_get_z_range(const struct wined3d_viewport *vp, float *min_z, float *max_z)
+{
+ *min_z = vp->min_z;
+
+ /* The magic constant is derived from tests. */
+ *max_z = max(vp->max_z, vp->min_z + 0.001f);
+}
+
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
--
2.23.0
More information about the wine-devel
mailing list