From fd5fc51bc5c2ac203bfba8b84dd23168ba9e1974 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 1 Oct 2013 10:38:30 +0200 Subject: [PATCH] wined3d: Send depth stencil binding updates through the command stream. --- dlls/wined3d/cs.c | 58 ++++++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 33 +------------------ dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 60 insertions(+), 32 deletions(-) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index b18291294e3..3d155f1274b 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -31,6 +31,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_VIEWPORT, WINED3D_CS_OP_SET_SCISSOR_RECT, WINED3D_CS_OP_SET_RENDER_TARGET, + WINED3D_CS_OP_SET_DEPTH_STENCIL, }; struct wined3d_cs_present @@ -84,6 +85,12 @@ struct wined3d_cs_set_render_target struct wined3d_surface *render_target; }; +struct wined3d_cs_set_depth_stencil +{ + enum wined3d_cs_op opcode; + struct wined3d_surface *depth_stencil; +}; + static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_present *op = data; @@ -227,6 +234,56 @@ void wined3d_cs_emit_set_render_target(struct wined3d_cs *cs, UINT render_target cs->ops->submit(cs); } +static void wined3d_cs_exec_set_depth_stencil(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_depth_stencil *op = data; + struct wined3d_device *device = cs->device; + struct wined3d_surface *prev; + + if ((prev = cs->state.fb->depth_stencil)) + { + if (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL + || prev->flags & SFLAG_DISCARD) + { + surface_modify_ds_location(prev, SFLAG_DISCARDED, + prev->resource.width, prev->resource.height); + if (prev == device->onscreen_depth_stencil) + { + wined3d_surface_decref(device->onscreen_depth_stencil); + device->onscreen_depth_stencil = NULL; + } + } + } + + cs->fb.depth_stencil = op->depth_stencil; + + if (!prev != !op->depth_stencil) + { + /* Swapping NULL / non NULL depth stencil affects the depth and tests */ + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE)); + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); + } + else if (prev && prev->resource.format->depth_size != op->depth_stencil->resource.format->depth_size) + { + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); + } + + device_invalidate_state(device, STATE_FRAMEBUFFER); +} + +void wined3d_cs_emit_set_depth_stencil(struct wined3d_cs *cs, struct wined3d_surface *depth_stencil) +{ + struct wined3d_cs_set_depth_stencil *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL; + op->depth_stencil = depth_stencil; + + cs->ops->submit(cs); +} + static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = { /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, @@ -235,6 +292,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, /* WINED3D_CS_OP_SET_RENDER_TARGET */ wined3d_cs_exec_set_render_target, + /* WINED3D_CS_OP_SET_DEPTH_STENCIL */ wined3d_cs_exec_set_depth_stencil, }; static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 46057c3f4f7..12d0239e30f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4054,43 +4054,12 @@ void CDECL wined3d_device_set_depth_stencil(struct wined3d_device *device, struc return; } - if (prev) - { - if (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || prev->flags & SFLAG_DISCARD) - { - surface_modify_ds_location(prev, SFLAG_DISCARDED, - prev->resource.width, prev->resource.height); - if (prev == device->onscreen_depth_stencil) - { - wined3d_surface_decref(device->onscreen_depth_stencil); - device->onscreen_depth_stencil = NULL; - } - } - } - device->fb.depth_stencil = depth_stencil; if (depth_stencil) wined3d_surface_incref(depth_stencil); - - if (!prev != !depth_stencil) - { - /* Swapping NULL / non NULL depth stencil affects the depth and tests */ - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE)); - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); - } - else if (prev && prev->resource.format->depth_size != depth_stencil->resource.format->depth_size) - { - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); - } + wined3d_cs_emit_set_depth_stencil(device->cs, depth_stencil); if (prev) wined3d_surface_decref(prev); - - device_invalidate_state(device, STATE_FRAMEBUFFER); - - return; } HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d8c66b73d77..7409807a387 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2486,6 +2486,7 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region, DWORD flags) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_depth_stencil(struct wined3d_cs *cs, struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_render_target(struct wined3d_cs *cs, UINT render_target_idx, struct wined3d_surface *render_target) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) DECLSPEC_HIDDEN;