Pass down the texture compare state.

Depth format textures can have a comparison operation performed after
their texels have been sampled.

Change-Id: I49f6bb7fab9765265761144ee8b6b62439beb5a3
Reviewed-on: https://swiftshader-review.googlesource.com/5870
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp
index 356aa47..003cfb3 100644
--- a/src/Renderer/PixelProcessor.cpp
+++ b/src/Renderer/PixelProcessor.cpp
@@ -489,6 +489,15 @@
 		else ASSERT(false);
 	}
 
+	void PixelProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
+	{
+		if(sampler < TEXTURE_IMAGE_UNITS)
+		{
+			context->sampler[sampler].setCompareFunc(compFunc);
+		}
+		else ASSERT(false);
+	}
+
 	void PixelProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
 	{
 		if(sampler < TEXTURE_IMAGE_UNITS)
diff --git a/src/Renderer/PixelProcessor.hpp b/src/Renderer/PixelProcessor.hpp
index d3b0602..57bbb19 100644
--- a/src/Renderer/PixelProcessor.hpp
+++ b/src/Renderer/PixelProcessor.hpp
@@ -237,6 +237,7 @@
 		void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
 		void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
 		void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
+		void setCompareFunc(unsigned int sampler, CompareFunc compare);
 		void setBaseLevel(unsigned int sampler, int baseLevel);
 		void setMaxLevel(unsigned int sampler, int maxLevel);
 		void setMinLod(unsigned int sampler, float minLod);
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index b7c423f..43e01bc 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -420,7 +420,7 @@
 				{
 					for(int sampler = 0; sampler < VERTEX_TEXTURE_IMAGE_UNITS; sampler++)
 					{
-						if(vertexState.samplerState[sampler].textureType != TEXTURE_NULL)
+						if(vertexState.sampler[sampler].textureType != TEXTURE_NULL)
 						{
 							draw->texture[TEXTURE_IMAGE_UNITS + sampler] = context->texture[TEXTURE_IMAGE_UNITS + sampler];
 							draw->texture[TEXTURE_IMAGE_UNITS + sampler]->lock(PUBLIC, PRIVATE);
@@ -2388,6 +2388,18 @@
 		}
 	}
 
+	void Renderer::setCompareFunc(SamplerType type, int sampler, CompareFunc compFunc)
+	{
+		if(type == SAMPLER_PIXEL)
+		{
+			PixelProcessor::setCompareFunc(sampler, compFunc);
+		}
+		else
+		{
+			VertexProcessor::setCompareFunc(sampler, compFunc);
+		}
+	}
+
 	void Renderer::setBaseLevel(SamplerType type, int sampler, int baseLevel)
 	{
 		if(type == SAMPLER_PIXEL)
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index ca2140a..108f84b 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -348,6 +348,7 @@
 		void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG);
 		void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB);
 		void setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA);
+		void setCompareFunc(SamplerType type, int sampler, CompareFunc compare);
 		void setBaseLevel(SamplerType type, int sampler, int baseLevel);
 		void setMaxLevel(SamplerType type, int sampler, int maxLevel);
 		void setMinLod(SamplerType type, int sampler, float minLod);
diff --git a/src/Renderer/Sampler.cpp b/src/Renderer/Sampler.cpp
index 123a1c9..5bf11c8 100644
--- a/src/Renderer/Sampler.cpp
+++ b/src/Renderer/Sampler.cpp
@@ -67,6 +67,8 @@
 		swizzleB = SWIZZLE_BLUE;
 		swizzleA = SWIZZLE_ALPHA;
 
+		compare = COMPARE_BYPASS;
+
 		texture.LOD = 0.0f;
 		exp2LOD = 1.0f;
 
@@ -99,6 +101,7 @@
 			state.swizzleB = swizzleB;
 			state.swizzleA = swizzleA;
 			state.highPrecisionFiltering = highPrecisionFiltering;
+			state.compare = getCompareFunc();
 
 			#if PERF_PROFILE
 				state.compressedFormat = Surface::isCompressed(externalTextureFormat);
@@ -332,6 +335,11 @@
 		this->swizzleA = swizzleA;
 	}
 
