Commit 1bd9e2f8 by Chris Forbes

Tidy stencil state handling

Bug: b/128715612 Change-Id: I1e9859d2cf001bfb341a49ad4f8fc9ef52c9fa5b Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27508Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 1cef4e69
......@@ -170,22 +170,9 @@ namespace sw
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;
......
......@@ -159,22 +159,9 @@ namespace sw
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;
......
......@@ -292,22 +292,9 @@ namespace sw
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())
......
......@@ -39,21 +39,9 @@ namespace sw
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;
......
......@@ -328,8 +328,8 @@ namespace sw
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;
......
......@@ -290,33 +290,33 @@ namespace sw
}
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 @@ namespace sw
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 @@ namespace sw
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 @@ namespace sw
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 @@ namespace sw
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 @@ namespace sw
*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 @@ namespace sw
}
}
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 @@ namespace sw
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));
......
......@@ -64,9 +64,9 @@ namespace sw
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
......
......@@ -381,21 +381,8 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn
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;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment