Tidy stencil state handling
Bug: b/128715612
Change-Id: I1e9859d2cf001bfb341a49ad4f8fc9ef52c9fa5b
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27508
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Device/Context.cpp b/src/Device/Context.cpp
index 855d39f..dc3ad68 100644
--- a/src/Device/Context.cpp
+++ b/src/Device/Context.cpp
@@ -170,22 +170,9 @@
stencilBuffer = nullptr;
stencilEnable = false;
- stencilCompareMode = VK_COMPARE_OP_ALWAYS;
- stencilReference = 0;
- stencilMask = 0xFFFFFFFF;
- stencilFailOperation = VK_STENCIL_OP_KEEP;
- stencilPassOperation = VK_STENCIL_OP_KEEP;
- stencilZFailOperation = VK_STENCIL_OP_KEEP;
- stencilWriteMask = 0xFFFFFFFF;
-
twoSidedStencil = false;
- stencilCompareModeCCW = VK_COMPARE_OP_ALWAYS;
- stencilReferenceCCW = 0;
- stencilMaskCCW = 0xFFFFFFFF;
- stencilFailOperationCCW = VK_STENCIL_OP_KEEP;
- stencilPassOperationCCW = VK_STENCIL_OP_KEEP;
- stencilZFailOperationCCW = VK_STENCIL_OP_KEEP;
- stencilWriteMaskCCW = 0xFFFFFFFF;
+ frontStencil = {};
+ backStencil = {};
rasterizerDiscard = false;
diff --git a/src/Device/Context.hpp b/src/Device/Context.hpp
index 6be2017..2405224 100644
--- a/src/Device/Context.hpp
+++ b/src/Device/Context.hpp
@@ -159,22 +159,9 @@
DrawType drawType;
bool stencilEnable;
- VkCompareOp stencilCompareMode;
- int stencilReference;
- int stencilMask;
- VkStencilOp stencilFailOperation;
- VkStencilOp stencilPassOperation;
- VkStencilOp stencilZFailOperation;
- int stencilWriteMask;
-
bool twoSidedStencil;
- VkCompareOp stencilCompareModeCCW;
- int stencilReferenceCCW;
- int stencilMaskCCW;
- VkStencilOp stencilFailOperationCCW;
- VkStencilOp stencilPassOperationCCW;
- VkStencilOp stencilZFailOperationCCW;
- int stencilWriteMaskCCW;
+ VkStencilOpState frontStencil;
+ VkStencilOpState backStencil;
// Pixel processor states
VkCullModeFlags cullMode;
diff --git a/src/Device/PixelProcessor.cpp b/src/Device/PixelProcessor.cpp
index da40dbe..df7f9e6 100644
--- a/src/Device/PixelProcessor.cpp
+++ b/src/Device/PixelProcessor.cpp
@@ -292,22 +292,9 @@
if(context->stencilActive())
{
state.stencilActive = true;
- state.stencilCompareMode = context->stencilCompareMode;
- state.stencilFailOperation = context->stencilFailOperation;
- state.stencilPassOperation = context->stencilPassOperation;
- state.stencilZFailOperation = context->stencilZFailOperation;
- state.noStencilMask = (context->stencilMask == 0xFF);
- state.noStencilWriteMask = (context->stencilWriteMask == 0xFF);
- state.stencilWriteMasked = (context->stencilWriteMask == 0x00);
-
state.twoSidedStencil = context->twoSidedStencil;
- state.stencilCompareModeCCW = context->twoSidedStencil ? context->stencilCompareModeCCW : state.stencilCompareMode;
- state.stencilFailOperationCCW = context->twoSidedStencil ? context->stencilFailOperationCCW : state.stencilFailOperation;
- state.stencilPassOperationCCW = context->twoSidedStencil ? context->stencilPassOperationCCW : state.stencilPassOperation;
- state.stencilZFailOperationCCW = context->twoSidedStencil ? context->stencilZFailOperationCCW : state.stencilZFailOperation;
- state.noStencilMaskCCW = context->twoSidedStencil ? (context->stencilMaskCCW == 0xFF) : state.noStencilMask;
- state.noStencilWriteMaskCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0xFF) : state.noStencilWriteMask;
- state.stencilWriteMaskedCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0x00) : state.stencilWriteMasked;
+ state.frontStencil = context->frontStencil;
+ state.backStencil = context->backStencil;
}
if(context->depthBufferActive())
diff --git a/src/Device/PixelProcessor.hpp b/src/Device/PixelProcessor.hpp
index 2d4437a..c15da8b 100644
--- a/src/Device/PixelProcessor.hpp
+++ b/src/Device/PixelProcessor.hpp
@@ -39,21 +39,9 @@
bool quadLayoutDepthBuffer;
bool stencilActive;
- VkCompareOp stencilCompareMode;
- VkStencilOp stencilFailOperation;
- VkStencilOp stencilPassOperation;
- VkStencilOp stencilZFailOperation;
- bool noStencilMask;
- bool noStencilWriteMask;
- bool stencilWriteMasked;
bool twoSidedStencil;
- VkCompareOp stencilCompareModeCCW;
- VkStencilOp stencilFailOperationCCW;
- VkStencilOp stencilPassOperationCCW;
- VkStencilOp stencilZFailOperationCCW;
- bool noStencilMaskCCW;
- bool noStencilWriteMaskCCW;
- bool stencilWriteMaskedCCW;
+ VkStencilOpState frontStencil;
+ VkStencilOpState backStencil;
bool depthTestActive;
bool occlusionEnabled;
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp
index 7a08703..2038d50 100644
--- a/src/Device/Renderer.cpp
+++ b/src/Device/Renderer.cpp
@@ -328,8 +328,8 @@
if(pixelState.stencilActive)
{
- data->stencil[0].set(context->stencilReference, context->stencilMask, context->stencilWriteMask);
- data->stencil[1].set(context->stencilReferenceCCW, context->stencilMaskCCW, context->stencilWriteMaskCCW);
+ data->stencil[0].set(context->frontStencil.reference, context->frontStencil.compareMask, context->frontStencil.writeMask);
+ data->stencil[1].set(context->backStencil.reference, context->backStencil.compareMask, context->backStencil.writeMask);
}
data->lineWidth = context->lineWidth;
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp
index aa4209e..b904014 100644
--- a/src/Pipeline/PixelRoutine.cpp
+++ b/src/Pipeline/PixelRoutine.cpp
@@ -290,33 +290,33 @@
}
Byte8 value = *Pointer<Byte8>(buffer);
- Byte8 valueCCW = value;
+ Byte8 valueBack = value;
- if(!state.noStencilMask)
+ if(state.frontStencil.compareMask != 0xff)
{
value &= *Pointer<Byte8>(data + OFFSET(DrawData,stencil[0].testMaskQ));
}
- stencilTest(value, state.stencilCompareMode, false);
+ stencilTest(value, state.frontStencil.compareOp, false);
if(state.twoSidedStencil)
{
- if(!state.noStencilMaskCCW)
+ if(state.backStencil.compareMask != 0xff)
{
- valueCCW &= *Pointer<Byte8>(data + OFFSET(DrawData,stencil[1].testMaskQ));
+ valueBack &= *Pointer<Byte8>(data + OFFSET(DrawData,stencil[1].testMaskQ));
}
- stencilTest(valueCCW, state.stencilCompareModeCCW, true);
+ stencilTest(valueBack, state.backStencil.compareOp, true);
value &= *Pointer<Byte8>(primitive + OFFSET(Primitive,clockwiseMask));
- valueCCW &= *Pointer<Byte8>(primitive + OFFSET(Primitive,invClockwiseMask));
- value |= valueCCW;
+ valueBack &= *Pointer<Byte8>(primitive + OFFSET(Primitive,invClockwiseMask));
+ value |= valueBack;
}
sMask = SignMask(value) & cMask;
}
- void PixelRoutine::stencilTest(Byte8 &value, VkCompareOp stencilCompareMode, bool CCW)
+ void PixelRoutine::stencilTest(Byte8 &value, VkCompareOp stencilCompareMode, bool isBack)
{
Byte8 equal;
@@ -330,31 +330,31 @@
break;
case VK_COMPARE_OP_LESS: // a < b ~ b > a
value += Byte8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
- value = CmpGT(As<SByte8>(value), *Pointer<SByte8>(data + OFFSET(DrawData,stencil[CCW].referenceMaskedSignedQ)));
+ value = CmpGT(As<SByte8>(value), *Pointer<SByte8>(data + OFFSET(DrawData,stencil[isBack].referenceMaskedSignedQ)));
break;
case VK_COMPARE_OP_EQUAL:
- value = CmpEQ(value, *Pointer<Byte8>(data + OFFSET(DrawData,stencil[CCW].referenceMaskedQ)));
+ value = CmpEQ(value, *Pointer<Byte8>(data + OFFSET(DrawData,stencil[isBack].referenceMaskedQ)));
break;
case VK_COMPARE_OP_NOT_EQUAL: // a != b ~ !(a == b)
- value = CmpEQ(value, *Pointer<Byte8>(data + OFFSET(DrawData,stencil[CCW].referenceMaskedQ)));
+ value = CmpEQ(value, *Pointer<Byte8>(data + OFFSET(DrawData,stencil[isBack].referenceMaskedQ)));
value ^= Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
break;
case VK_COMPARE_OP_LESS_OR_EQUAL: // a <= b ~ (b > a) || (a == b)
equal = value;
- equal = CmpEQ(equal, *Pointer<Byte8>(data + OFFSET(DrawData,stencil[CCW].referenceMaskedQ)));
+ equal = CmpEQ(equal, *Pointer<Byte8>(data + OFFSET(DrawData,stencil[isBack].referenceMaskedQ)));
value += Byte8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
- value = CmpGT(As<SByte8>(value), *Pointer<SByte8>(data + OFFSET(DrawData,stencil[CCW].referenceMaskedSignedQ)));
+ value = CmpGT(As<SByte8>(value), *Pointer<SByte8>(data + OFFSET(DrawData,stencil[isBack].referenceMaskedSignedQ)));
value |= equal;
break;
case VK_COMPARE_OP_GREATER: // a > b
- equal = *Pointer<Byte8>(data + OFFSET(DrawData,stencil[CCW].referenceMaskedSignedQ));
+ equal = *Pointer<Byte8>(data + OFFSET(DrawData,stencil[isBack].referenceMaskedSignedQ));
value += Byte8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
equal = CmpGT(As<SByte8>(equal), As<SByte8>(value));
value = equal;
break;
case VK_COMPARE_OP_GREATER_OR_EQUAL: // a >= b ~ !(a < b) ~ !(b > a)
value += Byte8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
- value = CmpGT(As<SByte8>(value), *Pointer<SByte8>(data + OFFSET(DrawData,stencil[CCW].referenceMaskedSignedQ)));
+ value = CmpGT(As<SByte8>(value), *Pointer<SByte8>(data + OFFSET(DrawData,stencil[isBack].referenceMaskedSignedQ)));
value ^= Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
break;
default:
@@ -729,15 +729,15 @@
return;
}
- if(state.stencilPassOperation == VK_STENCIL_OP_KEEP && state.stencilZFailOperation == VK_STENCIL_OP_KEEP && state.stencilFailOperation == VK_STENCIL_OP_KEEP)
+ if(state.frontStencil.passOp == VK_STENCIL_OP_KEEP && state.frontStencil.depthFailOp == VK_STENCIL_OP_KEEP && state.frontStencil.failOp == VK_STENCIL_OP_KEEP)
{
- if(!state.twoSidedStencil || (state.stencilPassOperationCCW == VK_STENCIL_OP_KEEP && state.stencilZFailOperationCCW == VK_STENCIL_OP_KEEP && state.stencilFailOperationCCW == VK_STENCIL_OP_KEEP))
+ if(!state.twoSidedStencil || (state.backStencil.passOp == VK_STENCIL_OP_KEEP && state.backStencil.depthFailOp == VK_STENCIL_OP_KEEP && state.backStencil.failOp == VK_STENCIL_OP_KEEP))
{
return;
}
}
- if(state.stencilWriteMasked && (!state.twoSidedStencil || state.stencilWriteMaskedCCW))
+ if((state.frontStencil.writeMask == 0) && (!state.twoSidedStencil || (state.backStencil.writeMask == 0)))
{
return;
}
@@ -752,9 +752,9 @@
Byte8 bufferValue = *Pointer<Byte8>(buffer);
Byte8 newValue;
- stencilOperation(newValue, bufferValue, state.stencilPassOperation, state.stencilZFailOperation, state.stencilFailOperation, false, zMask, sMask);
+ stencilOperation(newValue, bufferValue, state.frontStencil, false, zMask, sMask);
- if(!state.noStencilWriteMask)
+ if(state.frontStencil.writeMask != 0)
{
Byte8 maskedValue = bufferValue;
newValue &= *Pointer<Byte8>(data + OFFSET(DrawData,stencil[0].writeMaskQ));
@@ -764,21 +764,21 @@
if(state.twoSidedStencil)
{
- Byte8 newValueCCW;
+ Byte8 newValueBack;
- stencilOperation(newValueCCW, bufferValue, state.stencilPassOperationCCW, state.stencilZFailOperationCCW, state.stencilFailOperationCCW, true, zMask, sMask);
+ stencilOperation(newValueBack, bufferValue, state.backStencil, true, zMask, sMask);
- if(!state.noStencilWriteMaskCCW)
+ if(state.backStencil.writeMask != 0)
{
Byte8 maskedValue = bufferValue;
- newValueCCW &= *Pointer<Byte8>(data + OFFSET(DrawData,stencil[1].writeMaskQ));
+ newValueBack &= *Pointer<Byte8>(data + OFFSET(DrawData,stencil[1].writeMaskQ));
maskedValue &= *Pointer<Byte8>(data + OFFSET(DrawData,stencil[1].invWriteMaskQ));
- newValueCCW |= maskedValue;
+ newValueBack |= maskedValue;
}
newValue &= *Pointer<Byte8>(primitive + OFFSET(Primitive,clockwiseMask));
- newValueCCW &= *Pointer<Byte8>(primitive + OFFSET(Primitive,invClockwiseMask));
- newValue |= newValueCCW;
+ newValueBack &= *Pointer<Byte8>(primitive + OFFSET(Primitive,invClockwiseMask));
+ newValue |= newValueBack;
}
newValue &= *Pointer<Byte8>(constants + OFFSET(Constants,maskB4Q) + 8 * cMask);
@@ -788,27 +788,27 @@
*Pointer<Byte4>(buffer) = Byte4(newValue);
}
- void PixelRoutine::stencilOperation(Byte8 &newValue, Byte8 &bufferValue, VkStencilOp stencilPassOperation, VkStencilOp stencilZFailOperation, VkStencilOp stencilFailOperation, bool CCW, Int &zMask, Int &sMask)
+ void PixelRoutine::stencilOperation(Byte8 &newValue, Byte8 &bufferValue, VkStencilOpState const &ops, bool isBack, Int &zMask, Int &sMask)
{
Byte8 &pass = newValue;
Byte8 fail;
Byte8 zFail;
- stencilOperation(pass, bufferValue, stencilPassOperation, CCW);
+ stencilOperation(pass, bufferValue, ops.passOp, isBack);
- if(stencilZFailOperation != stencilPassOperation)
+ if(ops.depthFailOp != ops.passOp)
{
- stencilOperation(zFail, bufferValue, stencilZFailOperation, CCW);
+ stencilOperation(zFail, bufferValue, ops.depthFailOp, isBack);
}
- if(stencilFailOperation != stencilPassOperation || stencilFailOperation != stencilZFailOperation)
+ if(ops.failOp != ops.passOp || ops.failOp != ops.depthFailOp)
{
- stencilOperation(fail, bufferValue, stencilFailOperation, CCW);
+ stencilOperation(fail, bufferValue, ops.failOp, isBack);
}
- if(stencilFailOperation != stencilPassOperation || stencilFailOperation != stencilZFailOperation)
+ if(ops.failOp != ops.passOp || ops.failOp != ops.depthFailOp)
{
- if(state.depthTestActive && stencilZFailOperation != stencilPassOperation) // zMask valid and values not the same
+ if(state.depthTestActive && ops.depthFailOp != ops.passOp) // zMask valid and values not the same
{
pass &= *Pointer<Byte8>(constants + OFFSET(Constants,maskB4Q) + 8 * zMask);
zFail &= *Pointer<Byte8>(constants + OFFSET(Constants,invMaskB4Q) + 8 * zMask);
@@ -821,7 +821,7 @@
}
}
- void PixelRoutine::stencilOperation(Byte8 &output, Byte8 &bufferValue, VkStencilOp operation, bool CCW)
+ void PixelRoutine::stencilOperation(Byte8 &output, Byte8 &bufferValue, VkStencilOp operation, bool isBack)
{
switch(operation)
{
@@ -832,7 +832,7 @@
output = Byte8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
break;
case VK_STENCIL_OP_REPLACE:
- output = *Pointer<Byte8>(data + OFFSET(DrawData,stencil[CCW].referenceQ));
+ output = *Pointer<Byte8>(data + OFFSET(DrawData,stencil[isBack].referenceQ));
break;
case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
output = AddSat(bufferValue, Byte8(1, 1, 1, 1, 1, 1, 1, 1));
diff --git a/src/Pipeline/PixelRoutine.hpp b/src/Pipeline/PixelRoutine.hpp
index ff2044f..824c7ce 100644
--- a/src/Pipeline/PixelRoutine.hpp
+++ b/src/Pipeline/PixelRoutine.hpp
@@ -64,9 +64,9 @@
private:
Float4 interpolateCentroid(Float4 &x, Float4 &y, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective);
void stencilTest(Pointer<Byte> &sBuffer, int q, Int &x, Int &sMask, Int &cMask);
- void stencilTest(Byte8 &value, VkCompareOp stencilCompareMode, bool CCW);
- void stencilOperation(Byte8 &newValue, Byte8 &bufferValue, VkStencilOp stencilPassOperation, VkStencilOp stencilZFailOperation, VkStencilOp stencilFailOperation, bool CCW, Int &zMask, Int &sMask);
- void stencilOperation(Byte8 &output, Byte8 &bufferValue, VkStencilOp operation, bool CCW);
+ void stencilTest(Byte8 &value, VkCompareOp stencilCompareMode, bool isBack);
+ void stencilOperation(Byte8 &newValue, Byte8 &bufferValue, VkStencilOpState const &ops, bool isBack, Int &zMask, Int &sMask);
+ void stencilOperation(Byte8 &output, Byte8 &bufferValue, VkStencilOp operation, bool isBack);
Bool depthTest(Pointer<Byte> &zBuffer, int q, Int &x, Float4 &z, Int &sMask, Int &zMask, Int &cMask);
// Raster operations
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index 5cd45ce..c6b65ed 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -381,21 +381,8 @@
context.stencilEnable = context.twoSidedStencil = depthStencilState->stencilTestEnable;
if(context.stencilEnable)
{
- context.stencilMask = depthStencilState->front.compareMask;
- context.stencilCompareMode = depthStencilState->front.compareOp;
- context.stencilZFailOperation = depthStencilState->front.depthFailOp;
- context.stencilFailOperation = depthStencilState->front.failOp;
- context.stencilPassOperation = depthStencilState->front.passOp;
- context.stencilReference = depthStencilState->front.reference;
- context.stencilWriteMask = depthStencilState->front.writeMask;
-
- context.stencilMaskCCW = depthStencilState->back.compareMask;
- context.stencilCompareModeCCW = depthStencilState->back.compareOp;
- context.stencilZFailOperationCCW = depthStencilState->back.depthFailOp;
- context.stencilFailOperationCCW = depthStencilState->back.failOp;
- context.stencilPassOperationCCW = depthStencilState->back.passOp;
- context.stencilReferenceCCW = depthStencilState->back.reference;
- context.stencilWriteMaskCCW = depthStencilState->back.writeMask;
+ context.frontStencil = depthStencilState->front;
+ context.backStencil = depthStencilState->back;
}
}