Work around dEQP-VK output_location test flakiness

Added a mask to prevent writing to unused outputs

Bug: b/162348737
Change-Id: I72b86cf2f6d0f9f07992cc63bc55fe9e45822e1d
Tests: dEQP-VK.draw.output_location.array.*
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/47168
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/PixelProgram.cpp b/src/Pipeline/PixelProgram.cpp
index da26158..1bd924a 100644
--- a/src/Pipeline/PixelProgram.cpp
+++ b/src/Pipeline/PixelProgram.cpp
@@ -155,6 +155,10 @@
 		c[i].y = routine.outputs[i * 4 + 1];
 		c[i].z = routine.outputs[i * 4 + 2];
 		c[i].w = routine.outputs[i * 4 + 3];
+		outputMasks[i] = ((spirvShader->outputs[i * 4 + 0].Type != SpirvShader::ATTRIBTYPE_UNUSED) ? 0x1 : 0x0) |
+		                 ((spirvShader->outputs[i * 4 + 1].Type != SpirvShader::ATTRIBTYPE_UNUSED) ? 0x2 : 0x0) |
+		                 ((spirvShader->outputs[i * 4 + 2].Type != SpirvShader::ATTRIBTYPE_UNUSED) ? 0x4 : 0x0) |
+		                 ((spirvShader->outputs[i * 4 + 3].Type != SpirvShader::ATTRIBTYPE_UNUSED) ? 0x8 : 0x0);
 	}
 
 	clampColor(c);
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp
index 9a7a61c..e888883 100644
--- a/src/Pipeline/PixelRoutine.cpp
+++ b/src/Pipeline/PixelRoutine.cpp
@@ -44,6 +44,11 @@
 			routine.inputs[i] = Float4(0.0f);
 		}
 	}
+
+	for(int i = 0; i < RENDERTARGETS; i++)
+	{
+		outputMasks[i] = 0xF;
+	}
 }
 
 PixelRoutine::~PixelRoutine()
@@ -1272,7 +1277,7 @@
 			break;
 	}
 
-	int rgbaWriteMask = state.colorWriteActive(index);
+	int rgbaWriteMask = state.colorWriteActive(index) & outputMasks[index];
 	int bgraWriteMask = (rgbaWriteMask & 0x0000000A) | (rgbaWriteMask & 0x00000001) << 2 | (rgbaWriteMask & 0x00000004) >> 2;
 
 	switch(state.targetFormat[index])
@@ -2144,7 +2149,7 @@
 			UNSUPPORTED("VkFormat: %d", int(state.targetFormat[index]));
 	}
 
-	int rgbaWriteMask = state.colorWriteActive(index);
+	int rgbaWriteMask = state.colorWriteActive(index) & outputMasks[index];
 	int bgraWriteMask = (rgbaWriteMask & 0x0000000A) | (rgbaWriteMask & 0x00000001) << 2 | (rgbaWriteMask & 0x00000004) >> 2;
 
 	Int xMask;  // Combination of all masks
diff --git a/src/Pipeline/PixelRoutine.hpp b/src/Pipeline/PixelRoutine.hpp
index 72d4253..d9d4f21 100644
--- a/src/Pipeline/PixelRoutine.hpp
+++ b/src/Pipeline/PixelRoutine.hpp
@@ -37,6 +37,8 @@
 	Float4 w;     // Used as is
 	Float4 rhw;   // Reciprocal w
 
+	uint32_t outputMasks[RENDERTARGETS];  // TODO(b/162348737): Determine whether unwritten output should be left untouched
+
 	SpirvRoutine routine;
 	const vk::DescriptorSet::Bindings &descriptorSets;