Fixed format validations

Format validations were failing if the exact same format
wasn't used between different texture related calls to the
same texture, even when the formats were equivalent, so I
added a GetSizedInternalFormat function based on a format
map (courtesy of Angle). The validation checks were also
unified in utilities.cpp and used wherever texture formats
were used, to make sure Image objects used in Texture
objects always use the sized format, so that format
comparisons work properly.

Change-Id: I72fc8fb1b0f135ac679c274866e5b8e223541e7f
Reviewed-on: https://swiftshader-review.googlesource.com/4082
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/common/Image.cpp b/src/OpenGL/common/Image.cpp
index 32c3744..9799f98 100644
--- a/src/OpenGL/common/Image.cpp
+++ b/src/OpenGL/common/Image.cpp
@@ -468,6 +468,7 @@
 			}
 			break;
 		case GL_BGRA_EXT:
+		case GL_BGRA8_EXT:
 			switch(type)
 			{
 			case GL_UNSIGNED_BYTE:          return sw::FORMAT_A8R8G8B8;
@@ -735,6 +736,7 @@
 			case GL_RGBA_INTEGER:
 				return sw::FORMAT_A8B8G8R8UI;
 			case GL_BGRA_EXT:
+			case GL_BGRA8_EXT:
 				return sw::FORMAT_A8R8G8B8;
 			case GL_ALPHA:
 			case GL_ALPHA8_EXT:
@@ -923,7 +925,8 @@
 			case GL_SRGB8_ALPHA8:
 			case GL_RGBA:            return sizeof(unsigned char) * 4;
 			case GL_RGBA_INTEGER:    return sizeof(unsigned char) * 4;
-			case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
+			case GL_BGRA_EXT:
+			case GL_BGRA8_EXT:       return sizeof(unsigned char)* 4;
 			default: UNREACHABLE(format);
 			}
 			break;
@@ -1226,6 +1229,7 @@
 					case GL_RGBA:
 					case GL_RGBA_INTEGER:
 					case GL_BGRA_EXT:
+					case GL_BGRA8_EXT:
 						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					default: UNREACHABLE(format);
@@ -1267,6 +1271,7 @@
 					case GL_RGBA:
 					case GL_RGBA_INTEGER:
 					case GL_BGRA_EXT:
+					case GL_BGRA8_EXT:
 						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_SRGB8:
@@ -1441,6 +1446,7 @@
 					case GL_RGBA:
 					case GL_RGBA_INTEGER:
 					case GL_BGRA_EXT:
+					case GL_BGRA8_EXT:
 						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					default: UNREACHABLE(format);
@@ -1471,6 +1477,7 @@
 					case GL_RGBA:
 					case GL_RGBA_INTEGER:
 					case GL_BGRA_EXT:
+					case GL_BGRA8_EXT:
 						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_DEPTH_COMPONENT:
@@ -1505,6 +1512,7 @@
 					case GL_RGBA:
 					case GL_RGBA_INTEGER:
 					case GL_BGRA_EXT:
+					case GL_BGRA8_EXT:
 						LoadImageData<Bytes_16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					default: UNREACHABLE(format);
@@ -1535,6 +1543,7 @@
 					case GL_RGBA:
 					case GL_RGBA_INTEGER:
 					case GL_BGRA_EXT:
+					case GL_BGRA8_EXT:
 						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_DEPTH_COMPONENT16:
diff --git a/src/OpenGL/libGL/Texture.cpp b/src/OpenGL/libGL/Texture.cpp
index e6b761d..162599c 100644
--- a/src/OpenGL/libGL/Texture.cpp
+++ b/src/OpenGL/libGL/Texture.cpp
@@ -339,13 +339,13 @@
 GLenum Texture2D::getFormat(GLenum target, GLint level) const

 {

 	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);

-    return image[level] ? image[level]->getFormat() : 0;

+	return image[level] ? image[level]->getFormat() : GL_NONE;

 }

 

 GLenum Texture2D::getType(GLenum target, GLint level) const

 {

 	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);

-    return image[level] ? image[level]->getType() : 0;

+	return image[level] ? image[level]->getType() : GL_NONE;

 }

 

 sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const

@@ -716,13 +716,13 @@
 GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const

 {

 	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getFormat() : 0;

+	return image[face][level] ? image[face][level]->getFormat() : GL_NONE;

 }

 

 GLenum TextureCubeMap::getType(GLenum target, GLint level) const

 {

 	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getType() : 0;

+	return image[face][level] ? image[face][level]->getType() : GL_NONE;

 }

 

 sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const

diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index 13b52c0..0741b03 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -407,13 +407,13 @@
 GLenum Texture2D::getFormat(GLenum target, GLint level) const

 {

 	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getFormat() : 0;

+	return image[level] ? image[level]->getFormat() : GL_NONE;

 }

 

 GLenum Texture2D::getType(GLenum target, GLint level) const

 {

 	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getType() : 0;

+	return image[level] ? image[level]->getType() : GL_NONE;

 }

 

 sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const

diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index 79bc28e..7c216b9 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -578,13 +578,13 @@
 GLenum Texture2D::getFormat(GLenum target, GLint level) const

 {

 	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getFormat() : 0;

+	return image[level] ? image[level]->getFormat() : GL_NONE;

 }

 

 GLenum Texture2D::getType(GLenum target, GLint level) const

 {

 	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getType() : 0;

+	return image[level] ? image[level]->getType() : GL_NONE;

 }

 

 sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const

@@ -678,7 +678,8 @@
 		image[level]->unbind(this);

 	}

 

-	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);

+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

+	image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);

 

 	if(!image[level])

 	{

@@ -713,7 +714,8 @@
 		image[level]->unbind(this);

 	}

 

-	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);

+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

+	image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);

 

 	if(!image[level])

 	{

@@ -733,7 +735,7 @@
 		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);

 		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

 

-        copy(renderTarget, sourceRect, format, 0, 0, 0, image[level]);

+		copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[level]);

     }

 

 	renderTarget->release();

@@ -1079,7 +1081,8 @@
 		image[face][level]->unbind(this);

 	}

 

-	image[face][level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);

+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

+	image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);

 

 	if(!image[face][level])

 	{

@@ -1247,7 +1250,8 @@
 		image[face][level]->unbind(this);

 	}

 

-	image[face][level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);

+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

+	image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);

 

 	if(!image[face][level])

 	{

@@ -1267,7 +1271,7 @@
 		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);

 		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

         

-        copy(renderTarget, sourceRect, format, 0, 0, 0, image[face][level]);

+		copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[face][level]);

     }

 

 	renderTarget->release();

@@ -1484,13 +1488,13 @@
 GLenum Texture3D::getFormat(GLenum target, GLint level) const

 {

 	ASSERT(target == getTarget());

-	return image[level] ? image[level]->getFormat() : 0;

+	return image[level] ? image[level]->getFormat() : GL_NONE;

 }

 

 GLenum Texture3D::getType(GLenum target, GLint level) const

 {

 	ASSERT(target == getTarget());

-	return image[level] ? image[level]->getType() : 0;

+	return image[level] ? image[level]->getType() : GL_NONE;

 }

 

 sw::Format Texture3D::getInternalFormat(GLenum target, GLint level) const

@@ -1580,7 +1584,8 @@
 		image[level]->unbind(this);

 	}

 

-	image[level] = new egl::Image(this, width, height, depth, format, GL_UNSIGNED_BYTE);

+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

+	image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);

 

 	if(!image[level])

 	{

@@ -1592,7 +1597,7 @@
 

 void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)

 {

-	Texture::subImage(xoffset, yoffset, zoffset, width, height, format, depth, type, unpackInfo, pixels, image[level]);

+	Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels, image[level]);

 }

 

 void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)

@@ -1615,7 +1620,8 @@
 		image[level]->unbind(this);

 	}

 

-	image[level] = new egl::Image(this, width, height, depth, format, GL_UNSIGNED_BYTE);

+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

