[PATCH 1/5] wined3d: Make D3DRS_ZBIAS work.

Henri Verbeet hverbeet at codeweavers.com
Mon Jul 4 14:39:35 CDT 2011


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 9b1ad37..7e7da43 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 ebab791..c4d4ea9 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 34b4dbd..bde3703 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 85f9dda..b395272 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 bb2b292..ab6a7d7 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 6a01f87..544feae 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 */
-- 
1.7.3.4




More information about the wine-patches mailing list