Fixed sampler allocation

Instead of testing for the number of samplers used so far
in the shader, the Program object was checking for the
register index, which could have been larger or equal to
MAX_VERTEX_TEXTURE_IMAGE_UNITS or MAX_TEXTURE_IMAGE_UNITS,
making the shader compilation fail erroneously.

Changed sampler arrays to maps in order to get the sampler
data from the register index.

Change-Id: Iba6cbf0dbbcdbd926f2670af4413710550e341a9
Reviewed-on: https://swiftshader-review.googlesource.com/15428
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 00351e1..76058d3 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3074,15 +3074,16 @@
 {
 	Program *programObject = getCurrentProgram();
 
-	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
+	const std::map<int, es2::Program::Sampler> &samplerMap = programObject->getSamplerMap(samplerType);
 
-	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
+	int samplerIndex = 0;
+	for(auto sampler : samplerMap)
 	{
-		int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index
+		int textureUnit = sampler.second.logicalTextureUnit;
 
 		if(textureUnit != -1)
 		{
-			TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
+			TextureType textureType = programObject->getSamplerTextureType(samplerType, sampler.first);
 
 			Texture *texture = getSamplerTexture(textureUnit, textureType);
 
@@ -3153,6 +3154,13 @@
 		{
 			applyTexture(samplerType, samplerIndex, nullptr);
 		}
+		++samplerIndex;
+	}
+
+	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;
+	for(; samplerIndex < samplerCount; ++samplerIndex)
+	{
+		applyTexture(samplerType, samplerIndex, nullptr);
 	}
 }
 
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index 5abf345..c7af7a5 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -304,38 +304,9 @@
 		return attributeStream[attributeIndex];
 	}
 
-	// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)
-	GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
+	const std::map<int, es2::Program::Sampler>& Program::getSamplerMap(sw::SamplerType type) const
 	{
-		GLint logicalTextureUnit = -1;
-
-		switch(type)
-		{
-		case sw::SAMPLER_PIXEL:
-			ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
-
-			if(samplersPS[samplerIndex].active)
-			{
-				logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
-			}
-			break;
-		case sw::SAMPLER_VERTEX:
-			ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
-
-			if(samplersVS[samplerIndex].active)
-			{
-				logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
-			}
-			break;
-		default: UNREACHABLE(type);
-		}
-
-		if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
-		{
-			return logicalTextureUnit;
-		}
-
-		return -1;
+		return (type == sw::SAMPLER_PIXEL) ? samplersPS : samplersVS;
 	}
 
 	// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
@@ -344,12 +315,8 @@
 		switch(type)
 		{
 		case sw::SAMPLER_PIXEL:
-			ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
-			ASSERT(samplersPS[samplerIndex].active);
 			return samplersPS[samplerIndex].textureType;
 		case sw::SAMPLER_VERTEX:
-			ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
-			ASSERT(samplersVS[samplerIndex].active);
 			return samplersVS[samplerIndex].textureType;
 		default: UNREACHABLE(type);
 		}