+	image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);

 

 	if(!image[level])

 	{

@@ -1636,7 +1642,7 @@
 		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

 		for(GLint sliceZ = 0; sliceZ < depth; ++sliceZ, ++sourceRect.slice)

 		{

-			copy(renderTarget, sourceRect, format, 0, 0, sliceZ, image[level]);

+			copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, sliceZ, image[level]);

 		}

 	}

 

diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 44bf326..b5364b9 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -57,84 +57,12 @@
 	return true;

 }

 

-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)

-{

-	if(!texture)

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed != texture->isCompressed(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(format != GL_NONE && format != texture->getFormat(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed)

-	{

-		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-		   (height % 4 != 0 && height != texture->getHeight(target, 0)))

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-	}

-

-	if(xoffset + width > texture->getWidth(target, level) ||

-	   yoffset + height > texture->getHeight(target, level))

-	{

-		return error(GL_INVALID_VALUE, false);

-	}

-

-	return true;

-}

-

-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)

-{

-	if(!texture)

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed != texture->isCompressed(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(format != GL_NONE && format != texture->getFormat(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed)

-	{

-		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-		   (height % 4 != 0 && height != texture->getHeight(target, 0)) ||

-		   (depth % 4 != 0 && depth != texture->getDepth(target, 0)))

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-	}

-

-	if(xoffset + width > texture->getWidth(target, level) ||

-	   yoffset + height > texture->getHeight(target, level) ||

-	   zoffset + depth > texture->getDepth(target, level))

-	{

-		return error(GL_INVALID_VALUE, false);

-	}

-

-	return true;

-}

-

 static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)

 {

-	GLenum formatError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);

-	if(formatError != GL_NONE)

+	GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);

+	if(validationError != GL_NONE)

 	{

-		return error(formatError, false);

+		return error(validationError, false);

 	}

 

 	// [OpenGL ES 2.0.24] table 3.9

@@ -970,10 +898,10 @@
 		return error(GL_INVALID_OPERATION);

 	default:

 		{

-			GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

-			if(formatError != GL_NONE)

+			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

+			if(validationError != GL_NONE)

 			{

-				return error(formatError);

+				return error(validationError);

 			}

 		}

 		break;

@@ -1082,10 +1010,10 @@
 		return error(GL_INVALID_VALUE);

 	}

 

-	GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

-	if(formatError != GL_NONE)

+	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

+	if(validationError != GL_NONE)

 	{

-		return error(formatError);

+		return error(validationError);

 	}

 

 	if(width == 0 || height == 0 || data == NULL)

@@ -1113,22 +1041,36 @@
 			return error(GL_INVALID_OPERATION);

 		}

 

+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);

+

 		if(target == GL_TEXTURE_2D)

 		{

 			es2::Texture2D *texture = context->getTexture2D();

 

-			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))

+			GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);

+

+			if(validationError == GL_NONE)

 			{

-				texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);

+				texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);

+			}

+			else

+			{

+				return error(validationError);

 			}

 		}

 		else if(es2::IsCubemapTextureTarget(target))

 		{

 			es2::TextureCubeMap *texture = context->getTextureCubeMap();

 

-			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))

+			GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);

+

+			if(validationError == GL_NONE)

 			{

-				texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);

+				texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);

+			}

+			else

+			{

+				return error(validationError);

 			}

 		}

 		else UNREACHABLE(target);

@@ -1293,9 +1235,10 @@
 		}

 		else UNREACHABLE(target);

 

-		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))

+		GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);

+		if(validationError != GL_NONE)

 		{

-			return;

+			return error(validationError);

 		}

 

 		texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);

@@ -5184,10 +5127,10 @@
 			}

 		}

 

-		GLenum formatError = ValidateCompressedFormat(format, clientVersion, false);

-		if(formatError != GL_NONE)

+		GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);

+		if(validationError != GL_NONE)

 		{

-			return error(formatError);

+			return error(validationError);

 		}

 

 		switch(format)

@@ -5904,6 +5847,8 @@
 			return error(GL_INVALID_ENUM);

 		}

 

+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);

+

 		if(target == GL_TEXTURE_2D)

 		{

 			es2::Texture2D *texture = context->getTexture2D();

@@ -5913,7 +5858,7 @@
 				return error(GL_INVALID_OPERATION);

 			}

 

