Search the top level from the base level.

The 'top' level is the last valid mipmap level nearest to the top of
the pyramid. Start searching for it from the 'base' of the pyramid.

Change-Id: I2d2ea3a1834f6cff2e2d342876d0649205004581
Reviewed-on: https://swiftshader-review.googlesource.com/15348
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGL/Context.cpp b/src/OpenGL/libGL/Context.cpp
index f74ebda..8f8d96a 100644
--- a/src/OpenGL/libGL/Context.cpp
+++ b/src/OpenGL/libGL/Context.cpp
@@ -2109,7 +2109,7 @@
 
 	if(baseTexture && textureUsed)
 	{
-		int levelCount = baseTexture->getLevelCount();
+		int topLevel = baseTexture->getTopLevel();
 
 		if(baseTexture->getTarget() == GL_TEXTURE_2D)
 		{
@@ -2123,9 +2123,9 @@
 				{
 					surfaceLevel = 0;
 				}
-				else if(surfaceLevel >= levelCount)
+				else if(surfaceLevel > topLevel)
 				{
-					surfaceLevel = levelCount - 1;
+					surfaceLevel = topLevel;
 				}
 
 				Image *surface = texture->getImage(surfaceLevel);
@@ -2146,9 +2146,9 @@
 					{
 						surfaceLevel = 0;
 					}
-					else if(surfaceLevel >= levelCount)
+					else if(surfaceLevel > topLevel)
 					{
-						surfaceLevel = levelCount - 1;
+						surfaceLevel = topLevel;
 					}
 
 					Image *surface = cubeTexture->getImage(face, surfaceLevel);
diff --git a/src/OpenGL/libGL/Texture.cpp b/src/OpenGL/libGL/Texture.cpp
index 38b9cc6..3f5102a 100644
--- a/src/OpenGL/libGL/Texture.cpp
+++ b/src/OpenGL/libGL/Texture.cpp
@@ -353,7 +353,7 @@
 	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
 }
 
-int Texture2D::getLevelCount() const
+int Texture2D::getTopLevel() const
 {
 	ASSERT(isSamplerComplete());
 	int levels = 0;
@@ -726,7 +726,7 @@
 	return image[face][level] ? image[face][level]->getInternalFormat() : sw::FORMAT_NULL;
 }
 
-int TextureCubeMap::getLevelCount() const
+int TextureCubeMap::getTopLevel() const
 {
 	ASSERT(isSamplerComplete());
 	int levels = 0;
diff --git a/src/OpenGL/libGL/Texture.h b/src/OpenGL/libGL/Texture.h
index ed124c8..483dc77 100644
--- a/src/OpenGL/libGL/Texture.h
+++ b/src/OpenGL/libGL/Texture.h
@@ -77,7 +77,7 @@
 	virtual GLenum getFormat(GLenum target, GLint level) const = 0;
 	virtual GLenum getType(GLenum target, GLint level) const = 0;
 	virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
-	virtual int getLevelCount() const = 0;
+	virtual int getTopLevel() const = 0;
 
 	virtual bool isSamplerComplete() const = 0;
 	virtual bool isCompressed(GLenum target, GLint level) const = 0;
@@ -126,7 +126,7 @@
 	virtual GLenum getFormat(GLenum target, GLint level) const;
 	virtual GLenum getType(GLenum target, GLint level) const;
 	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
-	virtual int getLevelCount() const;
+	virtual int getTopLevel() const;
 
 	void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
 	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
@@ -179,7 +179,7 @@
 	virtual GLenum getFormat(GLenum target, GLint level) const;
 	virtual GLenum getType(GLenum target, GLint level) const;
 	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
-	virtual int getLevelCount() const;
+	virtual int getTopLevel() const;
 
 	void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
 	void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index 398c699..635d256 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -2358,7 +2358,7 @@
 
 	if(baseTexture)
 	{
-		int levelCount = baseTexture->getLevelCount();
+		int topLevel = baseTexture->getTopLevel();
 
 		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
 		{
@@ -2372,9 +2372,9 @@
 				{
 					surfaceLevel = 0;
 				}
-				else if(surfaceLevel >= levelCount)
+				else if(surfaceLevel > topLevel)
 				{
-					surfaceLevel = levelCount - 1;
+					surfaceLevel = topLevel;
 				}
 
 				egl::Image *surface = texture->getImage(surfaceLevel);
@@ -3147,7 +3147,7 @@
 			return EGL_BAD_PARAMETER;
 		}
 
-		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
+		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getTopLevel() == 0))
 		{
 			return EGL_BAD_PARAMETER;
 		}
diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index eba8f78..4b03dc2 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -444,17 +444,17 @@
 	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
 }
 
-int Texture2D::getLevelCount() const
+int Texture2D::getTopLevel() const
 {
 	ASSERT(isSamplerComplete());
-	int levels = 0;
+	int level = 0;
 
-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+	while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
 	{
-		levels++;
+		level++;
 	}
 
-	return levels;
+	return level - 1;
 }
 
 void Texture2D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
diff --git a/src/OpenGL/libGLES_CM/Texture.h b/src/OpenGL/libGLES_CM/Texture.h
index c99c1dc..c66ed19 100644
--- a/src/OpenGL/libGLES_CM/Texture.h
+++ b/src/OpenGL/libGLES_CM/Texture.h
@@ -79,7 +79,7 @@
 	virtual GLenum getFormat(GLenum target, GLint level) const = 0;
 	virtual GLenum getType(GLenum target, GLint level) const = 0;
 	virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
