From ddc29c40e66f686190a40ac4bc2578e81785f56f Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 4 Jul 2011 21:39:35 +0200 Subject: [PATCH] wined3d: Make D3DRS_ZBIAS work. D3DRS_ZBIAS is poorly defined, but it makes sense that the bias should be format independent. Looking at application behaviour, it seems to include a slope scale factor as well. This fixes a couple of regressions introduced by 96b758f7b37033bf382ce40dd3310965d3ac3f76, although it was broken before as well, just in a different way. --- dlls/d3d8/d3d8_main.c | 2 +- dlls/d3d8/device.c | 22 ++-------------------- dlls/ddraw/ddraw.c | 3 ++- dlls/ddraw/device.c | 30 ++++-------------------------- dlls/wined3d/state.c | 38 +++++++++++++++++++++++++------------- include/wine/wined3d.h | 1 + 6 files changed, 35 insertions(+), 61 deletions(-) diff --git a/dlls/d3d8/d3d8_main.c b/dlls/d3d8/d3d8_main.c index 9b1ad37c987..7e7da43807a 100644 --- a/dlls/d3d8/d3d8_main.c +++ b/dlls/d3d8/d3d8_main.c @@ -45,7 +45,7 @@ IDirect3D8* WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT SDKVersion) { object->IDirect3D8_iface.lpVtbl = &Direct3D8_Vtbl; object->ref = 1; - object->WineD3D = wined3d_create(8, 0, &object->IDirect3D8_iface); + object->WineD3D = wined3d_create(8, WINED3D_LEGACY_DEPTH_BIAS, &object->IDirect3D8_iface); TRACE("Created Direct3D object @ %p, WineObj @ %p\n", object, object->WineD3D); diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index ebab791d96c..c4d4ea9860e 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -1445,22 +1445,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(IDirect3DDevice8 *iface, return hr; } -/* This factor is the result of a trial-and-error search. Both ZBIAS and DEPTHBIAS require - * guesswork by design. d3d9 apps usually use a DEPTHBIAS of -0.00002(Mass Effect 2, WoW). - * d3d8 apps(Final Fantasy XI) set ZBIAS to 15 and still expect the depth test to sort - * objects properly. */ -static const float zbias_factor = -0.000005f; - static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(IDirect3DDevice8 *iface, D3DRENDERSTATETYPE State, DWORD Value) { IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface); HRESULT hr; - union - { - DWORD d; - float f; - } wined3d_value; TRACE("iface %p, state %#x, value %#x.\n", iface, State, Value); @@ -1468,8 +1457,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(IDirect3DDevice8 *ifac switch (State) { case D3DRS_ZBIAS: - wined3d_value.f = Value * zbias_factor; - hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, wined3d_value.d); + hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value); break; default: @@ -1485,11 +1473,6 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(IDirect3DDevice8 *ifac { IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface); HRESULT hr; - union - { - DWORD d; - float f; - } wined3d_value; TRACE("iface %p, state %#x, value %p.\n", iface, State, pValue); @@ -1497,8 +1480,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(IDirect3DDevice8 *ifac switch (State) { case D3DRS_ZBIAS: - hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, &wined3d_value.d); - if (SUCCEEDED(hr)) *pValue = (DWORD)(wined3d_value.f / zbias_factor); + hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, pValue); break; default: diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 34b4dbdb29c..bde37033dd1 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -6060,7 +6060,8 @@ HRESULT ddraw_init(IDirectDrawImpl *ddraw, WINED3DDEVTYPE device_type) ddraw->orig_width = GetSystemMetrics(SM_CXSCREEN); ddraw->orig_height = GetSystemMetrics(SM_CYSCREEN); - ddraw->wineD3D = wined3d_create(7, WINED3D_PALETTE_PER_SURFACE, &ddraw->IDirectDraw7_iface); + ddraw->wineD3D = wined3d_create(7, WINED3D_PALETTE_PER_SURFACE | WINED3D_LEGACY_DEPTH_BIAS, + &ddraw->IDirectDraw7_iface); if (!ddraw->wineD3D) { WARN("Failed to create a wined3d object.\n"); diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 85f9dda600f..b395272c9cb 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -2261,12 +2261,8 @@ static HRESULT WINAPI IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface, DWORD d * DDERR_INVALIDPARAMS if Value == NULL * *****************************************************************************/ -static const float zbias_factor = -0.000005f; - -static HRESULT -IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, - D3DRENDERSTATETYPE RenderStateType, - DWORD *Value) +static HRESULT IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, + D3DRENDERSTATETYPE RenderStateType, DWORD *Value) { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; HRESULT hr; @@ -2383,18 +2379,8 @@ IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, break; case D3DRENDERSTATE_ZBIAS: - { - union - { - DWORD d; - float f; - } wined3d_value; - - hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, &wined3d_value.d); - if (SUCCEEDED(hr)) - *Value = wined3d_value.f / zbias_factor; + hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value); break; - } default: if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00 @@ -2703,16 +2689,8 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, break; case D3DRENDERSTATE_ZBIAS: - { - union - { - DWORD d; - float f; - } wined3d_value; - wined3d_value.f = Value * zbias_factor; - hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, wined3d_value.d); + hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value); break; - } default: if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00 diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index bb2b292209d..ab6a7d73a1a 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1706,7 +1706,8 @@ static void state_depthbias(DWORD state, struct wined3d_stateblock *stateblock, if (stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS] || stateblock->state.render_states[WINED3DRS_DEPTHBIAS]) { - struct wined3d_surface *depth = stateblock->device->fb.depth_stencil; + const struct wined3d_device *device = stateblock->device; + const struct wined3d_surface *depth = device->fb.depth_stencil; float scale; union @@ -1721,23 +1722,34 @@ static void state_depthbias(DWORD state, struct wined3d_stateblock *stateblock, glEnable(GL_POLYGON_OFFSET_FILL); checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)"); - if (depth) + if (device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS) { - const struct wined3d_format *fmt = depth->resource.format; - scale = powf(2, fmt->depth_size) - 1; - TRACE("Depth format %s, using depthbias scale of %f\n", - debug_d3dformat(fmt->id), scale); + float bias = -(float)const_bias.d; + glPolygonOffset(bias, bias); + checkGLcall("glPolygonOffset"); } else { - /* The context manager will reapply this state on a depth stencil change */ - TRACE("No depth stencil, using depthbias scale of 0.0\n"); - scale = 0; - } + if (depth) + { + const struct wined3d_format *fmt = depth->resource.format; + scale = powf(2, fmt->depth_size) - 1; + TRACE("Depth format %s, using depthbias scale of %.8e.\n", + debug_d3dformat(fmt->id), scale); + } + else + { + /* The context manager will reapply this state on a depth stencil change */ + TRACE("No depth stencil, using depthbias scale of 0.0.\n"); + scale = 0.0f; + } - glPolygonOffset(scale_bias.f, const_bias.f * scale); - checkGLcall("glPolygonOffset(...)"); - } else { + glPolygonOffset(scale_bias.f, const_bias.f * scale); + checkGLcall("glPolygonOffset(...)"); + } + } + else + { glDisable(GL_POLYGON_OFFSET_FILL); checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)"); } diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 6a01f87a267..544feaee6c4 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1236,6 +1236,7 @@ enum wined3d_sysval_semantic #define WINED3DDEVCAPS_NPATCHES 0x01000000 #define WINED3D_PALETTE_PER_SURFACE 0x00000001 +#define WINED3D_LEGACY_DEPTH_BIAS 0x00000002 /* dwDDFX */ /* arithmetic stretching along y axis */