wined3d: Add support for half-integer pixel centers.

Like in OpenGL and Direct3D 10+.
This commit is contained in:
Henri Verbeet 2015-03-30 09:17:05 +02:00 committed by Alexandre Julliard
parent d9fbb3f847
commit 94967c28b9
8 changed files with 34 additions and 18 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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)
{

View File

@ -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