-			texture->setImage(level, width, height, format, type, context->getUnpackInfo(), pixels);

+			texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

 		}

 		else

 		{

@@ -5924,7 +5869,7 @@
 				return error(GL_INVALID_OPERATION);

 			}

 

-			texture->setImage(target, level, width, height, format, type, context->getUnpackInfo(), pixels);

+			texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

 		}

 	}

 }

@@ -6281,22 +6226,36 @@
 			return error(GL_INVALID_VALUE);

 		}

 

+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);

+

 		if(target == GL_TEXTURE_2D)

 		{

 			es2::Texture2D *texture = context->getTexture2D();

 

-			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))

+			GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);

+

+			if(validationError == GL_NONE)

 			{

-				texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), pixels);

+				texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

+			}

+			else

+			{

+				return error(validationError);

 			}

 		}

 		else if(es2::IsCubemapTextureTarget(target))

 		{

 			es2::TextureCubeMap *texture = context->getTextureCubeMap();

 

-			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))

+			GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);

+

+			if(validationError == GL_NONE)

 			{

-				texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), pixels);

+				texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

+			}

+			else

+			{

+				return error(validationError);

 			}

 		}

 		else UNREACHABLE(target);

@@ -7112,7 +7071,7 @@
 			return error(GL_INVALID_OPERATION);

 		}

 

-		texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), pixels);

+		texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);

 	}

 }

 

@@ -7152,9 +7111,16 @@
 	{

 		es2::Texture3D *texture = context->getTexture3D();

 

-		if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))

+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);

+

+		GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);

+		if(validationError == GL_NONE)

 		{

-			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), pixels);

+			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

+		}

+		else

+		{

+			return error(validationError);

 		}

 	}

 }

@@ -7198,9 +7164,11 @@
 

 		es2::Texture3D *texture = context->getTexture3D();

 

-		if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))

+		GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);

+

+		if(validationError != GL_NONE)

 		{

-			return;

+			return error(validationError);

 		}

 

 		texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);

@@ -7242,10 +7210,10 @@
 		return error(GL_INVALID_OPERATION);

 	default:

 		{

-			GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

-			if(formatError != GL_NONE)

+			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

+			if(validationError != GL_NONE)

 			{

-				return error(formatError);

+				return error(validationError);

 			}

 		}

 	}

@@ -7290,10 +7258,10 @@
 		return error(GL_INVALID_VALUE);

 	}

 

-	GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

-	if(formatError != GL_NONE)

+	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

+	if(validationError != GL_NONE)

 	{

-		return error(formatError);

+		return error(validationError);

 	}

 

 	if(width == 0 || height == 0 || depth == 0 || data == NULL)

diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 488f529..b2743df 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -46,49 +46,13 @@
 	return true;

 }

 

-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)

-{

-	if(!texture)

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed != texture->isCompressed(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(format != GL_NONE && format != texture->getFormat(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed)

-	{

-		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-		   (height % 4 != 0 && height != texture->getHeight(target, 0)) ||

-		   (depth % 4 != 0 && depth != texture->getDepth(target, 0)))

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-	}

-

-	if(xoffset + width > texture->getWidth(target, level) ||

-		yoffset + height > texture->getHeight(target, level) ||

-		zoffset + depth > texture->getDepth(target, level))

-	{

-		return error(GL_INVALID_VALUE, false);

-	}

-

-	return true;

-}

 

 static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)

 {

-	GLenum formatError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);

-	if(formatError != GL_NONE)

+	GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);

+	if(validationError != GL_NONE)

 	{

-		return error(formatError, false);

+		return error(validationError, false);

 	}

 

 	switch(textureFormat)

@@ -706,7 +670,7 @@
 			return error(GL_INVALID_OPERATION);

 		}

 

-		texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), pixels);

+		texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);

 	}

 }

 

@@ -747,9 +711,16 @@
 	{

 		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();

 

-		if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))

+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);

+

+		GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);

+		if(validationError == GL_NONE)

 		{

-			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), pixels);

+			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

+		}

+		else

