[PATCH 5/5] wined3d: Add support for half-integer pixel centers.

Henri Verbeet hverbeet at codeweavers.com
Mon Mar 30 02:17:05 CDT 2015


Like in OpenGL and Direct3D 10+.
---
 dlls/d3d8/directx.c            |    3 ++-
 dlls/d3d9/directx.c            |    2 +-
 dlls/ddraw/ddraw.c             |    7 ++-----
 dlls/ddraw/ddraw_private.h     |    3 +++
 dlls/ddraw/main.c              |    4 ++--
 dlls/wined3d/utils.c           |   21 ++++++++++++++-------
 dlls/wined3d/wined3d_private.h |   11 +++++++++--
 include/wine/wined3d.h         |    1 +
 8 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c
index 75c8218..132a56f 100644
--- a/dlls/d3d8/directx.c
+++ b/dlls/d3d8/directx.c
@@ -402,7 +402,8 @@ static const struct IDirect3D8Vtbl d3d8_vtbl =
 
 BOOL d3d8_init(struct d3d8 *d3d8)
 {
-    DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING | WINED3D_HANDLE_RESTORE;
+    DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
+            | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER;
 
     d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
     d3d8->refcount = 1;
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index 6059890..58c4d44 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -636,7 +636,7 @@ static const struct IDirect3D9ExVtbl d3d9_vtbl =
 
 BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
 {
-    DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE;
+    DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER;
 
     if (!extended)
         flags |= WINED3D_VIDMEM_ACCOUNTING;
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 02b2f6e..31ec6bf 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -4835,7 +4835,6 @@ static const struct wined3d_device_parent_ops ddraw_wined3d_device_parent_ops =
 HRESULT ddraw_init(struct ddraw *ddraw, enum wined3d_device_type device_type)
 {
     WINED3DCAPS caps;
-    DWORD flags;
     HRESULT hr;
 
     ddraw->IDirectDraw7_iface.lpVtbl = &ddraw7_vtbl;
@@ -4850,11 +4849,9 @@ HRESULT ddraw_init(struct ddraw *ddraw, enum wined3d_device_type device_type)
     ddraw->numIfaces = 1;
     ddraw->ref7 = 1;
 
-    flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
-            | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES;
-    if (!(ddraw->wined3d = wined3d_create(flags)))
+    if (!(ddraw->wined3d = wined3d_create(DDRAW_WINED3D_FLAGS)))
     {
-        if (!(ddraw->wined3d = wined3d_create(flags | WINED3D_NO3D)))
+        if (!(ddraw->wined3d = wined3d_create(DDRAW_WINED3D_FLAGS | WINED3D_NO3D)))
         {
             WARN("Failed to create a wined3d object.\n");
             return E_FAIL;
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 4a883b9..650b2c7 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -59,6 +59,9 @@ struct FvfToDecl
 
 #define DDRAW_STRIDE_ALIGNMENT  8
 
+#define DDRAW_WINED3D_FLAGS     (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \
+        | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER)
+
 enum ddraw_device_state
 {
     DDRAW_DEVICE_STATE_OK,
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 021c2b9..2f5d113 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -405,9 +405,9 @@ HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA callback, void *contex
         FIXME("flags 0x%08x not handled\n", flags & ~DDENUM_ATTACHEDSECONDARYDEVICES);
 
     TRACE("Enumerating ddraw interfaces\n");
-    if (!(wined3d = wined3d_create(WINED3D_LEGACY_DEPTH_BIAS)))
+    if (!(wined3d = wined3d_create(DDRAW_WINED3D_FLAGS)))
     {
-        if (!(wined3d = wined3d_create(WINED3D_LEGACY_DEPTH_BIAS | WINED3D_NO3D)))
+        if (!(wined3d = wined3d_create(DDRAW_WINED3D_FLAGS | WINED3D_NO3D)))
         {
             WARN("Failed to create a wined3d object.\n");
             return E_FAIL;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index a772af8..468aea9 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3155,6 +3155,8 @@ void get_modelview_matrix(const struct wined3d_context *context, const struct wi
 void get_projection_matrix(const struct wined3d_context *context, const struct wined3d_state *state,
         struct wined3d_matrix *mat)
 {
+    float center_offset;
+
     /* There are a couple of additional things we have to take into account
      * here besides the projection transformation itself:
      *   - We need to flip along the y-axis in case of offscreen rendering.
@@ -3170,6 +3172,11 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w
      * driver, but small enough to prevent it from interfering with any
      * anti-aliasing. */
 
+    if (context->swapchain->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER)
+        center_offset = 63.0f / 64.0f;
+    else
+        center_offset = -1.0f / 64.0f;
+
     if (context->last_was_rhw)
     {
         /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
@@ -3178,11 +3185,11 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w
         float w = state->viewport.width;
         float h = state->viewport.height;
         float x_scale = 2.0f / w;
-        float x_offset = (float)((63.0 / 64.0 - (2.0 * x) - w) / w);
+        float x_offset = (center_offset - (2.0f * x) - w) / w;
         float y_scale = context->render_offscreen ? 2.0f / h : 2.0f / -h;
-        float y_offset = (float)(context->render_offscreen
-                ? (63.0 / 64.0 - (2.0 * y) - h) / h
-                : (63.0 / 64.0 - (2.0 * y) - h) / -h);
+        float y_offset = context->render_offscreen
+                ? (center_offset - (2.0f * y) - h) / h
+                : (center_offset - (2.0f * y) - h) / -h;
         enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ?
                 state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE;
         float z_scale = zenable ? 2.0f : 0.0f;
@@ -3200,10 +3207,10 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w
     else
     {
         float y_scale = context->render_offscreen ? -1.0f : 1.0f;
-        float x_offset = 63.0f / 64.0f * (1.0f / state->viewport.width);
+        float x_offset = center_offset / state->viewport.width;
         float y_offset = context->render_offscreen
-                ? 63.0f / 64.0f * (1.0f / state->viewport.height)
-                : -63.0f / 64.0f * (1.0f / state->viewport.height);
+                ? center_offset / state->viewport.height
+                : -center_offset / state->viewport.height;
         const struct wined3d_matrix projection =
         {
                 1.0f,     0.0f,  0.0f, 0.0f,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 96b8244..9287fd7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3009,10 +3009,17 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
 static inline void shader_get_position_fixup(const struct wined3d_context *context,
         const struct wined3d_state *state, float *position_fixup)
 {
+    float center_offset;
+
+    if (context->swapchain->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER)
+        center_offset = 63.0f / 64.0f;
+    else
+        center_offset = -1.0f / 64.0f;
+
     position_fixup[0] = 1.0f;
     position_fixup[1] = 1.0f;
-    position_fixup[2] = (63.0f / 64.0f) / state->viewport.width;
-    position_fixup[3] = -(63.0f / 64.0f) / state->viewport.height;
+    position_fixup[2] = center_offset / state->viewport.width;
+    position_fixup[3] = -center_offset / state->viewport.height;
 
     if (context->render_offscreen)
     {
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 0f70848..8bc4c25 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1247,6 +1247,7 @@ enum wined3d_display_rotation
 #define WINED3D_RESTORE_MODE_ON_ACTIVATE                        0x00000010
 #define WINED3D_FOCUS_MESSAGES                                  0x00000020
 #define WINED3D_HANDLE_RESTORE                                  0x00000040
+#define WINED3D_PIXEL_CENTER_INTEGER                            0x00000080
 
 #define WINED3D_RESZ_CODE                                       0x7fa05000
 
-- 
1.7.10.4




More information about the wine-patches mailing list