+	void Sampler::setCompareFunc(CompareFunc compare)
+	{
+		this->compare = compare;
+	}
+
 	void Sampler::setBaseLevel(int baseLevel)
 	{
 		texture.baseLevel = baseLevel;
@@ -478,4 +486,19 @@
 
 		return addressingModeW;
 	}
+
+	CompareFunc Sampler::getCompareFunc() const
+	{
+		if(getTextureFilter() == FILTER_GATHER)
+		{
+			return COMPARE_BYPASS;
+		}
+
+		if(internalTextureFormat == FORMAT_D32FS8_SHADOW)
+		{
+			return COMPARE_LESSEQUAL;
+		}
+
+		return compare;
+	}
 }
diff --git a/src/Renderer/Sampler.hpp b/src/Renderer/Sampler.hpp
index 6fae602..ad2145c 100644
--- a/src/Renderer/Sampler.hpp
+++ b/src/Renderer/Sampler.hpp
@@ -110,6 +110,21 @@
 		ADDRESSING_LAST = ADDRESSING_TEXELFETCH
 	};
 
+	enum CompareFunc ENUM_UNDERLYING_TYPE_UNSIGNED_INT
+	{
+		COMPARE_BYPASS,
+		COMPARE_LESSEQUAL,
+		COMPARE_GREATEREQUAL,
+		COMPARE_LESS,
+		COMPARE_GREATER,
+		COMPARE_EQUAL,
+		COMPARE_NOTEQUAL,
+		COMPARE_ALWAYS,
+		COMPARE_NEVER,
+
+		COMPARE_LAST = COMPARE_NEVER
+	};
+
 	enum SwizzleType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
 	{
 		SWIZZLE_RED,
@@ -142,6 +157,7 @@
 			SwizzleType swizzleB           : BITS(SWIZZLE_LAST);
 			SwizzleType swizzleA           : BITS(SWIZZLE_LAST);
 			bool highPrecisionFiltering    : 1;
+			CompareFunc compare            : BITS(COMPARE_LAST);
 
 			#if PERF_PROFILE
 			bool compressedFormat          : 1;
@@ -170,6 +186,7 @@
 		void setSwizzleG(SwizzleType swizzleG);
 		void setSwizzleB(SwizzleType swizzleB);
 		void setSwizzleA(SwizzleType swizzleA);
+		void setCompareFunc(CompareFunc compare);
 		void setBaseLevel(int baseLevel);
 		void setMaxLevel(int maxLevel);
 		void setMinLod(float minLod);
@@ -193,6 +210,7 @@
 		AddressingMode getAddressingModeU() const;
 		AddressingMode getAddressingModeV() const;
 		AddressingMode getAddressingModeW() const;
+		CompareFunc getCompareFunc() const;
 
 		Format externalTextureFormat;
 		Format internalTextureFormat;
@@ -211,6 +229,8 @@
 		SwizzleType swizzleG;
 		SwizzleType swizzleB;
 		SwizzleType swizzleA;
+		CompareFunc compare;
+
 		Texture texture;
 		float exp2LOD;
 
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp
index 2fa6caa..3d364ac 100644
--- a/src/Renderer/VertexProcessor.cpp
+++ b/src/Renderer/VertexProcessor.cpp
@@ -647,6 +647,15 @@
 		else ASSERT(false);
 	}
 
+	void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
+	{
+		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
+		{
+			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc);
+		}
+		else ASSERT(false);
+	}
+
 	void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
 	{
 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
@@ -986,7 +995,7 @@
 			{
 				if(context->vertexShader->usesSampler(i))
 				{
-					state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
+					state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
 				}
 			}
 		}
diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp
index 3552f84..deac83d 100644
--- a/src/Renderer/VertexProcessor.hpp
+++ b/src/Renderer/VertexProcessor.hpp
@@ -91,7 +91,7 @@
 
 			TextureState textureState[8];
 
-			Sampler::State samplerState[VERTEX_TEXTURE_IMAGE_UNITS];
+			Sampler::State sampler[VERTEX_TEXTURE_IMAGE_UNITS];
 
 			struct Input
 			{
@@ -263,6 +263,7 @@
 		void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
 		void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
 		void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
+		void setCompareFunc(unsigned int sampler, CompareFunc compare);
 		void setBaseLevel(unsigned int sampler, int baseLevel);
 		void setMaxLevel(unsigned int sampler, int maxLevel);
 		void setMinLod(unsigned int sampler, float minLod);