diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 159d3f36334..c913a590dab 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -766,7 +766,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3 wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILFAIL, front->StencilFailOp); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILZFAIL, front->StencilDepthFailOp); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILPASS, front->StencilPassOp); - wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILFUNC, front->StencilFunc); if (front->StencilFailOp != back->StencilFailOp || front->StencilDepthFailOp != back->StencilDepthFailOp || front->StencilPassOp != back->StencilPassOp @@ -777,7 +776,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3 wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BACK_STENCILZFAIL, back->StencilDepthFailOp); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BACK_STENCILPASS, back->StencilPassOp); - wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BACK_STENCILFUNC, back->StencilFunc); } else { diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index c0be2fe592b..14d91c68e86 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -799,6 +799,8 @@ HRESULT d3d_depthstencil_state_create(struct d3d_device *device, const D3D11_DEP wined3d_desc.stencil = desc->StencilEnable; wined3d_desc.stencil_read_mask = desc->StencilReadMask; wined3d_desc.stencil_write_mask = desc->StencilWriteMask; + wined3d_desc.front.func = desc->FrontFace.StencilFunc; + wined3d_desc.back.func = desc->BackFace.StencilFunc; /* We cannot fail after creating a wined3d_depth_stencil_state object. It * would lead to double free. */ diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 80b06482e64..4ab21cd7998 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -120,13 +120,11 @@ static const struct wined3d_state_entry_template misc_state_template_vk[] = {STATE_RENDER(WINED3D_RS_STENCILFAIL), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, {STATE_RENDER(WINED3D_RS_STENCILZFAIL), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, {STATE_RENDER(WINED3D_RS_STENCILPASS), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, - {STATE_RENDER(WINED3D_RS_STENCILFUNC), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, {STATE_RENDER(WINED3D_RS_STENCILREF), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, {STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, {STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, {STATE_RENDER(WINED3D_RS_BACK_STENCILZFAIL), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, {STATE_RENDER(WINED3D_RS_BACK_STENCILPASS), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, - {STATE_RENDER(WINED3D_RS_BACK_STENCILFUNC), {STATE_RENDER(WINED3D_RS_ZFUNC)}}, {STATE_RENDER(WINED3D_RS_WRAP0), {STATE_RENDER(WINED3D_RS_WRAP0), state_nop}}, {STATE_RENDER(WINED3D_RS_WRAP1), {STATE_RENDER(WINED3D_RS_WRAP0)}}, {STATE_RENDER(WINED3D_RS_WRAP2), {STATE_RENDER(WINED3D_RS_WRAP0)}}, diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 26cd3f5a4ef..23b4fcbc90c 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2050,12 +2050,18 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte 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.compareOp = vk_compare_op_from_wined3d(d->desc.front.func); key->ds_desc.front.compareMask = d->desc.stencil_read_mask; key->ds_desc.front.writeMask = d->desc.stencil_write_mask; key->ds_desc.front.reference = state->render_states[WINED3D_RS_STENCILREF] & ((1 << state->fb.depth_stencil->format->stencil_size) - 1); + key->ds_desc.back.compareOp = vk_compare_op_from_wined3d(d->desc.back.func); + key->ds_desc.back.compareMask = d->desc.stencil_read_mask; + key->ds_desc.back.writeMask = d->desc.stencil_write_mask; + key->ds_desc.back.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( @@ -2064,12 +2070,6 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte 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 = d->desc.stencil_read_mask; - key->ds_desc.back.writeMask = d->desc.stencil_write_mask; - key->ds_desc.back.reference = state->render_states[WINED3D_RS_STENCILREF] - & ((1 << state->fb.depth_stencil->format->stencil_size) - 1); } else { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 754dd7693c9..c72ae633fcc 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3685,9 +3685,12 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, set_blend_state = TRUE; break; + case WINED3D_RS_BACK_STENCILFUNC: case WINED3D_RS_STENCILENABLE: + case WINED3D_RS_STENCILFUNC: case WINED3D_RS_STENCILMASK: case WINED3D_RS_STENCILWRITEMASK: + case WINED3D_RS_TWOSIDEDSTENCILMODE: case WINED3D_RS_ZENABLE: case WINED3D_RS_ZWRITEENABLE: set_depth_stencil_state = TRUE; @@ -3847,6 +3850,16 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, desc.stencil = state->rs[WINED3D_RS_STENCILENABLE]; desc.stencil_read_mask = state->rs[WINED3D_RS_STENCILMASK]; desc.stencil_write_mask = state->rs[WINED3D_RS_STENCILWRITEMASK]; + desc.front.func = state->rs[WINED3D_RS_STENCILFUNC]; + + if (state->rs[WINED3D_RS_TWOSIDEDSTENCILMODE]) + { + desc.back.func = state->rs[WINED3D_RS_BACK_STENCILFUNC]; + } + else + { + desc.back = desc.front; + } if ((entry = wine_rb_get(&device->depth_stencil_states, &desc))) { diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c168e25ee88..c97d47cab8f 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2446,13 +2446,11 @@ static const struct wined3d_state_entry_template misc_state_template_no3d[] = {STATE_RENDER(WINED3D_RS_STENCILFAIL), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_STENCILZFAIL), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_STENCILPASS), {STATE_VDECL}}, - {STATE_RENDER(WINED3D_RS_STENCILFUNC), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_STENCILREF), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_BACK_STENCILZFAIL), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_BACK_STENCILPASS), {STATE_VDECL}}, - {STATE_RENDER(WINED3D_RS_BACK_STENCILFUNC), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_WRAP0), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_WRAP1), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_WRAP2), {STATE_VDECL}}, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 4a1a7c80b8f..1819155fae3 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1078,9 +1078,9 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ } twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE]; - if (!(func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC]))) + if (!(func = wined3d_gl_compare_func(d->desc.front.func))) func = GL_ALWAYS; - if (!(func_back = wined3d_gl_compare_func(state->render_states[WINED3D_RS_BACK_STENCILFUNC]))) + if (!(func_back = wined3d_gl_compare_func(d->desc.back.func))) func_back = GL_ALWAYS; mask = d->desc.stencil_read_mask; ref = state->render_states[WINED3D_RS_STENCILREF] & ((1 << state->fb.depth_stencil->format->stencil_size) - 1); @@ -4769,13 +4769,11 @@ const struct wined3d_state_entry_template misc_state_template_gl[] = { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_BACK_STENCILZFAIL), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_BACK_STENCILPASS), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_BACK_STENCILFUNC), { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, @@ -5575,6 +5573,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 42, 45}, { 47, 47}, { 52, 52}, + { 56, 56}, { 58, 59}, { 61, 127}, {149, 150}, @@ -5582,7 +5581,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) {168, 169}, {171, 171}, {174, 177}, - {190, 193}, + {189, 193}, {195, 197}, {206, 209}, { 0, 0}, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index f77f7dec7eb..f9a4402873f 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2036,6 +2036,11 @@ struct wined3d_blend_state_desc } rt[WINED3D_MAX_RENDER_TARGETS]; }; +struct wined3d_stencil_op_desc +{ + enum wined3d_cmp_func func; +}; + struct wined3d_depth_stencil_state_desc { BOOL depth; @@ -2043,6 +2048,8 @@ struct wined3d_depth_stencil_state_desc BOOL stencil; unsigned int stencil_read_mask; unsigned int stencil_write_mask; + struct wined3d_stencil_op_desc front; + struct wined3d_stencil_op_desc back; }; struct wined3d_rasterizer_state_desc