From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/d3d8/device.c | 1 + dlls/d3d9/device.c | 1 + dlls/ddraw/device.c | 3 +++ dlls/ddraw/surface.c | 5 +++++ dlls/wined3d/stateblock.c | 17 ++++++++++++++++- dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 1 + 7 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 8a1393909d3..b5bf370790a 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -1601,6 +1601,7 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface, wined3d_device_context_set_depth_stencil_view(device->immediate_context, original_dsv); } d3d8_surface_release_rendertarget_view(rt_impl, rtv); + wined3d_stateblock_depth_buffer_changed(device->state); }
wined3d_mutex_unlock(); diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index e9499a3be9b..3ba5764af60 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -2200,6 +2200,7 @@ static HRESULT WINAPI d3d9_device_SetDepthStencilSurface(IDirect3DDevice9Ex *ifa wined3d_mutex_lock(); rtv = ds_impl ? d3d9_surface_acquire_rendertarget_view(ds_impl) : NULL; hr = wined3d_device_context_set_depth_stencil_view(device->immediate_context, rtv); + wined3d_stateblock_depth_buffer_changed(device->state); d3d9_surface_release_rendertarget_view(ds_impl, rtv); wined3d_mutex_unlock();
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 399857adf9d..360f93b516b 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -3410,6 +3410,7 @@ static void d3d_device_sync_rendertarget(struct d3d_device *device) dsv = device->target_ds ? ddraw_surface_get_rendertarget_view(device->target_ds) : NULL; if (FAILED(wined3d_device_context_set_depth_stencil_view(device->immediate_context, dsv))) ERR("wined3d_device_context_set_depth_stencil_view failed.\n"); + wined3d_stateblock_depth_buffer_changed(device->state);
if (device->hardware_device) return; @@ -6820,6 +6821,7 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device { TRACE("Setting wined3d depth stencil to NULL\n"); wined3d_device_context_set_depth_stencil_view(device->immediate_context, NULL); + wined3d_stateblock_depth_buffer_changed(device->state); device->target_ds = NULL; return WINED3D_ZB_FALSE; } @@ -6827,6 +6829,7 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device device->target_ds = impl_from_IDirectDrawSurface7(depthStencil); wined3d_device_context_set_depth_stencil_view(device->immediate_context, ddraw_surface_get_rendertarget_view(device->target_ds)); + wined3d_stateblock_depth_buffer_changed(device->state);
IDirectDrawSurface7_Release(depthStencil); return WINED3D_ZB_TRUE; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 179262a629e..8cdaa48b753 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -2191,6 +2191,7 @@ static HRESULT ddraw_surface_delete_attached_surface(struct ddraw_surface *surfa { struct wined3d_rendertarget_view *dsv; struct ddraw_surface *prev = surface; + struct d3d_device *device;
TRACE("surface %p, attachment %p, detach_iface %p.\n", surface, attachment, detach_iface);
@@ -2239,7 +2240,11 @@ static HRESULT ddraw_surface_delete_attached_surface(struct ddraw_surface *surfa * but don't cleanup properly after the relevant dll is unloaded. */ dsv = wined3d_device_context_get_depth_stencil_view(surface->ddraw->immediate_context); if (attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER && dsv == attachment->wined3d_rtv) + { wined3d_device_context_set_depth_stencil_view(surface->ddraw->immediate_context, NULL); + LIST_FOR_EACH_ENTRY(device, &surface->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) + wined3d_stateblock_depth_buffer_changed(device->state); + } wined3d_mutex_unlock();
/* Set attached_iface to NULL before releasing it, the surface may go diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 9e10dbafb10..80c1a6ea5b7 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -3560,7 +3560,8 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, float x_offset = (-(2.0f * x) - w) / w; float y_scale = 2.0f / -h; float y_offset = (-(2.0f * y) - h) / -h; - float z_scale = state->rs[WINED3D_RS_ZENABLE] ? 1.0f : 0.0f; + bool depth = (state->rs[WINED3D_RS_ZENABLE] && context->state->fb.depth_stencil); + float z_scale = depth ? 1.0f : 0.0f; const struct wined3d_matrix matrix = { x_scale, 0.0f, 0.0f, 0.0f, @@ -3926,3 +3927,17 @@ void CDECL wined3d_stateblock_texture_changed(struct wined3d_stateblock *statebl stateblock->changed.textures |= (1u << i); } } + +void CDECL wined3d_stateblock_depth_buffer_changed(struct wined3d_stateblock *stateblock) +{ + struct wined3d_vertex_declaration *decl = stateblock->stateblock_state.vertex_declaration; + + /* The presence of a depth buffer affects depth clipping when drawing RHW. + * The depth buffer is not part of the stateblock, though, so we need a + * separate function to invalidate it. + * We pass this via the projection matrix, but use + * changed->position_transformed to invalidate it. */ + + if (decl && decl->position_transformed) + stateblock->changed.position_transformed = 1; +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 4d19e6d975f..16c7624eb9c 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -232,6 +232,7 @@ @ cdecl wined3d_stateblock_capture(ptr ptr) @ cdecl wined3d_stateblock_create(ptr ptr long ptr) @ cdecl wined3d_stateblock_decref(ptr) +@ cdecl wined3d_stateblock_depth_buffer_changed(ptr) @ cdecl wined3d_stateblock_get_light(ptr long ptr ptr) @ cdecl wined3d_stateblock_get_ps_consts_b(ptr long long ptr) @ cdecl wined3d_stateblock_get_ps_consts_f(ptr long long ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 73af1be484b..b9ae23bac16 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2760,6 +2760,7 @@ void __cdecl wined3d_stateblock_capture(struct wined3d_stateblock *stateblock, HRESULT __cdecl wined3d_stateblock_create(struct wined3d_device *device, const struct wined3d_stateblock *device_state, enum wined3d_stateblock_type type, struct wined3d_stateblock **stateblock); ULONG __cdecl wined3d_stateblock_decref(struct wined3d_stateblock *stateblock); +void __cdecl wined3d_stateblock_depth_buffer_changed(struct wined3d_stateblock *stateblock); HRESULT __cdecl wined3d_stateblock_get_light(const struct wined3d_stateblock *stateblock, UINT light_idx, struct wined3d_light *light, BOOL *enabled); HRESULT __cdecl wined3d_stateblock_get_ps_consts_b(struct wined3d_stateblock *stateblock,