-	virtual int getLevelCount() const = 0;
+	virtual int getTopLevel() const = 0;
 
 	virtual bool isSamplerComplete() const = 0;
 	virtual bool isCompressed(GLenum target, GLint level) const = 0;
@@ -137,7 +137,7 @@
 	GLenum getFormat(GLenum target, GLint level) const override;
 	GLenum getType(GLenum target, GLint level) const override;
 	sw::Format getInternalFormat(GLenum target, GLint level) const override;
-	int getLevelCount() const override;
+	int getTopLevel() const override;
 
 	void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
 	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 5862d2d..8590b54 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3183,7 +3183,7 @@
 
 	if(baseTexture && textureUsed)
 	{
-		int levelCount = baseTexture->getLevelCount();
+		int topLevel = baseTexture->getTopLevel();
 
 		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
 		{
@@ -3197,9 +3197,9 @@
 				{
 					surfaceLevel = 0;
 				}
-				else if(surfaceLevel >= levelCount)
+				else if(surfaceLevel > topLevel)
 				{
-					surfaceLevel = levelCount - 1;
+					surfaceLevel = topLevel;
 				}
 
 				egl::Image *surface = texture->getImage(surfaceLevel);
@@ -3218,9 +3218,9 @@
 				{
 					surfaceLevel = 0;
 				}
-				else if(surfaceLevel >= levelCount)
+				else if(surfaceLevel > topLevel)
 				{
-					surfaceLevel = levelCount - 1;
+					surfaceLevel = topLevel;
 				}
 
 				egl::Image *surface = texture->getImage(surfaceLevel);
@@ -3239,9 +3239,9 @@
 				{
 					surfaceLevel = 0;
 				}
-				else if(surfaceLevel >= levelCount)
+				else if(surfaceLevel > topLevel)
 				{
-					surfaceLevel = levelCount - 1;
+					surfaceLevel = topLevel;
 				}
 
 				egl::Image *surface = texture->getImage(surfaceLevel);
@@ -3264,9 +3264,9 @@
 					{
 						surfaceLevel = 0;
 					}
-					else if(surfaceLevel >= levelCount)
+					else if(surfaceLevel > topLevel)
 					{
-						surfaceLevel = levelCount - 1;
+						surfaceLevel = topLevel;
 					}
 
 					egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
@@ -4376,7 +4376,7 @@
 			return EGL_BAD_PARAMETER;
 		}
 
-		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
+		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getTopLevel() == 0))
 		{
 			return EGL_BAD_PARAMETER;
 		}
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index 4776d66..fa5817d 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -589,17 +589,17 @@
 	return image[level] ? image[level]->getType() : GL_NONE;
 }
 
-int Texture2D::getLevelCount() const
+int Texture2D::getTopLevel() const
 {
 	ASSERT(isSamplerComplete());
-	int levels = 0;
+	int level = mBaseLevel;
 
-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+	while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
 	{
-		levels++;
+		level++;
 	}
 
-	return levels;
+	return level - 1;
 }
 
 void Texture2D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
@@ -1076,17 +1076,17 @@
 	return image[face][level] ? image[face][level]->getType() : 0;
 }
 
-int TextureCubeMap::getLevelCount() const
+int TextureCubeMap::getTopLevel() const
 {
 	ASSERT(isSamplerComplete());
-	int levels = 0;
+	int level = mBaseLevel;
 
-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][levels])
+	while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][level])
 	{
-		levels++;
+		level++;
 	}
 
-	return levels;
+	return level - 1;
 }
 
 void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
@@ -1613,17 +1613,17 @@
 	return image[level] ? image[level]->getType() : GL_NONE;
 }
 
-int Texture3D::getLevelCount() const
+int Texture3D::getTopLevel() const
 {
 	ASSERT(isSamplerComplete());
-	int levels = 0;
+	int level = mBaseLevel;
 
-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+	while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
 	{
-		levels++;
+		level++;
 	}
 
-	return levels;
+	return level - 1;
 }
 
 void Texture3D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h
index 5badc9f..10f0c11 100644
--- a/src/OpenGL/libGLESv2/Texture.h
+++ b/src/OpenGL/libGLESv2/Texture.h
@@ -97,7 +97,7 @@
 	virtual GLsizei getDepth(GLenum target, GLint level) const;
 	virtual GLenum getFormat(GLenum target, GLint level) const = 0;
 	virtual GLenum getType(GLenum target, GLint level) const = 0;
-	virtual int getLevelCount() const = 0;
+	virtual int getTopLevel() const = 0;
 
 	virtual bool isSamplerComplete() const = 0;
 	virtual bool isCompressed(GLenum target, GLint level) const = 0;
@@ -160,7 +160,7 @@
 	GLsizei getHeight(GLenum target, GLint level) const override;
 	GLenum getFormat(GLenum target, GLint level) const override;
 	GLenum getType(GLenum target, GLint level) const override;
-	int getLevelCount() const override;
+	int getTopLevel() const override;
 
 	void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
 	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
@@ -218,7 +218,7 @@
 	GLsizei getHeight(GLenum target, GLint level) const override;
 	GLenum getFormat(GLenum target, GLint level) const override;
 	GLenum getType(GLenum target, GLint level) const override;
-	int getLevelCount() const override;
+	int getTopLevel() const override;
 
 	void setImage(egl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
 	void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
@@ -280,7 +280,7 @@
 	GLsizei getDepth(GLenum target, GLint level) const override;
 	GLenum getFormat(GLenum target, GLint level) const override;
 	GLenum getType(GLenum target, GLint level) const override;
-	int getLevelCount() const override;
+	int getTopLevel() const override;
 
 	void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
 	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);