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.
This commit is contained in:
parent
39684c7e3a
commit
ddc29c40e6
@ -45,7 +45,7 @@ IDirect3D8* WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT SDKVersion) {
|
|||||||
|
|
||||||
object->IDirect3D8_iface.lpVtbl = &Direct3D8_Vtbl;
|
object->IDirect3D8_iface.lpVtbl = &Direct3D8_Vtbl;
|
||||||
object->ref = 1;
|
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);
|
TRACE("Created Direct3D object @ %p, WineObj @ %p\n", object, object->WineD3D);
|
||||||
|
|
||||||
|
@ -1445,22 +1445,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(IDirect3DDevice8 *iface,
|
|||||||
return hr;
|
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,
|
static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(IDirect3DDevice8 *iface,
|
||||||
D3DRENDERSTATETYPE State, DWORD Value)
|
D3DRENDERSTATETYPE State, DWORD Value)
|
||||||
{
|
{
|
||||||
IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
|
IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
union
|
|
||||||
{
|
|
||||||
DWORD d;
|
|
||||||
float f;
|
|
||||||
} wined3d_value;
|
|
||||||
|
|
||||||
TRACE("iface %p, state %#x, value %#x.\n", iface, State, 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)
|
switch (State)
|
||||||
{
|
{
|
||||||
case D3DRS_ZBIAS:
|
case D3DRS_ZBIAS:
|
||||||
wined3d_value.f = Value * zbias_factor;
|
hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value);
|
||||||
hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, wined3d_value.d);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1485,11 +1473,6 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(IDirect3DDevice8 *ifac
|
|||||||
{
|
{
|
||||||
IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
|
IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
union
|
|
||||||
{
|
|
||||||
DWORD d;
|
|
||||||
float f;
|
|
||||||
} wined3d_value;
|
|
||||||
|
|
||||||
TRACE("iface %p, state %#x, value %p.\n", iface, State, pValue);
|
TRACE("iface %p, state %#x, value %p.\n", iface, State, pValue);
|
||||||
|
|
||||||
@ -1497,8 +1480,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(IDirect3DDevice8 *ifac
|
|||||||
switch (State)
|
switch (State)
|
||||||
{
|
{
|
||||||
case D3DRS_ZBIAS:
|
case D3DRS_ZBIAS:
|
||||||
hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, &wined3d_value.d);
|
hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, pValue);
|
||||||
if (SUCCEEDED(hr)) *pValue = (DWORD)(wined3d_value.f / zbias_factor);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -6060,7 +6060,8 @@ HRESULT ddraw_init(IDirectDrawImpl *ddraw, WINED3DDEVTYPE device_type)
|
|||||||
ddraw->orig_width = GetSystemMetrics(SM_CXSCREEN);
|
ddraw->orig_width = GetSystemMetrics(SM_CXSCREEN);
|
||||||
ddraw->orig_height = GetSystemMetrics(SM_CYSCREEN);
|
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)
|
if (!ddraw->wineD3D)
|
||||||
{
|
{
|
||||||
WARN("Failed to create a wined3d object.\n");
|
WARN("Failed to create a wined3d object.\n");
|
||||||
|
@ -2261,12 +2261,8 @@ static HRESULT WINAPI IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface, DWORD d
|
|||||||
* DDERR_INVALIDPARAMS if Value == NULL
|
* 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;
|
IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@ -2383,18 +2379,8 @@ IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case D3DRENDERSTATE_ZBIAS:
|
case D3DRENDERSTATE_ZBIAS:
|
||||||
{
|
hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value);
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
|
if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
|
||||||
@ -2703,16 +2689,8 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case D3DRENDERSTATE_ZBIAS:
|
case D3DRENDERSTATE_ZBIAS:
|
||||||
{
|
hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
|
if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
|
||||||
|
@ -1706,7 +1706,8 @@ static void state_depthbias(DWORD state, struct wined3d_stateblock *stateblock,
|
|||||||
if (stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS]
|
if (stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS]
|
||||||
|| stateblock->state.render_states[WINED3DRS_DEPTHBIAS])
|
|| 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;
|
float scale;
|
||||||
|
|
||||||
union
|
union
|
||||||
@ -1721,23 +1722,34 @@ static void state_depthbias(DWORD state, struct wined3d_stateblock *stateblock,
|
|||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
checkGLcall("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;
|
float bias = -(float)const_bias.d;
|
||||||
scale = powf(2, fmt->depth_size) - 1;
|
glPolygonOffset(bias, bias);
|
||||||
TRACE("Depth format %s, using depthbias scale of %f\n",
|
checkGLcall("glPolygonOffset");
|
||||||
debug_d3dformat(fmt->id), scale);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The context manager will reapply this state on a depth stencil change */
|
if (depth)
|
||||||
TRACE("No depth stencil, using depthbias scale of 0.0\n");
|
{
|
||||||
scale = 0;
|
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);
|
glPolygonOffset(scale_bias.f, const_bias.f * scale);
|
||||||
checkGLcall("glPolygonOffset(...)");
|
checkGLcall("glPolygonOffset(...)");
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
|
checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
|
||||||
}
|
}
|
||||||
|
@ -1236,6 +1236,7 @@ enum wined3d_sysval_semantic
|
|||||||
#define WINED3DDEVCAPS_NPATCHES 0x01000000
|
#define WINED3DDEVCAPS_NPATCHES 0x01000000
|
||||||
|
|
||||||
#define WINED3D_PALETTE_PER_SURFACE 0x00000001
|
#define WINED3D_PALETTE_PER_SURFACE 0x00000001
|
||||||
|
#define WINED3D_LEGACY_DEPTH_BIAS 0x00000002
|
||||||
|
|
||||||
/* dwDDFX */
|
/* dwDDFX */
|
||||||
/* arithmetic stretching along y axis */
|
/* arithmetic stretching along y axis */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user