[PATCH v2 2/5] wined3d: Don't offset the viewport in the !WINED3D_PIXEL_CENTER_INTEGER case.

Matteo Bruni mbruni at codeweavers.com
Tue Feb 12 11:25:58 CST 2019

Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
v2: It turns out this also fixes the existing
test_fractional_viewports() (but only when ARB_clip_control is supported...)

Avoids two failures in (upcoming) d3d11:test_viewport().

My understanding of what's happening is: the affected quad extends to
the left of the viewport bounds and moving the viewport even a tiny
bit to the left makes GL take an extra column of pixels in
consideration. Those pixels are covered by the quad since the pixel
center is inside the quad, so they are drawn.

My reading of the spec doesn't entirely clarify if this is correct /
expected behavior, of course the pixel center of those "extra" pixels
isn't inside the viewport, but part of the pixel is. It looks to me as
the first few lines at
might be interpreted as implying this is actually correct behavior as
far as d3d is concerned and I suspect the hardware to be quite tied to

FWIW decreasing the offset fixes the issue only when the offset is
effectively set to 0.

Of course the offset was added in the first place for a reason,
specifically to force the expected (d3d) top-left rule for triangle
rasterization, since OpenGL leaves that unspecified except for
requiring that only one of two adjacent triangles get to cover any
pixel. I suspect that all the GPUs supporting ARB_clip_control also in
practice make use of the same rule in OpenGL. Also the test should
check that case too and it passes for me on AMD and Nvidia.

If this all seems too much of a hassle I can drop this patch and
update the test accordingly, no worries. I really only wanted to get
to the bottom of the test failure, this patch created itself while
debugging :P

 dlls/d3d11/tests/d3d11.c | 1 -
 dlls/wined3d/state.c     | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 3c870c27e77..c8df7b8c7c4 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -25853,7 +25853,6 @@ static void test_fractional_viewports(void)
                 ok(compare_float(v->x, expected.x, 0) && compare_float(v->y, expected.y, 0),
                         "Got fragcoord {%.8e, %.8e}, expected {%.8e, %.8e} at (%u, %u), offset %.8e.\n",
                         v->x, v->y, expected.x, expected.y, x, y, viewport_offsets[i]);
-                todo_wine
                 ok(compare_float(v->z, expected.z, 2) && compare_float(v->w, expected.w, 2),
                         "Got texcoord {%.8e, %.8e}, expected {%.8e, %.8e} at (%u, %u), offset %.8e.\n",
                         v->z, v->w, expected.z, expected.w, x, y, viewport_offsets[i]);
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 1b5eacdf216..43fef746f11 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4089,7 +4089,7 @@ static void viewport_miscpart_cc(struct wined3d_context *context,
     /* See get_projection_matrix() in utils.c for a discussion about those values. */
     float pixel_center_offset = context->d3d_info->wined3d_creation_flags
-            & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f;
+            & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : 0.0f;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS];
     GLdouble depth_ranges[2 * WINED3D_MAX_VIEWPORTS];

More information about the wine-devel mailing list