Min LOD and Max LOD sampler parameters

Plumbing to send Min LOD and Max LOD from the Sampler
object in the Context to the Renderer's texture's state.

Change-Id: I6831a8e17d67e745d12a78176d566750d971ec76
Reviewed-on: https://swiftshader-review.googlesource.com/5510
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Meng-Lin Wu <marleymoo@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 9e024d3..65363e5 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3040,6 +3040,7 @@
 			if(texture->isSamplerComplete())
 			{
 				GLenum wrapS, wrapT, wrapR, minFilter, magFilter;
+				GLfloat minLOD, maxLOD;
 
 				Sampler *samplerObject = mState.sampler[textureUnit];
 				if(samplerObject)
@@ -3049,6 +3050,8 @@
 					wrapR = samplerObject->getWrapR();
 					minFilter = samplerObject->getMinFilter();
 					magFilter = samplerObject->getMagFilter();
+					minLOD = samplerObject->getMinLod();
+					maxLOD = samplerObject->getMaxLod();
 				}
 				else
 				{
@@ -3057,6 +3060,8 @@
 					wrapR = texture->getWrapR();
 					minFilter = texture->getMinFilter();
 					magFilter = texture->getMagFilter();
+					minLOD = texture->getMinLOD();
+					maxLOD = texture->getMaxLOD();
 				}
 				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
 
@@ -3074,6 +3079,8 @@
 				device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
 				device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
 				device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
+				device->setMinLod(samplerType, samplerIndex, minLOD);
+				device->setMaxLod(samplerType, samplerIndex, maxLOD);
 				device->setBaseLevel(samplerType, samplerIndex, baseLevel);
 				device->setMaxLevel(samplerType, samplerIndex, maxLevel);
 
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp
index 331d15a..7b6580a 100644
--- a/src/Renderer/PixelProcessor.cpp
+++ b/src/Renderer/PixelProcessor.cpp
@@ -498,6 +498,24 @@
 		else ASSERT(false);
 	}
 
+	void PixelProcessor::setMinLod(unsigned int sampler, float minLod)
+	{
+		if(sampler < TEXTURE_IMAGE_UNITS)
+		{
+			context->sampler[sampler].setMinLod(minLod);
+		}
+		else ASSERT(false);
+	}
+
+	void PixelProcessor::setMaxLod(unsigned int sampler, float maxLod)
+	{
+		if(sampler < TEXTURE_IMAGE_UNITS)
+		{
+			context->sampler[sampler].setMaxLod(maxLod);
+		}
+		else ASSERT(false);
+	}
+
 	void PixelProcessor::setWriteSRGB(bool sRGB)
 	{
 		context->setWriteSRGB(sRGB);
diff --git a/src/Renderer/PixelProcessor.hpp b/src/Renderer/PixelProcessor.hpp
index a47da3f..7081809 100644
--- a/src/Renderer/PixelProcessor.hpp
+++ b/src/Renderer/PixelProcessor.hpp
@@ -237,6 +237,8 @@
 		virtual void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
 		virtual void setBaseLevel(unsigned int sampler, int baseLevel);
 		virtual void setMaxLevel(unsigned int sampler, int maxLevel);
+		virtual void setMinLod(unsigned int sampler, float minLod);
+		virtual void setMaxLod(unsigned int sampler, float maxLod);
 
 		virtual void setWriteSRGB(bool sRGB);
 		virtual void setDepthBufferEnable(bool depthBufferEnable);
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index 681ce37..df6a2c7 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -2371,6 +2371,30 @@
 		}
 	}
 
