Added ES3 validation for glReadPixels and glReadnPixelsEXT.

TRAC #22956

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang

git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2355 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index a615c16..ed30736 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -1205,7 +1205,7 @@
 }
 
 // check for combinations of format and type that are valid for ReadPixels
-bool validReadFormatType(GLenum format, GLenum type)
+bool validES2ReadFormatType(GLenum format, GLenum type)
 {
     switch (format)
     {
@@ -1235,6 +1235,52 @@
     return true;
 }
 
+bool validES3ReadFormatType(GLenum internalFormat, GLenum format, GLenum type)
+{
+    switch (format)
+    {
+      case GL_RGBA:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:
+            break;
+          case GL_UNSIGNED_INT_2_10_10_10_REV:
+            if (internalFormat != GL_RGB10_A2)
+            {
+                return false;
+            }
+            break;
+          default:
+            return false;
+        }
+        break;
+      case GL_RGBA_INTEGER:
+        switch (type)
+        {
+          case GL_INT:
+          case GL_UNSIGNED_INT:
+            break;
+          default:
+            return false;
+        }
+        break;
+      case GL_BGRA_EXT:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:
+          case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+          case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+            break;
+          default:
+            return false;
+        }
+        break;
+      default:
+        return false;
+    }
+    return true;
+}
+
 bool validateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments,
                                              const GLenum* attachments)
 {
@@ -5725,15 +5771,19 @@
 
         if (context)
         {
+            GLint currentInternalFormat;
             GLenum currentFormat, currentType;
-    
+
             // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
             // and attempting to read back if that's the case is an error. The error will be registered
             // by getCurrentReadFormat.
-            if (!context->getCurrentReadFormatType(&currentFormat, &currentType))
+            if (!context->getCurrentReadFormatType(&currentInternalFormat, &currentFormat, &currentType))
                 return;
 
-            if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
+            bool validReadFormat = (context->getClientVersion() < 3) ? validES2ReadFormatType(format, type) :
+                                                                       validES3ReadFormatType(currentInternalFormat, format, type);
+
+            if (!(currentFormat == format && currentType == type) && !validReadFormat)
             {
                 return gl::error(GL_INVALID_OPERATION);
             }
@@ -5765,15 +5815,19 @@
 
         if (context)
         {
+            GLint currentInternalFormat;
             GLenum currentFormat, currentType;
-    
+
             // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
             // and attempting to read back if that's the case is an error. The error will be registered
             // by getCurrentReadFormat.
-            if (!context->getCurrentReadFormatType(&currentFormat, &currentType))
+            if (!context->getCurrentReadFormatType(&currentInternalFormat, &currentFormat, &currentType))
                 return;
 
-            if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
+            bool validReadFormat = (context->getClientVersion() < 3) ? validES2ReadFormatType(format, type) :
+                                                                       validES3ReadFormatType(currentInternalFormat, format, type);
+
+            if (!(currentFormat == format && currentType == type) && !validReadFormat)
             {
                 return gl::error(GL_INVALID_OPERATION);
             }