diff --git a/Source/Engine/Graphics/GPUContext.h b/Source/Engine/Graphics/GPUContext.h
index 99a226193..3ff7ec256 100644
--- a/Source/Engine/Graphics/GPUContext.h
+++ b/Source/Engine/Graphics/GPUContext.h
@@ -321,6 +321,12 @@ public:
/// Blend factors, one for each RGBA component.
API_FUNCTION() virtual void SetBlendFactor(const Float4& value) = 0;
+ ///
+ /// Sets the reference value for depth stencil tests.
+ ///
+ /// Reference value to perform against when doing a depth-stencil test.
+ API_FUNCTION() virtual void SetStencilRef(uint32 value) = 0;
+
public:
///
/// Unbinds all shader resource slots and flushes the change with the driver (used to prevent driver detection of resource hazards, eg. when down-scaling the texture).
diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp
index 10d85c179..6b6ebd6bc 100644
--- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp
+++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp
@@ -103,6 +103,7 @@ void GPUContextDX11::FrameBegin()
CurrentPS = nullptr;
CurrentCS = nullptr;
CurrentPrimitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
+ CurrentStencilRef = 0;
CurrentBlendFactor = Float4::One;
// Bind static samplers
@@ -275,6 +276,12 @@ void GPUContextDX11::SetBlendFactor(const Float4& value)
_context->OMSetBlendState(CurrentBlendState, CurrentBlendFactor.Raw, D3D11_DEFAULT_SAMPLE_MASK);
}
+void GPUContextDX11::SetStencilRef(uint32 value)
+{
+ if (CurrentStencilRef != value)
+ _context->OMSetDepthStencilState(CurrentDepthStencilState, CurrentStencilRef);
+}
+
void GPUContextDX11::ResetSR()
{
_srDirtyFlag = false;
@@ -559,7 +566,7 @@ void GPUContextDX11::SetState(GPUPipelineState* state)
if (CurrentDepthStencilState != depthStencilState)
{
CurrentDepthStencilState = depthStencilState;
- _context->OMSetDepthStencilState(depthStencilState, 0);
+ _context->OMSetDepthStencilState(depthStencilState, CurrentStencilRef);
}
if (CurrentRasterizerState != rasterizerState)
{
diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h
index b623cba3b..4e47c2f11 100644
--- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h
+++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h
@@ -61,6 +61,7 @@ private:
GPUShaderProgramPSDX11* CurrentPS;
GPUShaderProgramCSDX11* CurrentCS;
D3D11_PRIMITIVE_TOPOLOGY CurrentPrimitiveTopology;
+ uint32 CurrentStencilRef;
Float4 CurrentBlendFactor;
public:
@@ -117,6 +118,7 @@ public:
void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;
void SetRenderTarget(GPUTextureView* depthBuffer, const Span& rts) override;
void SetBlendFactor(const Float4& value) override;
+ void SetStencilRef(uint32 value) override;
void ResetSR() override;
void ResetUA() override;
void ResetCB() override;
diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp
index 54f1a4290..107895cf5 100644
--- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp
+++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp
@@ -222,6 +222,7 @@ void GPUContextDX12::Reset()
_rtDepth = nullptr;
_srMaskDirtyGraphics = 0;
_srMaskDirtyCompute = 0;
+ _stencilRef = 0;
_psDirtyFlag = false;
_isCompute = false;
_currentCompute = nullptr;
@@ -850,6 +851,15 @@ void GPUContextDX12::SetBlendFactor(const Float4& value)
_commandList->OMSetBlendFactor(value.Raw);
}
+void GPUContextDX12::SetStencilRef(uint32 value)
+{
+ if (_stencilRef != value)
+ {
+ _stencilRef = value;
+ _commandList->OMSetStencilRef(value);
+ }
+}
+
void GPUContextDX12::ResetSR()
{
for (int32 slot = 0; slot < GPU_MAX_SR_BINDED; slot++)
diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h
index c870cf71e..45dfa8162 100644
--- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h
+++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h
@@ -47,6 +47,7 @@ private:
uint32 _srMaskDirtyGraphics;
uint32 _srMaskDirtyCompute;
+ uint32 _stencilRef;
int32 _isCompute : 1;
int32 _rtDirtyFlag : 1;
@@ -167,6 +168,7 @@ public:
void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;
void SetRenderTarget(GPUTextureView* depthBuffer, const Span& rts) override;
void SetBlendFactor(const Float4& value) override;
+ void SetStencilRef(uint32 value) override;
void ResetSR() override;
void ResetUA() override;
void ResetCB() override;
diff --git a/Source/Engine/GraphicsDevice/Null/GPUContextNull.h b/Source/Engine/GraphicsDevice/Null/GPUContextNull.h
index 7568bb60c..e22c4b147 100644
--- a/Source/Engine/GraphicsDevice/Null/GPUContextNull.h
+++ b/Source/Engine/GraphicsDevice/Null/GPUContextNull.h
@@ -88,6 +88,10 @@ public:
{
}
+ void SetStencilRef(uint32 value) override
+ {
+ }
+
void ResetSR() override
{
}
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp
index d52b446e3..64d8bfb67 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp
@@ -727,6 +727,7 @@ void GPUContextVulkan::FrameBegin()
_cbDirtyFlag = 0;
_rtCount = 0;
_vbCount = 0;
+ _stencilRef = 0;
_renderPass = nullptr;
_currentState = nullptr;
_rtDepth = nullptr;
@@ -972,6 +973,16 @@ void GPUContextVulkan::SetBlendFactor(const Float4& value)
vkCmdSetBlendConstants(cmdBuffer->GetHandle(), value.Raw);
}
+void GPUContextVulkan::SetStencilRef(uint32 value)
+{
+ if (_stencilRef != value)
+ {
+ _stencilRef = value;
+ const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
+ vkCmdSetStencilReference(cmdBuffer->GetHandle(), VK_STENCIL_FRONT_AND_BACK, _stencilRef);
+ }
+}
+
void GPUContextVulkan::ResetSR()
{
Platform::MemoryClear(_srHandles, sizeof(_srHandles));
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h
index 63224b2d0..08b5c1d6a 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h
@@ -97,6 +97,7 @@ private:
int32 _rtCount;
int32 _vbCount;
+ uint32 _stencilRef;
RenderPassVulkan* _renderPass;
GPUPipelineStateVulkan* _currentState;
@@ -185,6 +186,7 @@ public:
void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;
void SetRenderTarget(GPUTextureView* depthBuffer, const Span& rts) override;
void SetBlendFactor(const Float4& value) override;
+ void SetStencilRef(uint32 value) override;
void ResetSR() override;
void ResetUA() override;
void ResetCB() override;
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp
index 935f37873..d2ccf7da1 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp
@@ -274,7 +274,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
_descDynamic.pDynamicStates = _dynamicStates;
_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
- //_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE;
+ _dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE;
static_assert(ARRAY_COUNT(_dynamicStates) <= 3, "Invalid dynamic states array.");
_desc.pDynamicState = &_descDynamic;