+		{

+			return error(validationError);

 		}

 	}

 }

@@ -800,9 +771,10 @@
 		GLenum colorbufferFormat = source->getFormat();

 		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();

 

-		if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))

+		GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);

+		if(validationError != GL_NONE)

 		{

-			return;

+			return error(validationError);

 		}

 

 		GLenum textureFormat = texture->getFormat(target, level);

@@ -852,10 +824,10 @@
 		return error(GL_INVALID_OPERATION);

 	default:

 		{

-			GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

-			if(formatError != GL_NONE)

+			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

+			if(validationError != GL_NONE)

 			{

-				return error(formatError);

+				return error(validationError);

 			}

 		}

 	}

@@ -901,10 +873,10 @@
 		return error(GL_INVALID_VALUE);

 	}

 

-	GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

-	if(formatError != GL_NONE)

+	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

+	if(validationError != GL_NONE)

 	{

-		return error(formatError);

+		return error(validationError);

 	}

 

 	if(width == 0 || height == 0 || depth == 0 || data == NULL)

@@ -3875,7 +3847,7 @@
 

 			for(int level = 0; level < levels; ++level)

 			{

-				texture->setImage(level, width, height, internalformat, type, context->getUnpackInfo(), NULL);

+				texture->setImage(level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);

 				width = std::max(1, (width / 2));

 				height = std::max(1, (height / 2));

 			}

@@ -3894,7 +3866,7 @@
 			{

 				for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)

 				{

-					texture->setImage(face, level, width, height, internalformat, type, context->getUnpackInfo(), NULL);

+					texture->setImage(face, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);

 				}

 				width = std::max(1, (width / 2));

 				height = std::max(1, (height / 2));

@@ -3945,7 +3917,7 @@
 

 			for(int level = 0; level < levels; ++level)

 			{

-				texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), NULL);

+				texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);

 				width = std::max(1, (width / 2));

 				height = std::max(1, (height / 2));

 				depth = std::max(1, (depth / 2));

@@ -3970,7 +3942,7 @@
 			{

 				for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)

 				{

-					texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), NULL);

+					texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);

 				}

 				width = std::max(1, (width / 2));

 				height = std::max(1, (height / 2));

diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index 4896b27..0b83802 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -23,6 +23,154 @@
 

 namespace es2

 {

+	// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation

+	// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid

+	// format and type combinations.

+

+	typedef std::pair<GLenum, GLenum> FormatTypePair;

+	typedef std::pair<FormatTypePair, GLenum> FormatPair;

+	typedef std::map<FormatTypePair, GLenum> FormatMap;

+

+	// A helper function to insert data into the format map with fewer characters.

+	static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)

+	{

+		map->insert(FormatPair(FormatTypePair(format, type), internalFormat));

+	}

+

+	FormatMap BuildFormatMap()

+	{

+		static const GLenum GL_BGRA4_ANGLEX = 0x6ABC;

+		static const GLenum GL_BGR5_A1_ANGLEX = 0x6ABD;

+

+		FormatMap map;

+

+		//                       | Format | Type | Internal format |

+		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);

+		InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);

+		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);

+		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);

+		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);

+		InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);

+		InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);

+		InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);

+

+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);

+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);

+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);

+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);

+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);

+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);

+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);

+

+		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);

+		InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);

+		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);

+		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);

+		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);

+		InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);

+		InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);

+		InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);

+

+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);

+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);

+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);

+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);

+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);

+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);

+

+		InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);

+		InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);

+		InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);

+		InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);

+		InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);

+

+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);

+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);

+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);

+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);

+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);

+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);

+

+		InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);

+		InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);

+		InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);

+		InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);

+		InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);

+

+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);

+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);

+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);

+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);

+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);

+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);

+

+		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);

+		InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);

+		InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);

+		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);

+		InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);

+		InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);

+		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);

+		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);

+		InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);

+		InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);

+		InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);

+		InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);

+

+		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);

+		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);

+		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);

+

+		InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);

+		InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);

+

+		InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);

+		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);

+		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);

+		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);

+

+		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);

+		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);

+		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);

+

+		InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);

+

