From 440459645b082c779e8b6312363aa61463f31398 Mon Sep 17 00:00:00 2001 From: Giancarlo Devich Date: Tue, 11 Apr 2023 16:47:40 -0700 Subject: [PATCH] d3d12: Support separate front/back stencils Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3833 Part-of: --- src/gallium/drivers/d3d12/ci/d3d12-quick_gl.txt | 1 - src/gallium/drivers/d3d12/d3d12_context.cpp | 21 +++++++++++++++++---- src/gallium/drivers/d3d12/d3d12_draw.cpp | 10 ++++++++-- src/gallium/drivers/d3d12/d3d12_pipeline_state.h | 1 + 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/d3d12/ci/d3d12-quick_gl.txt b/src/gallium/drivers/d3d12/ci/d3d12-quick_gl.txt index 3791fd4..ed9ccb8 100644 --- a/src/gallium/drivers/d3d12/ci/d3d12-quick_gl.txt +++ b/src/gallium/drivers/d3d12/ci/d3d12-quick_gl.txt @@ -22,7 +22,6 @@ spec@!opengl 1.1@polygon-mode-offset@config 4: Expected white pixel on top edge, spec@!opengl 1.1@polygon-offset,Fail spec@!opengl 1.1@vertex-fallbacks,Crash spec@!opengl 1.1@windowoverlap,Missing -spec@!opengl 2.0@gl-2.0-two-sided-stencil,Fail spec@!opengl 3.0@sampler-cube-shadow,Fail spec@!opengl 3.1@default-vao,Fail spec@!opengl 3.1@genned-names,Fail diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index 0ba6abd..145f14f 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -437,6 +437,8 @@ stencil_op_state(const struct pipe_stencil_state *src) ret.StencilPassOp = stencil_op((pipe_stencil_op) src->zpass_op); ret.StencilDepthFailOp = stencil_op((pipe_stencil_op) src->zfail_op); ret.StencilFunc = compare_op((pipe_compare_func) src->func); + ret.StencilReadMask = src->valuemask; + ret.StencilWriteMask = src->writemask; return ret; } @@ -467,13 +469,21 @@ d3d12_create_depth_stencil_alpha_state(struct pipe_context *pctx, dsa->desc.FrontFace = stencil_op_state(depth_stencil_alpha->stencil); } - if (depth_stencil_alpha->stencil[1].enabled) + if (depth_stencil_alpha->stencil[1].enabled) { + struct d3d12_screen* screen = d3d12_screen(pctx->screen); + + dsa->backface_enabled = true; dsa->desc.BackFace = stencil_op_state(depth_stencil_alpha->stencil + 1); - else + + if (!screen->opts14.IndependentFrontAndBackStencilRefMaskSupported) { + dsa->desc.BackFace.StencilReadMask = dsa->desc.FrontFace.StencilReadMask; + dsa->desc.BackFace.StencilWriteMask = dsa->desc.FrontFace.StencilWriteMask; + } + } + else { dsa->desc.BackFace = dsa->desc.FrontFace; + } - dsa->desc.FrontFace.StencilReadMask = dsa->desc.BackFace.StencilReadMask = depth_stencil_alpha->stencil[0].valuemask; /* FIXME Back face mask */ - dsa->desc.FrontFace.StencilWriteMask = dsa->desc.BackFace.StencilWriteMask = depth_stencil_alpha->stencil[0].writemask; /* FIXME Back face mask */ dsa->desc.DepthWriteMask = (D3D12_DEPTH_WRITE_MASK) depth_stencil_alpha->depth_writemask; return dsa; @@ -1509,7 +1519,10 @@ d3d12_set_stencil_ref(struct pipe_context *pctx, const struct pipe_stencil_ref ref) { struct d3d12_context *ctx = d3d12_context(pctx); + struct d3d12_screen *screen = d3d12_screen(pctx->screen); if ((ref.ref_value[0] != ref.ref_value[1]) && + (!screen->opts14.IndependentFrontAndBackStencilRefMaskSupported || + ctx->cmdlist8 == nullptr) && (d3d12_debug & D3D12_DEBUG_VERBOSE)) debug_printf("D3D12: Different values for front and back stencil reference are not supported\n"); ctx->stencil_ref = ref; diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index 12e690e..6e0f5bd 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -1101,8 +1101,14 @@ d3d12_draw_vbo(struct pipe_context *pctx, } } - if (ctx->cmdlist_dirty & D3D12_DIRTY_STENCIL_REF) - ctx->cmdlist->OMSetStencilRef(ctx->stencil_ref.ref_value[0]); + if (ctx->cmdlist_dirty & D3D12_DIRTY_STENCIL_REF) { + if (ctx->gfx_pipeline_state.zsa->backface_enabled && + screen->opts14.IndependentFrontAndBackStencilRefMaskSupported && + ctx->cmdlist8 != nullptr) + ctx->cmdlist8->OMSetFrontAndBackStencilRef(ctx->stencil_ref.ref_value[0], ctx->stencil_ref.ref_value[1]); + else + ctx->cmdlist->OMSetStencilRef(ctx->stencil_ref.ref_value[0]); + } if (ctx->cmdlist_dirty & D3D12_DIRTY_PRIM_MODE) ctx->cmdlist->IASetPrimitiveTopology(topology((enum pipe_prim_type)dinfo->mode, ctx->patch_vertices)); diff --git a/src/gallium/drivers/d3d12/d3d12_pipeline_state.h b/src/gallium/drivers/d3d12/d3d12_pipeline_state.h index 400df34..fcfc98a 100644 --- a/src/gallium/drivers/d3d12/d3d12_pipeline_state.h +++ b/src/gallium/drivers/d3d12/d3d12_pipeline_state.h @@ -53,6 +53,7 @@ struct d3d12_blend_state { struct d3d12_depth_stencil_alpha_state { D3D12_DEPTH_STENCIL_DESC2 desc; + bool backface_enabled; }; struct d3d12_gfx_pipeline_state { -- 2.7.4