Add texture filtering precision hint

A new extension will be added to SwiftShader in order to allow
Chromium to trigger high precision filtering when necessary.
This extension is documented in:
extensions/CHROMIUM_texture_filtering_hint.txt

Bug swiftshader:76

Change-Id: I7c5b5c5fd01afbd7079e7949ecbd9c18fc539f2b
Reviewed-on: https://swiftshader-review.googlesource.com/10708
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp
index 172e8ef..db11aed 100644
--- a/src/Renderer/PixelProcessor.cpp
+++ b/src/Renderer/PixelProcessor.cpp
@@ -444,6 +444,15 @@
 		else ASSERT(false);
 	}
 
+	void PixelProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
+	{
+		if(sampler < TEXTURE_IMAGE_UNITS)
+		{
+			context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
+		}
+		else ASSERT(false);
+	}
+
 	void PixelProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
 	{
 		if(sampler < TEXTURE_IMAGE_UNITS)
diff --git a/src/Renderer/PixelProcessor.hpp b/src/Renderer/PixelProcessor.hpp
index 94d52d3..dd54b72 100644
--- a/src/Renderer/PixelProcessor.hpp
+++ b/src/Renderer/PixelProcessor.hpp
@@ -231,6 +231,7 @@
 		void setMipmapLOD(unsigned int sampler, float bias);
 		void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
 		void setMaxAnisotropy(unsigned int sampler, float maxAnisotropy);
+		void setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering);
 		void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
 		void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
 		void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index a84423d..a67ba22 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -2314,6 +2314,18 @@
 		}
 	}
 
+	void Renderer::setHighPrecisionFiltering(SamplerType type, int sampler, bool highPrecisionFiltering)
+	{
+		if(type == SAMPLER_PIXEL)
+		{
+			PixelProcessor::setHighPrecisionFiltering(sampler, highPrecisionFiltering);
+		}
+		else
+		{
+			VertexProcessor::setHighPrecisionFiltering(sampler, highPrecisionFiltering);
+		}
+	}
+
 	void Renderer::setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR)
 	{
 		if(type == SAMPLER_PIXEL)
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index c59dd31..c29020f 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -345,6 +345,7 @@
 		void setMipmapLOD(SamplerType type, int sampler, float bias);
 		void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor);
 		void setMaxAnisotropy(SamplerType type, int sampler, float maxAnisotropy);
+		void setHighPrecisionFiltering(SamplerType type, int sampler, bool highPrecisionFiltering);
 		void setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR);
 		void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG);
 		void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB);
diff --git a/src/Renderer/Sampler.cpp b/src/Renderer/Sampler.cpp
index e2447e0..7d7d47c 100644
--- a/src/Renderer/Sampler.cpp
+++ b/src/Renderer/Sampler.cpp
@@ -60,6 +60,7 @@
 		mipmapFilterState = MIPMAP_NONE;
 		sRGB = false;
 		gather = false;
+		highPrecisionFiltering = false;
 
 		swizzleR = SWIZZLE_RED;
 		swizzleG = SWIZZLE_GREEN;
@@ -97,6 +98,7 @@
 			state.swizzleG = swizzleG;
 			state.swizzleB = swizzleB;
 			state.swizzleA = swizzleA;
+			state.highPrecisionFiltering = highPrecisionFiltering;
 
 			#if PERF_PROFILE
 				state.compressedFormat = Surface::isCompressed(externalTextureFormat);
@@ -298,6 +300,11 @@
 		texture.maxAnisotropy = maxAnisotropy;
 	}
 
+	void Sampler::setHighPrecisionFiltering(bool highPrecisionFiltering)
+	{
+		this->highPrecisionFiltering = highPrecisionFiltering;
+	}
+
 	void Sampler::setSwizzleR(SwizzleType swizzleR)
 	{
 		this->swizzleR = swizzleR;
diff --git a/src/Renderer/Sampler.hpp b/src/Renderer/Sampler.hpp
index 4c4973d..288f179 100644
--- a/src/Renderer/Sampler.hpp
+++ b/src/Renderer/Sampler.hpp
@@ -140,6 +140,7 @@
 			SwizzleType swizzleG           : BITS(SWIZZLE_LAST);
 			SwizzleType swizzleB           : BITS(SWIZZLE_LAST);
 			SwizzleType swizzleA           : BITS(SWIZZLE_LAST);
+			bool highPrecisionFiltering    : 1;
 
 			#if PERF_PROFILE
 			bool compressedFormat          : 1;
@@ -163,6 +164,7 @@
 		void setReadSRGB(bool sRGB);
 		void setBorderColor(const Color<float> &borderColor);
 		void setMaxAnisotropy(float maxAnisotropy);
+		void setHighPrecisionFiltering(bool highPrecisionFiltering);
 		void setSwizzleR(SwizzleType swizzleR);
 		void setSwizzleG(SwizzleType swizzleG);
 		void setSwizzleB(SwizzleType swizzleB);
@@ -202,6 +204,7 @@
 		MipmapType mipmapFilterState;
 		bool sRGB;
 		bool gather;
+		bool highPrecisionFiltering;
 
 		SwizzleType swizzleR;
 		SwizzleType swizzleG;
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp
index 91c4d34..6972d94 100644
--- a/src/Renderer/VertexProcessor.cpp
+++ b/src/Renderer/VertexProcessor.cpp
@@ -602,6 +602,15 @@
 		else ASSERT(false);
 	}
 
+	void VertexProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
+	{
+		if(sampler < TEXTURE_IMAGE_UNITS)
+		{
+			context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
+		}
+		else ASSERT(false);
+	}
+
 	void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
 	{
 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp
index 278c9b1..3552f84 100644
--- a/src/Renderer/VertexProcessor.hpp
+++ b/src/Renderer/VertexProcessor.hpp
@@ -258,6 +258,7 @@
 		void setMipmapLOD(unsigned int sampler, float bias);
 		void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
 		void setMaxAnisotropy(unsigned int stage, float maxAnisotropy);
+		void setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering);
 		void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
 		void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
 		void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);