[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