Fix validation for compressed texture functions.

 * No validation that the format matched the texture level's format for
   SubImage calls.
 * WebGL does not allow the base level to be smaller than the block size.
 * ANGLE used to allow mips of size 3 when this is disallowed.
 * Don't early-exit validation when dimensions are 0, imageSize validation
   happens later.

TEST=conformance/extensions/webgl-compressed-texture-s3tc

BUG=angleproject:1998

Change-Id: I05f5a0b5180344d67b036fdecc17edd2256e85ab
Reviewed-on: https://chromium-review.googlesource.com/480442
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 657522c..f3639cd 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -524,11 +524,33 @@
                           "internalformat is not a supported compressed internal format"));
                 return false;
         }
-        if (!ValidCompressedImageSize(context, actualInternalFormat, xoffset, yoffset, width,
-                                      height))
+
+        if (isSubImage)
         {
-            context->handleError(Error(GL_INVALID_OPERATION));
-            return false;
+            if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
+                                             height, texture->getWidth(target, level),
+                                             texture->getHeight(target, level)))
+            {
+                context->handleError(
+                    Error(GL_INVALID_OPERATION, "Invalid compressed format dimension."));
+                return false;
+            }
+
+            if (format != actualInternalFormat)
+            {
+                context->handleError(Error(
+                    GL_INVALID_OPERATION, "Format must match the internal format of the texture."));
+                return false;
+            }
+        }
+        else
+        {
+            if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
+            {
+                context->handleError(
+                    Error(GL_INVALID_OPERATION, "Invalid compressed format dimension."));
+                return false;
+            }
         }
     }
     else
@@ -1970,7 +1992,7 @@
     if (context->getClientMajorVersion() < 3)
     {
         if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
-                                           yoffset, width, height, 0, GL_NONE, GL_NONE, -1, data))
+                                           yoffset, width, height, 0, format, GL_NONE, -1, data))
         {
             return false;
         }
@@ -1979,7 +2001,7 @@
     {
         ASSERT(context->getClientMajorVersion() >= 3);
         if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
-                                             yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, -1,
+                                             yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
                                              data))
         {
             return false;