Implement sRGB texture sampling.

Previously sRGB data was converted to linear space on upload. This
caused a loss of precision. This change performs the conversion after
texel lookup. Note that we had a code path for performing the
conversion after filtering, but that leads to failures in dEQP and
unacceptable darkening between texels.

Also, glTexSubImage calls can update sRGB textures using a format/type
combination with no indication of the color space, which caused an
unintentional conversion on upload. Likewise we were missing support
for an A2B10G10R10UI implementation format.

Change-Id: Ib10845f628fb2d1849e88d7a9350868cdec32fa2
Reviewed-on: https://swiftshader-review.googlesource.com/15068
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 93a59a6..b834e00 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -5062,7 +5062,7 @@
 
 		GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
 
-		validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
+		validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
 		if(validationError != GL_NONE)
 		{
 			return error(validationError);
@@ -5423,8 +5423,6 @@
 
 	if(context)
 	{
-		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
-
 		if(target == GL_TEXTURE_2D)
 		{
 			es2::Texture2D *texture = context->getTexture2D();
@@ -5435,13 +5433,13 @@
 				return error(validationError);
 			}
 
-			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
+			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
 			if(validationError != GL_NONE)
 			{
 				return error(validationError);
 			}
 
-			texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
+			texture->subImage(context, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), data);
 		}
 		else if(es2::IsCubemapTextureTarget(target))
 		{
@@ -5453,13 +5451,13 @@
 				return error(validationError);
 			}
 
-			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
+			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
 			if(validationError != GL_NONE)
 			{
 				return error(validationError);
 			}
 
-			texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
+			texture->subImage(context, target, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), data);
 		}
 		else UNREACHABLE(target);
 	}
@@ -6342,21 +6340,19 @@
 	{
 		es2::Texture3D *texture = context->getTexture3D();
 
-		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
-
 		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));
+		validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
 		if(validationError != GL_NONE)
 		{
 			return error(validationError);
 		}
 
-		texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
+		texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), data);
 	}
 }