Always apply the fragment shader if it is present

Previously we tried to avoid applying a shader which didn't do anything
useful. Unfortunately we missed various edge cases. Just remove this
logic completely.

Bug: b/118386749
Test: dEQP-VK.renderpass*
Change-Id: I48f2f9f08ad491381db22af9f6f3430f7b4d4db1
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29728
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp
index 116f2d7..62b4666 100644
--- a/src/Pipeline/PixelRoutine.cpp
+++ b/src/Pipeline/PixelRoutine.cpp
@@ -181,27 +181,27 @@
 
 			Bool alphaPass = true;
 
-			if(colorUsed())
+			#if PERF_PROFILE
+				Long shaderTime = Ticks();
+			#endif
+
+			if (spirvShader)
 			{
-				#if PERF_PROFILE
-					Long shaderTime = Ticks();
-				#endif
-
 				applyShader(cMask);
+			}
 
-				#if PERF_PROFILE
-					cycles[PERF_SHADER] += Ticks() - shaderTime;
-				#endif
+			#if PERF_PROFILE
+				cycles[PERF_SHADER] += Ticks() - shaderTime;
+			#endif
 
-				alphaPass = alphaTest(cMask);
+			alphaPass = alphaTest(cMask);
 
-				if((spirvShader && spirvShader->getModes().ContainsKill) || state.alphaToCoverage)
+			if((spirvShader && spirvShader->getModes().ContainsKill) || state.alphaToCoverage)
+			{
+				for(unsigned int q = 0; q < state.multiSample; q++)
 				{
-					for(unsigned int q = 0; q < state.multiSample; q++)
-					{
-						zMask[q] &= cMask[q];
-						sMask[q] &= cMask[q];
-					}
+					zMask[q] &= cMask[q];
+					sMask[q] &= cMask[q];
 				}
 			}
 
@@ -234,14 +234,11 @@
 						}
 					}
 
-					if(colorUsed())
-					{
-						#if PERF_PROFILE
-							AddAtomic(Pointer<Long>(&profiler.ropOperations), 4);
-						#endif
+					#if PERF_PROFILE
+						AddAtomic(Pointer<Long>(&profiler.ropOperations), 4);
+					#endif
 
-						rasterOperation(cBuffer, x, sMask, zMask, cMask);
-					}
+					rasterOperation(cBuffer, x, sMask, zMask, cMask);
 				}
 
 				#if PERF_PROFILE
@@ -2474,9 +2471,4 @@
 
 		return Min(Max(linear, Float4(0.0f)), Float4(1.0f));
 	}
-
-	bool PixelRoutine::colorUsed()
-	{
-		return state.colorWriteMask || state.alphaToCoverage || (spirvShader && spirvShader->getModes().ContainsKill);
-	}
 }
diff --git a/src/Pipeline/PixelRoutine.hpp b/src/Pipeline/PixelRoutine.hpp
index e4d8eee..587d365 100644
--- a/src/Pipeline/PixelRoutine.hpp
+++ b/src/Pipeline/PixelRoutine.hpp
@@ -89,8 +89,6 @@
 
 		void writeDepth32F(Pointer<Byte> &zBuffer, int q, Int &x, Float4 &z, Int &zMask);
 		void writeDepth16(Pointer<Byte> &zBuffer, int q, Int &x, Float4 &z, Int &zMask);
-
-		bool colorUsed();
 	};
 }
 
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index 73e3e4a..2068bcc 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -511,6 +511,11 @@
 			return inputBuiltins.find(b) != inputBuiltins.end();
 		}
 
+		bool hasBuiltinOutput(spv::BuiltIn b) const
+		{
+			return outputBuiltins.find(b) != outputBuiltins.end();
+		}
+
 		struct Decorations
 		{
 			int32_t Location = -1;