Prevent recompiling programs on changes to compareMask or writeMask

This CL changes PixelProcessor::States::StencilOpState, so that it
no longer causes useless recompilation of pixel programs because of
changes to compareMask or writeMask if the new values produce the
same program.

Bug: b/143288278
Change-Id: Ic23d3552080260ae3e923f9d0db9c149335871ce
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/66768
Tested-by: Alexis Hétu <sugoi@google.com>
Commit-Queue: Alexis Hétu <sugoi@google.com>
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Device/PixelProcessor.hpp b/src/Device/PixelProcessor.hpp
index 5d4b9bb..a63af34 100644
--- a/src/Device/PixelProcessor.hpp
+++ b/src/Device/PixelProcessor.hpp
@@ -43,8 +43,9 @@
 			VkStencilOp passOp;
 			VkStencilOp depthFailOp;
 			VkCompareOp compareOp;
-			uint32_t compareMask;
-			uint32_t writeMask;
+			bool useCompareMask;
+			bool useWriteMask;
+			bool writeEnabled;
 
 			void operator=(const VkStencilOpState &rhs)
 			{
@@ -52,8 +53,9 @@
 				passOp = rhs.passOp;
 				depthFailOp = rhs.depthFailOp;
 				compareOp = rhs.compareOp;
-				compareMask = rhs.compareMask;
-				writeMask = rhs.writeMask;
+				useCompareMask = (rhs.compareMask != 0xff);
+				useWriteMask = ((rhs.writeMask & 0xFF) != 0xFF);
+				writeEnabled = (rhs.writeMask != 0);
 			}
 		};
 
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp
index a95a363..f2c24f9 100644
--- a/src/Pipeline/PixelRoutine.cpp
+++ b/src/Pipeline/PixelRoutine.cpp
@@ -350,14 +350,14 @@
 		value = value | (*Pointer<Byte8>(buffer + pitch - 2) & Byte8(0, 0, -1, -1, 0, 0, 0, 0));
 		Byte8 valueBack = value;
 
-		if(state.frontStencil.compareMask != 0xff)
+		if(state.frontStencil.useCompareMask)
 		{
 			value &= *Pointer<Byte8>(data + OFFSET(DrawData, stencil[0].testMaskQ));
 		}
 
 		stencilTest(value, state.frontStencil.compareOp, false);
 
-		if(state.backStencil.compareMask != 0xff)
+		if(state.backStencil.useCompareMask)
 		{
 			valueBack &= *Pointer<Byte8>(data + OFFSET(DrawData, stencil[1].testMaskQ));
 		}
@@ -789,7 +789,7 @@
 		}
 	}
 
-	if((state.frontStencil.writeMask == 0) && (state.backStencil.writeMask == 0))
+	if(!state.frontStencil.writeEnabled && !state.backStencil.writeEnabled)
 	{
 		return;
 	}
@@ -808,7 +808,7 @@
 		bufferValue = bufferValue | (*Pointer<Byte8>(buffer + pitch - 2) & Byte8(0, 0, -1, -1, 0, 0, 0, 0));
 		Byte8 newValue = stencilOperation(bufferValue, state.frontStencil, false, zMask[q], sMask[q]);
 
-		if((state.frontStencil.writeMask & 0xFF) != 0xFF)  // Assume 8-bit stencil buffer
+		if(state.frontStencil.useWriteMask)  // Assume 8-bit stencil buffer
 		{
 			Byte8 maskedValue = bufferValue;
 			newValue &= *Pointer<Byte8>(data + OFFSET(DrawData, stencil[0].writeMaskQ));
@@ -818,7 +818,7 @@
 
 		Byte8 newValueBack = stencilOperation(bufferValue, state.backStencil, true, zMask[q], sMask[q]);
 
-		if((state.backStencil.writeMask & 0xFF) != 0xFF)  // Assume 8-bit stencil buffer
+		if(state.backStencil.useWriteMask)  // Assume 8-bit stencil buffer
 		{
 			Byte8 maskedValue = bufferValue;
 			newValueBack &= *Pointer<Byte8>(data + OFFSET(DrawData, stencil[1].writeMaskQ));