From 939e8d25f993eedaefa362f57147f03cd425782a Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 21 May 2020 23:21:35 +0430 Subject: [PATCH] wined3d: Implement stencil tests for the Vulkan adapter. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/context_vk.c | 64 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 00d66ed052b..0157e213816 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -218,6 +218,35 @@ static VkPrimitiveTopology vk_topology_from_wined3d(enum wined3d_primitive_type } } +static VkStencilOp vk_stencil_op_from_wined3d(enum wined3d_stencil_op op) +{ + switch (op) + { + case WINED3D_STENCIL_OP_KEEP: + return VK_STENCIL_OP_KEEP; + case WINED3D_STENCIL_OP_ZERO: + return VK_STENCIL_OP_ZERO; + case WINED3D_STENCIL_OP_REPLACE: + return VK_STENCIL_OP_REPLACE; + case WINED3D_STENCIL_OP_INCR_SAT: + return VK_STENCIL_OP_INCREMENT_AND_CLAMP; + case WINED3D_STENCIL_OP_DECR_SAT: + return VK_STENCIL_OP_DECREMENT_AND_CLAMP; + case WINED3D_STENCIL_OP_INVERT: + return VK_STENCIL_OP_INVERT; + case WINED3D_STENCIL_OP_INCR: + return VK_STENCIL_OP_INCREMENT_AND_WRAP; + case WINED3D_STENCIL_OP_DECR: + return VK_STENCIL_OP_DECREMENT_AND_WRAP; + default: + if (!op) + WARN("Unhandled stencil operation %#x.\n", op); + else + FIXME("Unhandled stencil operation %#x.\n", op); + return VK_STENCIL_OP_KEEP; + } +} + void *wined3d_allocator_chunk_vk_map(struct wined3d_allocator_chunk_vk *chunk_vk, struct wined3d_context_vk *context_vk) { @@ -1811,11 +1840,44 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte update = true; } - if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_RENDER(WINED3D_RS_ZENABLE))) + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_RENDER(WINED3D_RS_ZENABLE)) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER)) { key->ds_desc.depthTestEnable = !!state->render_states[WINED3D_RS_ZENABLE]; key->ds_desc.depthWriteEnable = !!state->render_states[WINED3D_RS_ZWRITEENABLE]; key->ds_desc.depthCompareOp = vk_compare_op_from_wined3d(state->render_states[WINED3D_RS_ZFUNC]); + key->ds_desc.stencilTestEnable = state->fb.depth_stencil && state->render_states[WINED3D_RS_STENCILENABLE]; + if (key->ds_desc.stencilTestEnable) + { + key->ds_desc.front.failOp = vk_stencil_op_from_wined3d(state->render_states[WINED3D_RS_STENCILFAIL]); + key->ds_desc.front.passOp = vk_stencil_op_from_wined3d(state->render_states[WINED3D_RS_STENCILPASS]); + key->ds_desc.front.depthFailOp = vk_stencil_op_from_wined3d(state->render_states[WINED3D_RS_STENCILZFAIL]); + key->ds_desc.front.compareOp = vk_compare_op_from_wined3d(state->render_states[WINED3D_RS_STENCILFUNC]); + key->ds_desc.front.compareMask = state->render_states[WINED3D_RS_STENCILMASK]; + key->ds_desc.front.writeMask = state->render_states[WINED3D_RS_STENCILWRITEMASK]; + key->ds_desc.front.reference = state->render_states[WINED3D_RS_STENCILREF] + & ((1 << state->fb.depth_stencil->format->stencil_size) - 1); + + if (state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE]) + { + key->ds_desc.back.failOp = vk_stencil_op_from_wined3d( + state->render_states[WINED3D_RS_BACK_STENCILFAIL]); + key->ds_desc.back.passOp = vk_stencil_op_from_wined3d( + state->render_states[WINED3D_RS_BACK_STENCILPASS]); + key->ds_desc.back.depthFailOp = vk_stencil_op_from_wined3d( + state->render_states[WINED3D_RS_BACK_STENCILZFAIL]); + key->ds_desc.back.compareOp = vk_compare_op_from_wined3d( + state->render_states[WINED3D_RS_BACK_STENCILFUNC]); + key->ds_desc.back.compareMask = state->render_states[WINED3D_RS_STENCILMASK]; + key->ds_desc.back.writeMask = state->render_states[WINED3D_RS_STENCILWRITEMASK]; + key->ds_desc.back.reference = state->render_states[WINED3D_RS_STENCILREF] + & ((1 << state->fb.depth_stencil->format->stencil_size) - 1); + } + else + { + key->ds_desc.back = key->ds_desc.front; + } + } update = true; }