+		InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);

+		InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);

+

+		return map;

+	}

+

+	GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)

+	{

+		switch(internalFormat)

+		{

+		case GL_ALPHA:

+		case GL_LUMINANCE:

+		case GL_LUMINANCE_ALPHA:

+		case GL_RED:

+		case GL_RG:

+		case GL_RGB:

+		case GL_RGBA:

+		case GL_RED_INTEGER:

+		case GL_RG_INTEGER:

+		case GL_RGB_INTEGER:

+		case GL_RGBA_INTEGER:

+		case GL_BGRA_EXT:

+		case GL_DEPTH_COMPONENT:

+		case GL_DEPTH_STENCIL:

+		case GL_SRGB_EXT:

+		case GL_SRGB_ALPHA_EXT:

+			{

+				static const FormatMap formatMap = BuildFormatMap();

+				FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));

+				return (iter != formatMap.end()) ? iter->second : GL_NONE;

+			}

+		default:

+			return internalFormat;

+		}

+	}

+

 	unsigned int UniformComponentCount(GLenum type)

 	{

 		switch(type)

@@ -377,6 +525,78 @@
 		}

 	}

 

+	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)

+	{

+		if(!texture)

+		{

+			return GL_INVALID_OPERATION;

+		}

+

+		if(compressed != texture->isCompressed(target, level))

+		{

+			return GL_INVALID_OPERATION;

+		}

+

+		if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))

+		{

+			return GL_INVALID_OPERATION;

+		}

+

+		if(compressed)

+		{

+			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

+			   (height % 4 != 0 && height != texture->getHeight(target, 0)))

+			{

+				return GL_INVALID_OPERATION;

+			}

+		}

+

+		if(xoffset + width > texture->getWidth(target, level) ||

+		   yoffset + height > texture->getHeight(target, level))

+		{

+			return GL_INVALID_VALUE;

+		}

+

+		return GL_NONE;

+	}

+

+	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)

+	{

+		if(!texture)

+		{

+			return GL_INVALID_OPERATION;

+		}

+

+		if(compressed != texture->isCompressed(target, level))

+		{

+			return GL_INVALID_OPERATION;

+		}

+

+		if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level)))

+		{

+			return GL_INVALID_OPERATION;

+		}

+

+		if(compressed)

+		{

+			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

+			   (height % 4 != 0 && height != texture->getHeight(target, 0)) ||

+			   (depth % 4 != 0 && depth != texture->getDepth(target, 0)))

+			{

+				return GL_INVALID_OPERATION;

+			}

+		}

+

+		if(xoffset + width > texture->getWidth(target, level) ||

+		   yoffset + height > texture->getHeight(target, level) ||

+		   zoffset + depth > texture->getDepth(target, level))

+		{

+			return GL_INVALID_VALUE;

+		}

+

+		return GL_NONE;

+	}

+

 	bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion)

 	{

 		switch(format)

@@ -452,7 +672,9 @@
 	bool IsStencilTexture(GLenum format)

 	{

 		return format == GL_STENCIL_INDEX_OES ||

-		       format == GL_DEPTH_STENCIL_OES;

+		       format == GL_DEPTH_STENCIL_OES ||

+		       format == GL_DEPTH24_STENCIL8 ||

+		       format == GL_DEPTH32F_STENCIL8;

 	}

 

 	bool IsCubemapTextureTarget(GLenum target)

diff --git a/src/OpenGL/libGLESv2/utilities.h b/src/OpenGL/libGLESv2/utilities.h
index 7354f95..db4930d 100644
--- a/src/OpenGL/libGLESv2/utilities.h
+++ b/src/OpenGL/libGLESv2/utilities.h
@@ -41,7 +41,10 @@
 	GLint floatToInt(GLfloat value);

 

 	bool IsCompressed(GLenum format, egl::GLint clientVersion);

+	GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);

 	GLenum ValidateCompressedFormat(GLenum format, egl::GLint clientVersion, bool expectCompressedFormats);

+	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);

+	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);

 	bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion);

 	bool IsDepthTexture(GLenum format);

 	bool IsStencilTexture(GLenum format);