@@ -1709,10 +1676,8 @@
 			{
 				if(shader == GL_VERTEX_SHADER)
 				{
-					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+					if(samplersVS.size() < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
 					{
-						samplersVS[index].active = true;
-
 						switch(type)
 						{
 						default:                      UNREACHABLE(type);
@@ -1744,10 +1709,8 @@
 				}
 				else if(shader == GL_FRAGMENT_SHADER)
 				{
-					if(index < MAX_TEXTURE_IMAGE_UNITS)
+					if(samplersPS.size() < MAX_TEXTURE_IMAGE_UNITS)
 					{
-						samplersPS[index].active = true;
-
 						switch(type)
 						{
 						default:                      UNREACHABLE(type);
@@ -2267,9 +2230,8 @@
 				{
 					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
 
-					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+					if(samplersPS.find(samplerIndex) != samplersPS.end())
 					{
-						ASSERT(samplersPS[samplerIndex].active);
 						samplersPS[samplerIndex].logicalTextureUnit = v[i];
 					}
 				}
@@ -2281,9 +2243,8 @@
 				{
 					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
 
-					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+					if(samplersVS.find(samplerIndex) != samplersVS.end())
 					{
-						ASSERT(samplersVS[samplerIndex].active);
 						samplersVS[samplerIndex].logicalTextureUnit = v[i];
 					}
 				}
@@ -2369,9 +2330,8 @@
 				{
 					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
 
-					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+					if(samplersPS.find(samplerIndex) != samplersPS.end())
 					{
-						ASSERT(samplersPS[samplerIndex].active);
 						samplersPS[samplerIndex].logicalTextureUnit = v[i];
 					}
 				}
@@ -2383,9 +2343,8 @@
 				{
 					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
 
-					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+					if(samplersVS.find(samplerIndex) != samplersVS.end())
 					{
-						ASSERT(samplersVS[samplerIndex].active);
 						samplersVS[samplerIndex].logicalTextureUnit = v[i];
 					}
 				}
@@ -2510,15 +2469,8 @@
 			attributeStream[index] = -1;
 		}
 
-		for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
-		{
-			samplersPS[index].active = false;
-		}
-
-		for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
-		{
-			samplersVS[index].active = false;
-		}
+		samplersPS.clear();
+		samplersVS.clear();
 
 		while(!uniforms.empty())
 		{
@@ -2934,73 +2886,67 @@
 			textureUnitType[i] = TEXTURE_UNKNOWN;
 		}
 
-		for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
+		for(auto sampler : samplersPS)
 		{
-			if(samplersPS[i].active)
-			{
-				unsigned int unit = samplersPS[i].logicalTextureUnit;
+			unsigned int unit = sampler.second.logicalTextureUnit;
 
-				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+			if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+			{
+				if(logErrors)
+				{
+					appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+				}
+
+				return false;
+			}
+
+			if(textureUnitType[unit] != TEXTURE_UNKNOWN)
+			{
+				if(sampler.second.textureType != textureUnitType[unit])
 				{
 					if(logErrors)
 					{
-						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+						appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
 					}
 
 					return false;
 				}
-
-				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
-				{
-					if(samplersPS[i].textureType != textureUnitType[unit])
-					{
-						if(logErrors)
-						{
-							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
-						}
-
-						return false;
-					}
-				}
-				else
-				{
-					textureUnitType[unit] = samplersPS[i].textureType;
-				}
+			}
+			else
+			{
+				textureUnitType[unit] = sampler.second.textureType;
 			}
 		}
 
-		for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+		for(auto sampler : samplersVS)
 		{
-			if(samplersVS[i].active)
-			{
-				unsigned int unit = samplersVS[i].logicalTextureUnit;
+			unsigned int unit = sampler.second.logicalTextureUnit;
 
-				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+			if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+			{
+				if(logErrors)
+				{
+					appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+				}
+
+				return false;
+			}
+
+			if(textureUnitType[unit] != TEXTURE_UNKNOWN)
+			{
+				if(sampler.second.textureType != textureUnitType[unit])
 				{
 					if(logErrors)
 					{
-						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+						appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
 					}
 
 					return false;
 				}
-
-				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
-				{
-					if(samplersVS[i].textureType != textureUnitType[unit])
-					{
-						if(logErrors)
-						{
-							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
-						}
-
-						return false;
-					}
-				}
-				else
-				{
-					textureUnitType[unit] = samplersVS[i].textureType;
-				}
+			}
+			else
+			{
+				textureUnitType[unit] = sampler.second.textureType;
 			}
 		}
 
diff --git a/src/OpenGL/libGLESv2/Program.h b/src/OpenGL/libGLESv2/Program.h
index 451b2dc..e43d8f1 100644
--- a/src/OpenGL/libGLESv2/Program.h
+++ b/src/OpenGL/libGLESv2/Program.h
@@ -121,6 +121,12 @@
 	class Program
 	{
 	public:
+		struct Sampler
+		{
+			GLint logicalTextureUnit;
+			TextureType textureType;
+		};
+
 		Program(ResourceManager *manager, GLuint handle);
 
 		~Program();
@@ -136,7 +142,7 @@
 		GLint getAttributeLocation(const char *name);
 		int getAttributeStream(int attributeIndex);
 
-		GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex);
+		const std::map<int, es2::Program::Sampler>& getSamplerMap(sw::SamplerType type) const;
 		TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);
 
 		GLuint getUniformIndex(const std::string &name) const;
@@ -291,15 +297,8 @@
 		GLenum transformFeedbackBufferMode;
 		size_t totalLinkedVaryingsComponents;
 
-		struct Sampler
-		{
-			bool active;
-			GLint logicalTextureUnit;
-			TextureType textureType;
-		};
-
-		Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];
-		Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+		std::map<int, Sampler> samplersPS;
+		std::map<int, Sampler> samplersVS;
 
 		typedef std::vector<Uniform*> UniformArray;
 		UniformArray uniforms;