diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf
index 992feebe7..dbca7cd91 100644
--- a/bindings/bf/bgfx.bf
+++ b/bindings/bf/bgfx.bf
@@ -281,9 +281,16 @@ public static class bgfx
FuncRefMask = 0x000000ff,
FuncRmaskShift = 8,
FuncRmaskMask = 0x0000ff00,
- None = 0x00000000,
+
+ ///
+ /// No stencil test.
+ ///
+ None = 0x0000ff00,
+
+ ///
+ /// Stencil front or back mask.
+ ///
Mask = 0xffffffff,
- Default = 0x00000000,
///
/// Enable stencil test, less.
diff --git a/bindings/c3/bgfx.c3 b/bindings/c3/bgfx.c3
index 3e677f433..1a3721814 100644
--- a/bindings/c3/bgfx.c3
+++ b/bindings/c3/bgfx.c3
@@ -178,9 +178,12 @@ constdef StencilFlags : inline uint
FUNCREFMASK = 0x000000ff,
FUNCRMASKSHIFT = 8,
FUNCRMASKMASK = 0x0000ff00,
- NONE = 0x00000000,
+
+ // No stencil test.
+ NONE = 0x0000ff00,
+
+ // Stencil front or back mask.
MASK = 0xffffffff,
- DEFAULT = 0x00000000,
// Enable stencil test, less.
TESTLESS = 0x00010000,
diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs
index 06f55a636..139aea8d4 100644
--- a/bindings/cs/bgfx.cs
+++ b/bindings/cs/bgfx.cs
@@ -280,9 +280,16 @@ public static partial class bgfx
FuncRefMask = 0x000000ff,
FuncRmaskShift = 8,
FuncRmaskMask = 0x0000ff00,
- None = 0x00000000,
+
+ ///
+ /// No stencil test.
+ ///
+ None = 0x0000ff00,
+
+ ///
+ /// Stencil front or back mask.
+ ///
Mask = 0xffffffff,
- Default = 0x00000000,
///
/// Enable stencil test, less.
diff --git a/bindings/d/package.d b/bindings/d/package.d
index 784e6e998..f1727ec88 100644
--- a/bindings/d/package.d
+++ b/bindings/d/package.d
@@ -9,7 +9,7 @@ import bindbc.common.types: c_int64, c_uint64, va_list;
import bindbc.bgfx.config;
static import bgfx.impl;
-enum uint apiVersion = 147;
+enum uint apiVersion = 148;
alias ViewID = ushort;
@@ -171,9 +171,8 @@ StencilFuncRMask_ toStencilFuncRMask(uint v) nothrow @nogc pure @safe{ return (v
alias Stencil_ = uint;
enum Stencil: Stencil_{
- none = 0x0000_0000,
- mask = 0xFFFF_FFFF,
- default_ = 0x0000_0000,
+ none = 0x0000_FF00, ///No stencil test.
+ mask = 0xFFFF_FFFF, ///Stencil front or back mask.
}
alias StencilTest_ = uint;
diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig
index c9990ab78..e0c621435 100644
--- a/bindings/zig/bgfx.zig
+++ b/bindings/zig/bgfx.zig
@@ -176,9 +176,12 @@ pub const StencilFlags_FuncRefShift: StencilFlags = 0;
pub const StencilFlags_FuncRefMask: StencilFlags = 0x000000ff;
pub const StencilFlags_FuncRmaskShift: StencilFlags = 8;
pub const StencilFlags_FuncRmaskMask: StencilFlags = 0x0000ff00;
-pub const StencilFlags_None: StencilFlags = 0x00000000;
+
+/// No stencil test.
+pub const StencilFlags_None: StencilFlags = 0x0000ff00;
+
+/// Stencil front or back mask.
pub const StencilFlags_Mask: StencilFlags = 0xffffffff;
-pub const StencilFlags_Default: StencilFlags = 0x00000000;
/// Enable stencil test, less.
pub const StencilFlags_TestLess: StencilFlags = 0x00010000;
diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h
index d72360676..636b06976 100644
--- a/include/bgfx/defines.h
+++ b/include/bgfx/defines.h
@@ -15,7 +15,7 @@
#ifndef BGFX_DEFINES_H_HEADER_GUARD
#define BGFX_DEFINES_H_HEADER_GUARD
-#define BGFX_API_VERSION UINT32_C(147)
+#define BGFX_API_VERSION UINT32_C(148)
/**
* Color RGB/alpha/depth write. When it's not specified write will be disabled.
@@ -170,9 +170,8 @@
#define BGFX_STENCIL_FUNC_RMASK_MASK UINT32_C(0x0000ff00)
#define BGFX_STENCIL_FUNC_RMASK(v) ( ( (uint32_t)(v)<> (32*_0or1) ) );
}
- static constexpr uint64_t kStencilNoRefMask = packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK);
- static constexpr uint64_t kStencilDisabled = packStencil(
+ inline constexpr uint8_t unpackStencilWriteMask(uint64_t _stencil)
+ {
+ return uint8_t( (unpackStencil(1, _stencil) & BGFX_STENCIL_FUNC_RMASK_MASK) >> BGFX_STENCIL_FUNC_RMASK_SHIFT);
+ }
+
+ inline constexpr bool stencilFrontAndBack(uint64_t _stencil)
+ {
+ const uint32_t fstencil = unpackStencil(0, _stencil) & ~BGFX_STENCIL_FUNC_RMASK_MASK;
+ const uint32_t bstencil = unpackStencil(1, _stencil) & ~BGFX_STENCIL_FUNC_RMASK_MASK;
+ return bstencil != (BGFX_STENCIL_NONE & ~BGFX_STENCIL_FUNC_RMASK_MASK)
+ && bstencil != fstencil;
+ }
+
+ static constexpr uint64_t kStencilNoRefMask = packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK);
+ static constexpr uint64_t kStencilNoRefAndRwMask = packStencil(~(BGFX_STENCIL_FUNC_REF_MASK|BGFX_STENCIL_FUNC_RMASK_MASK), ~(BGFX_STENCIL_FUNC_REF_MASK|BGFX_STENCIL_FUNC_RMASK_MASK));
+ static constexpr uint64_t kStencilDisabled = packStencil(
BGFX_STENCIL_TEST_ALWAYS | BGFX_STENCIL_OP_FAIL_S_KEEP | BGFX_STENCIL_OP_FAIL_Z_KEEP | BGFX_STENCIL_OP_PASS_Z_KEEP
, BGFX_STENCIL_TEST_ALWAYS | BGFX_STENCIL_OP_FAIL_S_KEEP | BGFX_STENCIL_OP_FAIL_Z_KEEP | BGFX_STENCIL_OP_PASS_Z_KEEP
);
+ inline constexpr bool stencilEnabled(uint64_t _stencil)
+ {
+ return 0 != (_stencil & kStencilNoRefAndRwMask);
+ }
+
inline constexpr bool needBorderColor(uint64_t _flags)
{
return BGFX_SAMPLER_U_BORDER == (_flags & BGFX_SAMPLER_U_BORDER)
@@ -2045,7 +2066,7 @@ namespace bgfx
m_uniformIdx = UINT8_MAX;
m_stateFlags = BGFX_STATE_DEFAULT;
- m_stencil = packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT);
+ m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
m_rgba = 0;
m_scissor = UINT16_MAX;
}
diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp
index ba0566663..6d11c9ac3 100644
--- a/src/renderer_d3d11.cpp
+++ b/src/renderer_d3d11.cpp
@@ -2982,9 +2982,14 @@ namespace bgfx { namespace d3d11
uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
_state &= 0 == func ? 0 : BGFX_D3D11_DEPTH_STENCIL_MASK;
- uint32_t fstencil = unpackStencil(0, _stencil);
- uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
- _stencil &= kStencilNoRefMask;
+ const uint32_t ref = (unpackStencil(0, _stencil)&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
+ _stencil = stencilEnabled(_stencil)
+ ? (_stencil & kStencilNoRefMask)
+ : 0
+ ;
+
+ const uint32_t fstencil = unpackStencil(0, _stencil);
+ const uint8_t writeMask = unpackStencilWriteMask(_stencil);
bx::HashMurmur2A murmur;
murmur.begin();
@@ -3001,13 +3006,12 @@ namespace bgfx { namespace d3d11
desc.DepthWriteMask = !!(BGFX_STATE_WRITE_Z & _state) ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = s_cmpFunc[func];
- uint32_t bstencil = unpackStencil(1, _stencil);
- uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
- bstencil = frontAndBack ? bstencil : fstencil;
+ uint32_t frontAndBack = stencilFrontAndBack(_stencil);
+ uint32_t bstencil = frontAndBack ? unpackStencil(1, _stencil) : fstencil;
desc.StencilEnable = 0 != _stencil;
desc.StencilReadMask = (fstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
- desc.StencilWriteMask = 0xff;
+ desc.StencilWriteMask = writeMask;
desc.FrontFace.StencilFailOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];
desc.FrontFace.StencilDepthFailOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];
desc.FrontFace.StencilPassOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];
@@ -6123,7 +6127,7 @@ namespace bgfx { namespace d3d11
currentBind.clear();
setBlendState(newFlags, draw.m_rgba);
- setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) );
+ setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE) );
const uint64_t pt = newFlags&BGFX_STATE_PT_MASK;
primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp
index 35e587124..343a5265b 100644
--- a/src/renderer_d3d12.cpp
+++ b/src/renderer_d3d12.cpp
@@ -2580,7 +2580,7 @@ namespace bgfx { namespace d3d12
const VertexLayout* layouts[1] = { &m_vertexLayouts[_blitter.m_vb->layoutHandle.idx] };
ID3D12PipelineState* pso = getPipelineState(state
, 0
- , packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT)
+ , packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE)
, 1
, layouts
, _blitter.m_program
@@ -3243,6 +3243,7 @@ namespace bgfx { namespace d3d12
void setDepthStencilState(D3D12_DEPTH_STENCIL_DESC& _desc, uint64_t _state, uint64_t _stencil = 0)
{
const uint32_t fstencil = unpackStencil(0, _stencil);
+ const uint8_t writeMask = unpackStencilWriteMask(_stencil);
bx::memSet(&_desc, 0, sizeof(_desc) );
uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
@@ -3253,13 +3254,12 @@ namespace bgfx { namespace d3d12
;
_desc.DepthFunc = s_cmpFunc[func];
- uint32_t bstencil = unpackStencil(1, _stencil);
- uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
- bstencil = frontAndBack ? bstencil : fstencil;
+ uint32_t frontAndBack = stencilFrontAndBack(_stencil);
+ uint32_t bstencil = frontAndBack ? unpackStencil(1, _stencil) : fstencil;
- _desc.StencilEnable = 0 != _stencil;
+ _desc.StencilEnable = stencilEnabled(_stencil);
_desc.StencilReadMask = (fstencil & BGFX_STENCIL_FUNC_RMASK_MASK) >> BGFX_STENCIL_FUNC_RMASK_SHIFT;
- _desc.StencilWriteMask = 0xff;
+ _desc.StencilWriteMask = writeMask;
_desc.FrontFace.StencilFailOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_S_MASK) >> BGFX_STENCIL_OP_FAIL_S_SHIFT];
_desc.FrontFace.StencilDepthFailOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_Z_MASK) >> BGFX_STENCIL_OP_FAIL_Z_SHIFT];
@@ -3456,7 +3456,10 @@ namespace bgfx { namespace d3d12
| BGFX_STATE_PT_MASK
;
- _stencil &= kStencilNoRefMask;
+ _stencil = stencilEnabled(_stencil)
+ ? (_stencil & kStencilNoRefMask)
+ : 0
+ ;
const uint32_t rgba = !!(BGFX_STATE_BLEND_INDEPENDENT & _state) ? _rgba : 0;
diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp
index 584650858..a6c045d2d 100644
--- a/src/renderer_gl.cpp
+++ b/src/renderer_gl.cpp
@@ -4670,6 +4670,7 @@ namespace bgfx { namespace gl
{
flags |= GL_STENCIL_BUFFER_BIT;
GL_CHECK(glClearStencil(_clear.m_stencil) );
+ GL_CHECK(glStencilMask(0xff) );
}
if (0 != flags)
@@ -4708,6 +4709,7 @@ namespace bgfx { namespace gl
if (BGFX_CLEAR_STENCIL & _clear.m_flags)
{
GL_CHECK(glEnable(GL_STENCIL_TEST) );
+ GL_CHECK(glStencilMask(0xff) );
GL_CHECK(glStencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, _clear.m_stencil, 0xff) );
GL_CHECK(glStencilOpSeparate(GL_FRONT_AND_BACK, GL_REPLACE, GL_REPLACE, GL_REPLACE) );
}
@@ -8078,32 +8080,31 @@ namespace bgfx { namespace gl
if (0 != changedStencil)
{
- if (0 != newStencil)
+ if (stencilEnabled(newStencil) )
{
GL_CHECK(glEnable(GL_STENCIL_TEST) );
- uint32_t bstencil = unpackStencil(1, newStencil);
- uint8_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != unpackStencil(0, newStencil);
+ const uint32_t frmaskChanged = unpackStencil(0, changedStencil) & BGFX_STENCIL_FUNC_RMASK_MASK;
+ const GLint readMask = (unpackStencil(0, newStencil)&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
-// uint32_t bchanged = unpackStencil(1, changedStencil);
-// if (BGFX_STENCIL_FUNC_RMASK_MASK & bchanged)
-// {
-// uint32_t wmask = (bstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
-// GL_CHECK(glStencilMask(wmask) );
-// }
+ uint8_t frontAndBack = stencilFrontAndBack(newStencil);
+
+ if (0 != (changedStencil & (uint64_t(BGFX_STENCIL_FUNC_RMASK_MASK)<<32) ) )
+ {
+ GL_CHECK(glStencilMask(unpackStencilWriteMask(newStencil) ) );
+ }
for (uint8_t ii = 0, num = frontAndBack+1; ii < num; ++ii)
{
- uint32_t stencil = unpackStencil(ii, newStencil);
- uint32_t changed = unpackStencil(ii, changedStencil);
- GLenum face = s_stencilFace[frontAndBack+ii];
+ uint32_t stencil = unpackStencil(ii, newStencil);
+ uint32_t changed = (unpackStencil(ii, changedStencil) & ~BGFX_STENCIL_FUNC_RMASK_MASK) | frmaskChanged;
+ GLenum face = s_stencilFace[frontAndBack+ii];
if ( (BGFX_STENCIL_TEST_MASK|BGFX_STENCIL_FUNC_REF_MASK|BGFX_STENCIL_FUNC_RMASK_MASK) & changed)
{
- GLint ref = (stencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
- GLint mask = (stencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
- uint32_t func = (stencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT;
- GL_CHECK(glStencilFuncSeparate(face, s_cmpFunc[func], ref, mask) );
+ GLint ref = (stencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
+ uint32_t func = (stencil&BGFX_STENCIL_TEST_MASK )>>BGFX_STENCIL_TEST_SHIFT;
+ GL_CHECK(glStencilFuncSeparate(face, s_cmpFunc[func], ref, readMask) );
}
if ( (BGFX_STENCIL_OP_FAIL_S_MASK|BGFX_STENCIL_OP_FAIL_Z_MASK|BGFX_STENCIL_OP_PASS_Z_MASK) & changed)
diff --git a/src/renderer_mtl.cpp b/src/renderer_mtl.cpp
index 5112c80df..08e83b04b 100644
--- a/src/renderer_mtl.cpp
+++ b/src/renderer_mtl.cpp
@@ -2351,7 +2351,10 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
uint32_t fstencil = unpackStencil(0, _stencil);
uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
- _stencil &= kStencilNoRefMask;
+ _stencil = stencilEnabled(_stencil)
+ ? (_stencil & kStencilNoRefMask)
+ : 0
+ ;
bx::HashMurmur3 murmur;
murmur.begin();
@@ -2368,17 +2371,16 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
desc->setDepthWriteEnabled(!!(BGFX_STATE_WRITE_Z & _state) );
desc->setDepthCompareFunction( (MTL::CompareFunction)s_cmpFunc[func]);
- uint32_t bstencil = unpackStencil(1, _stencil);
- uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
- bstencil = frontAndBack ? bstencil : fstencil;
+ uint32_t frontAndBack = stencilFrontAndBack(_stencil);
+ uint32_t bstencil = frontAndBack ? unpackStencil(1, _stencil) : fstencil;
- if (0 != _stencil)
+ if (stencilEnabled(_stencil) )
{
MTL::StencilDescriptor* frontFaceDesc = m_frontFaceStencilDescriptor;
MTL::StencilDescriptor* backfaceDesc = m_backFaceStencilDescriptor;
uint32_t readMask = (fstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
- uint32_t writeMask = 0xff;
+ uint32_t writeMask = unpackStencilWriteMask(_stencil);
frontFaceDesc->setStencilFailureOperation( (MTL::StencilOperation)s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT]);
frontFaceDesc->setDepthFailureOperation( (MTL::StencilOperation)s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT]);
@@ -5552,7 +5554,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
currentBind.clear();
currentProgram = BGFX_INVALID_HANDLE;
- setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) );
+ setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE) );
const uint64_t pt = newFlags&BGFX_STATE_PT_MASK;
primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
@@ -5606,7 +5608,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
) & changedFlags
|| 0 != changedStencil)
{
- setDepthStencilState(newFlags,newStencil);
+ setDepthStencilState(newFlags, newStencil);
}
if ( (0
diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp
index 45381c23d..ba43e7b32 100644
--- a/src/renderer_vk.cpp
+++ b/src/renderer_vk.cpp
@@ -2865,7 +2865,7 @@ VK_IMPORT_DEVICE
const VertexLayout* layout = &m_vertexLayouts[_blitter.m_vb->layoutHandle.idx];
VkPipeline pso = getPipeline(state
, 0
- , packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT)
+ , packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE)
, 1
, &layout
, _blitter.m_program
@@ -3376,11 +3376,10 @@ VK_IMPORT_DEVICE
_desc.depthCompareOp = s_cmpFunc[func];
_desc.depthBoundsTestEnable = VK_FALSE;
- _desc.stencilTestEnable = 0 != _stencil;
+ _desc.stencilTestEnable = stencilEnabled(_stencil);
- uint32_t bstencil = unpackStencil(1, _stencil);
- uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
- bstencil = frontAndBack ? bstencil : fstencil;
+ uint32_t frontAndBack = stencilFrontAndBack(_stencil);
+ uint32_t bstencil = frontAndBack ? unpackStencil(1, _stencil) : fstencil;
_desc.front.failOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_S_MASK) >> BGFX_STENCIL_OP_FAIL_S_SHIFT];
_desc.front.passOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_PASS_Z_MASK) >> BGFX_STENCIL_OP_PASS_Z_SHIFT];
@@ -3888,7 +3887,7 @@ VK_IMPORT_DEVICE
| BGFX_STATE_PT_MASK
;
- _stencil &= kStencilNoRefMask;
+ _stencil &= kStencilNoRefAndRwMask;
VertexLayout layout;
if (0 < _numStreams)
@@ -3989,6 +3988,7 @@ VK_IMPORT_DEVICE
VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
+ VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR, // optional
};
@@ -9954,7 +9954,7 @@ VK_DESTROY
vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
}
- const bool hasStencil = 0 != draw.m_stencil;
+ const bool hasStencil = stencilEnabled(draw.m_stencil);
if (hasStencil
&& currentState.m_stencil != draw.m_stencil)
@@ -9964,6 +9964,7 @@ VK_DESTROY
const uint32_t fstencil = unpackStencil(0, draw.m_stencil);
const uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
vkCmdSetStencilReference(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, ref);
+ vkCmdSetStencilWriteMask(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, unpackStencilWriteMask(draw.m_stencil) );
}
const bool hasFactor = 0
diff --git a/src/renderer_vk.h b/src/renderer_vk.h
index 0a0e80c44..e418fdd80 100644
--- a/src/renderer_vk.h
+++ b/src/renderer_vk.h
@@ -189,6 +189,7 @@
VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatchIndirect); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBindPipeline); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdSetStencilReference); \
+ VK_IMPORT_DEVICE_FUNC(false, vkCmdSetStencilWriteMask); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdSetBlendConstants); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdSetScissor); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBindDescriptorSets); \
diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp
index a5942b97f..2a212c3ea 100644
--- a/src/renderer_webgpu.cpp
+++ b/src/renderer_webgpu.cpp
@@ -2032,7 +2032,7 @@ WGPU_IMPORT
, 1
, state
, 0
- , packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT)
+ , packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE)
, 1
, &stream
, 0
@@ -2756,7 +2756,10 @@ WGPU_IMPORT
| BGFX_STATE_PT_MASK
;
- _stencil &= kStencilNoRefMask;
+ _stencil = stencilEnabled(_stencil)
+ ? (_stencil & kStencilNoRefMask)
+ : 0
+ ;
const uint8_t numVertexStreams = bx::countBits(_streamMask);
@@ -3311,12 +3314,12 @@ WGPU_IMPORT
_stencil = 0;
}
- _stencil = 0 == _stencil ? kStencilDisabled : _stencil;
+ _stencil = !stencilEnabled(_stencil) ? kStencilDisabled : _stencil;
+ const uint8_t writeMask = unpackStencilWriteMask(_stencil);
const uint32_t fstencil = unpackStencil(0, _stencil);
- uint32_t bstencil = unpackStencil(1, _stencil);
- const uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
- bstencil = frontAndBack ? bstencil : fstencil;
+ const uint32_t frontAndBack = stencilFrontAndBack(_stencil);
+ uint32_t bstencil = frontAndBack ? unpackStencil(1, _stencil) : fstencil;
const uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
@@ -3341,7 +3344,7 @@ WGPU_IMPORT
.passOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_PASS_Z_MASK) >> BGFX_STENCIL_OP_PASS_Z_SHIFT],
},
.stencilReadMask = (fstencil & BGFX_STENCIL_FUNC_RMASK_MASK) >> BGFX_STENCIL_FUNC_RMASK_SHIFT,
- .stencilWriteMask = 0xff,
+ .stencilWriteMask = writeMask,
.depthBias = 0,
.depthBiasSlopeScale = 0.0f,
.depthBiasClamp = 0.0f,