+	void Renderer::setMinLod(SamplerType type, int sampler, float minLod)
+	{
+		if(type == SAMPLER_PIXEL)
+		{
+			PixelProcessor::setMinLod(sampler, minLod);
+		}
+		else
+		{
+			VertexProcessor::setMinLod(sampler, minLod);
+		}
+	}
+
+	void Renderer::setMaxLod(SamplerType type, int sampler, float maxLod)
+	{
+		if(type == SAMPLER_PIXEL)
+		{
+			PixelProcessor::setMaxLod(sampler, maxLod);
+		}
+		else
+		{
+			VertexProcessor::setMaxLod(sampler, maxLod);
+		}
+	}
+
 	void Renderer::setPointSpriteEnable(bool pointSpriteEnable)
 	{
 		context->setPointSpriteEnable(pointSpriteEnable);
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index 3fa3bae..5d9ef35 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -347,6 +347,8 @@
 		virtual void setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA);
 		virtual void setBaseLevel(SamplerType type, int sampler, int baseLevel);
 		virtual void setMaxLevel(SamplerType type, int sampler, int maxLevel);
+		virtual void setMinLod(SamplerType type, int sampler, float minLod);
+		virtual void setMaxLod(SamplerType type, int sampler, float maxLod);
 
 		virtual void setPointSpriteEnable(bool pointSpriteEnable);
 		virtual void setPointScaleEnable(bool pointScaleEnable);
diff --git a/src/Renderer/Sampler.cpp b/src/Renderer/Sampler.cpp
index 5c434fe..93cca30 100644
--- a/src/Renderer/Sampler.cpp
+++ b/src/Renderer/Sampler.cpp
@@ -73,6 +73,11 @@
 
 		texture.LOD = 0.0f;
 		exp2LOD = 1.0f;
+
+		texture.baseLevel = 0;
+		texture.maxLevel = 1000;
+		texture.maxLod = 1000;
+		texture.minLod = -1000;
 	}
 
 	Sampler::~Sampler()
@@ -344,6 +349,16 @@
 		texture.maxLevel = maxLevel;
 	}
 
+	void Sampler::setMinLod(float minLod)
+	{
+		texture.minLod = minLod;
+	}
+
+	void Sampler::setMaxLod(float maxLod)
+	{
+		texture.maxLod = maxLod;
+	}
+
 	void Sampler::setFilterQuality(FilterType maximumFilterQuality)
 	{
 		Sampler::maximumTextureFilterQuality = maximumFilterQuality;
diff --git a/src/Renderer/Sampler.hpp b/src/Renderer/Sampler.hpp
index cbb0588..032bf58 100644
--- a/src/Renderer/Sampler.hpp
+++ b/src/Renderer/Sampler.hpp
@@ -69,6 +69,8 @@
 		float maxAnisotropy;
 		int baseLevel;
 		int maxLevel;
+		float minLod;
+		float maxLod;
 	};
 
 	enum SamplerType
@@ -182,6 +184,8 @@
 		void setSwizzleA(SwizzleType swizzleA);
 		void setBaseLevel(int baseLevel);
 		void setMaxLevel(int maxLevel);
+		void setMinLod(float minLod);
+		void setMaxLod(float maxLod);
 
 		static void setFilterQuality(FilterType maximumFilterQuality);
 		static void setMipmapQuality(MipmapType maximumFilterQuality);
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp
index 2b0a97f..402e11a 100644
--- a/src/Renderer/VertexProcessor.cpp
+++ b/src/Renderer/VertexProcessor.cpp
@@ -656,6 +656,24 @@
 		else ASSERT(false);
 	}
 
+	void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
+	{
+		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
+		{
+			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
+		}
+		else ASSERT(false);
+	}
+
+	void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
+	{
+		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
+		{
+			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
+		}
+		else ASSERT(false);
+	}
+
 	void VertexProcessor::setPointSize(float pointSize)
 	{
 		point.pointSize = replicate(pointSize);
diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp
index 3df2ad8..2f8122a 100644
--- a/src/Renderer/VertexProcessor.hpp
+++ b/src/Renderer/VertexProcessor.hpp
@@ -262,6 +262,8 @@
 		virtual void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
 		virtual void setBaseLevel(unsigned int sampler, int baseLevel);
 		virtual void setMaxLevel(unsigned int sampler, int maxLevel);
+		virtual void setMinLod(unsigned int sampler, float minLod);
+		virtual void setMaxLod(unsigned int sampler, float maxLod);
 
 		virtual void setPointSize(float pointSize);
 		virtual void setPointSizeMin(float pointSizeMin);