Fix internalformat handling.

- Use internalformat parameter if valid, instead of deriving from
  format/type parameters.
- Validate format/type/internalformat parameters in CopyTexSubImage().
- Moved early-out optimizations after validation.
- Removed duplicate validation.
- Use GLint consistently for internalformat parameters.

Change-Id: I377c6bb5381602d13d281f19985aa4f11d201099
Reviewed-on: https://swiftshader-review.googlesource.com/14488
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/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 3d7aa42..08abb33 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -902,7 +902,6 @@
 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
 				{
-
 					GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
 					if(validationError != GL_NONE)
 					{
@@ -941,12 +940,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
-	if(validationError != GL_NONE)
-	{
-		return error(validationError);
-	}
-
 	if(imageSize != egl::ComputeCompressedSize(width, height, format))
 	{
 		return error(GL_INVALID_VALUE);
@@ -956,11 +949,6 @@
 
 	if(context)
 	{
-		if(imageSize != egl::ComputeCompressedSize(width, height, format))
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
 		if(xoffset % 4 != 0 || yoffset % 4 != 0)
 		{
 			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
@@ -973,41 +961,37 @@
 		{
 			es2::Texture2D *texture = context->getTexture2D();
 
-			GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
-
-			if(validationError == GL_NONE)
-			{
-				validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
-			}
-
-			if(validationError == GL_NONE)
-			{
-				texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
-			}
-			else
+			GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
+			if(validationError != GL_NONE)
 			{
 				return error(validationError);
 			}
+
+			validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
+			if(validationError != GL_NONE)
+			{
+				return error(validationError);
+			}
+
+			texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
 		}
 		else if(es2::IsCubemapTextureTarget(target))
 		{
 			es2::TextureCubeMap *texture = context->getTextureCubeMap();
 
-			GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
-
-			if(validationError == GL_NONE)
-			{
-				validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
-			}
-
-			if(validationError == GL_NONE)
-			{
-				texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
-			}
-			else
+			GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
+			if(validationError != GL_NONE)
 			{
 				return error(validationError);
 			}
+
+			validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
+			if(validationError != GL_NONE)
+			{
+				return error(validationError);
+			}
+
+			texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
 		}
 		else UNREACHABLE(target);
 	}
@@ -1136,11 +1120,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(width == 0 || height == 0)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -1171,7 +1150,7 @@
 		}
 		else UNREACHABLE(target);
 
-		GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);
+		GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE, GL_NONE, texture, context->getClientVersion());
 		if(validationError != GL_NONE)
 		{
 			return error(validationError);
@@ -4759,7 +4738,7 @@
 
 		GLint clientVersion = context->getClientVersion();
 
-		if(IsColorRenderable(internalformat, clientVersion, false))
+		if(IsColorRenderable(internalformat, clientVersion))
 		{
 			context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
 		}
@@ -5102,9 +5081,10 @@
 			return error(validationError);
 		}
 
-		if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
+		validationError = ValidateTextureFormatType(format, type, internalformat, context->getClientVersion());
+		if(validationError != GL_NONE)
 		{
-			return;
+			return error(validationError);
 		}
 
 		if(border != 0)
@@ -5142,7 +5122,7 @@
 			return error(GL_INVALID_ENUM);
 		}
 
-		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+		GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
 
 		validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
 		if(validationError != GL_NONE)
@@ -5501,57 +5481,47 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
-	{
-		return;
-	}
-
-	if(width == 0 || height == 0)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
 	{
 		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
 
-		GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
-		if(validationError != GL_NONE)
-		{
-			return error(validationError);
-		}
-
 		if(target == GL_TEXTURE_2D)
 		{
 			es2::Texture2D *texture = context->getTexture2D();
 
-			validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
-
-			if(validationError == GL_NONE)
-			{
-				texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
-			}
-			else
+			GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
+			if(validationError != GL_NONE)
 			{
 				return error(validationError);
 			}
+
+			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
+			if(validationError != GL_NONE)
+			{
+				return error(validationError);
+			}
+
+			texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
 		}
 		else if(es2::IsCubemapTextureTarget(target))
 		{
 			es2::TextureCubeMap *texture = context->getTextureCubeMap();
 
-			validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
-
-			if(validationError == GL_NONE)
-			{
-				texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
-			}
-			else
+			GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
+			if(validationError != GL_NONE)
 			{
 				return error(validationError);
 			}
+
+			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
+			if(validationError != GL_NONE)
+			{
+				return error(validationError);
+			}
+
+			texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
 		}
 		else UNREACHABLE(target);
 	}
@@ -6349,9 +6319,15 @@
 		return error(GL_INVALID_ENUM);
 	}
 
-	if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
+	if(internalformat != (GLint)format)
 	{
-		return;
+		return error(GL_INVALID_OPERATION);
+	}
+
+	GLenum validationError = ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion());
+	if(validationError != GL_NONE)
+	{
+		return error(validationError);
 	}
 
 	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
@@ -6430,21 +6406,19 @@
 
 		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
 
-		GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
-
-		if(validationError == GL_NONE)
-		{
-			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
-		}
-
-		if(validationError == GL_NONE)
-		{
-			texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
-		}
-		else
+		GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
+		if(validationError != GL_NONE)
 		{
 			return error(validationError);
 		}
+
+		validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
+		if(validationError != GL_NONE)
+		{
+			return error(validationError);
+		}
+
+		texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
 	}
 }
 
@@ -6487,8 +6461,7 @@
 
 		es2::Texture3D *texture = context->getTexture3D();
 
-		GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
-
+		GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion());
 		if(validationError != GL_NONE)
 		{
 			return error(validationError);
@@ -6616,7 +6589,6 @@
 		}
 
 		GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
-
 		if(validationError != GL_NONE)
 		{
 			return error(validationError);