From 690ff3dbea5748b5a503981447f8efe3b6d93cdf Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Fri, 25 Sep 2020 16:01:25 -0500 Subject: [PATCH] wined3d: Move the stencil write mask to wined3d_depth_stencil_state. Signed-off-by: Zebediah Figura Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/d3d11/device.c | 1 - dlls/d3d11/state.c | 1 + dlls/wined3d/adapter_vk.c | 1 - dlls/wined3d/context_vk.c | 4 +-- dlls/wined3d/cs.c | 1 - dlls/wined3d/device.c | 2 ++ dlls/wined3d/directx.c | 1 - dlls/wined3d/state.c | 69 +++++++++++++++++++++++---------------- dlls/wined3d/texture.c | 4 +-- include/wine/wined3d.h | 1 + 10 files changed, 48 insertions(+), 37 deletions(-) diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 7ed8dc8bd71..159d3f36334 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -761,7 +761,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3 if (desc->StencilEnable) { - wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILWRITEMASK, desc->StencilWriteMask); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILREF, stencil_ref); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILFAIL, front->StencilFailOp); diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 78540d35117..c0be2fe592b 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -798,6 +798,7 @@ HRESULT d3d_depthstencil_state_create(struct d3d_device *device, const D3D11_DEP wined3d_desc.depth_write = desc->DepthWriteMask; wined3d_desc.stencil = desc->StencilEnable; wined3d_desc.stencil_read_mask = desc->StencilReadMask; + wined3d_desc.stencil_write_mask = desc->StencilWriteMask; /* 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 ee5390006a0..80b06482e64 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -122,7 +122,6 @@ static const struct wined3d_state_entry_template misc_state_template_vk[] = {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_STENCILWRITEMASK), {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)}}, diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index f91a1e2e8e9..26cd3f5a4ef 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2052,7 +2052,7 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte 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 = d->desc.stencil_read_mask; - key->ds_desc.front.writeMask = state->render_states[WINED3D_RS_STENCILWRITEMASK]; + 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); @@ -2067,7 +2067,7 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte 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 = state->render_states[WINED3D_RS_STENCILWRITEMASK]; + 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); } diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 66a67ce239b..48b73a71fe4 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1227,7 +1227,6 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const { /* Swapping NULL / non NULL depth stencil affects the depth and tests */ device_invalidate_state(device, STATE_DEPTH_STENCIL); - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); device_invalidate_state(device, STATE_RASTERIZER); } else if (prev) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 054fc528383..754dd7693c9 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3687,6 +3687,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, case WINED3D_RS_STENCILENABLE: case WINED3D_RS_STENCILMASK: + case WINED3D_RS_STENCILWRITEMASK: case WINED3D_RS_ZENABLE: case WINED3D_RS_ZWRITEENABLE: set_depth_stencil_state = TRUE; @@ -3845,6 +3846,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, desc.depth_write = state->rs[WINED3D_RS_ZWRITEENABLE]; 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]; if ((entry = wine_rb_get(&device->depth_stencil_states, &desc))) { diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 49b14228466..c168e25ee88 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2448,7 +2448,6 @@ static const struct wined3d_state_entry_template misc_state_template_no3d[] = {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_STENCILWRITEMASK), {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}}, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 32076289ac6..4a1a7c80b8f 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1158,30 +1158,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ } } -static void state_stencilwrite2s_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; - const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; - - GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); - checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); - gl_info->gl_ops.gl.p_glStencilMask(mask); - checkGLcall("glStencilMask"); - GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT)); - checkGLcall("glActiveStencilFaceEXT(GL_FRONT)"); - gl_info->gl_ops.gl.p_glStencilMask(mask); -} - -static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; - const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; - - gl_info->gl_ops.gl.p_glStencilMask(mask); - checkGLcall("glStencilMask"); -} - -static void depth_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void depth(struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; const struct wined3d_depth_stencil_state *d = state->depth_stencil_state; @@ -1215,12 +1192,47 @@ static void depth_stencil(struct wined3d_context *context, const struct wined3d_ checkGLcall("glDepthMask(GL_FALSE)"); } - state_stencil(context, state); - if (context->last_was_rhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))) context_apply_state(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); } +static void depth_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + const struct wined3d_depth_stencil_state *d = state->depth_stencil_state; + GLuint stencil_write_mask = 0; + + depth(context, state); + state_stencil(context, state); + + if (state->fb.depth_stencil) + stencil_write_mask = d ? d->desc.stencil_write_mask : ~0u; + + gl_info->gl_ops.gl.p_glStencilMask(stencil_write_mask); + checkGLcall("glStencilMask"); +} + +static void depth_stencil_2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + const struct wined3d_depth_stencil_state *d = state->depth_stencil_state; + GLuint stencil_write_mask = 0; + + depth(context, state); + state_stencil(context, state); + + if (state->fb.depth_stencil) + stencil_write_mask = d ? d->desc.stencil_write_mask : ~0u; + + GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); + checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); + gl_info->gl_ops.gl.p_glStencilMask(stencil_write_mask); + checkGLcall("glStencilMask"); + GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT)); + checkGLcall("glActiveStencilFaceEXT(GL_FRONT)"); + gl_info->gl_ops.gl.p_glStencilMask(stencil_write_mask); +} + static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; @@ -4667,6 +4679,7 @@ const struct wined3d_state_entry_template misc_state_template_gl[] = { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor_w}, WINED3D_GL_EXT_NONE }, { STATE_SAMPLE_MASK, { STATE_SAMPLE_MASK, state_sample_mask }, ARB_TEXTURE_MULTISAMPLE }, { STATE_SAMPLE_MASK, { STATE_SAMPLE_MASK, state_sample_mask_w }, WINED3D_GL_EXT_NONE }, + { STATE_DEPTH_STENCIL, { STATE_DEPTH_STENCIL, depth_stencil_2s }, EXT_STENCIL_TWO_SIDE }, { STATE_DEPTH_STENCIL, { STATE_DEPTH_STENCIL, depth_stencil }, WINED3D_GL_EXT_NONE }, { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE }, @@ -4758,8 +4771,6 @@ const struct wined3d_state_entry_template misc_state_template_gl[] = { 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_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s_ext}, EXT_STENCIL_TWO_SIDE }, - { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, 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 }, @@ -5564,7 +5575,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 42, 45}, { 47, 47}, { 52, 52}, - { 58, 58}, + { 58, 59}, { 61, 127}, {149, 150}, {162, 162}, diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 911ee0e6262..3381252e75d 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -515,7 +515,7 @@ static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct context_invalidate_state(context, STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE)); } gl_info->gl_ops.gl.p_glStencilMask(~0U); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); + context_invalidate_state(context, STATE_DEPTH_STENCIL); } gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); @@ -5394,7 +5394,7 @@ static void ffp_blitter_clear_rendertargets(struct wined3d_device *device, unsig context_invalidate_state(context, STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE)); } gl_info->gl_ops.gl.p_glStencilMask(~0u); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); + context_invalidate_state(context, STATE_DEPTH_STENCIL); gl_info->gl_ops.gl.p_glClearStencil(stencil); checkGLcall("glClearStencil"); clear_mask = clear_mask | GL_STENCIL_BUFFER_BIT; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index e2db42766fb..f77f7dec7eb 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2042,6 +2042,7 @@ struct wined3d_depth_stencil_state_desc BOOL depth_write; BOOL stencil; unsigned int stencil_read_mask; + unsigned int stencil_write_mask; }; struct wined3d_rasterizer_state_desc