Support multisample arrays as framebuffer attachments

This contains tests for framebuffer completeness when layers of
multisample array textures are attached.

Simple clearing of a layer of a multisample color texture array and
blitting the result to a non-multisampled texture is also covered.

BUG=angleproject:2775
TEST=angle_end2end_tests

Change-Id: Idf383cab69587dbd8157ab9a2b7c47e5a90b3cf7
Reviewed-on: https://chromium-review.googlesource.com/1190184
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index cc80c13..0a9fa00 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -1151,13 +1151,14 @@
             {
                 if (level > gl::log2(caps.max2DTextureSize))
                 {
-                    context->handleError(InvalidValue());
+                    ANGLE_VALIDATION_ERR(context, InvalidValue(),
+                                         FramebufferTextureInvalidMipLevel);
                     return false;
                 }
 
                 if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
                 {
-                    context->handleError(InvalidValue());
+                    ANGLE_VALIDATION_ERR(context, InvalidValue(), FramebufferTextureInvalidLayer);
                     return false;
                 }
             }
@@ -1167,20 +1168,39 @@
             {
                 if (level > gl::log2(caps.max3DTextureSize))
                 {
-                    context->handleError(InvalidValue());
+                    ANGLE_VALIDATION_ERR(context, InvalidValue(),
+                                         FramebufferTextureInvalidMipLevel);
                     return false;
                 }
 
                 if (static_cast<GLuint>(layer) >= caps.max3DTextureSize)
                 {
-                    context->handleError(InvalidValue());
+                    ANGLE_VALIDATION_ERR(context, InvalidValue(), FramebufferTextureInvalidLayer);
+                    return false;
+                }
+            }
+            break;
+
+            case TextureType::_2DMultisampleArray:
+            {
+                if (level != 0)
+                {
+                    ANGLE_VALIDATION_ERR(context, InvalidValue(),
+                                         FramebufferTextureInvalidMipLevel);
+                    return false;
+                }
+
+                if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
+                {
+                    ANGLE_VALIDATION_ERR(context, InvalidValue(), FramebufferTextureInvalidLayer);
                     return false;
                 }
             }
             break;
 
             default:
-                context->handleError(InvalidOperation());
+                ANGLE_VALIDATION_ERR(context, InvalidOperation(),
+                                     FramebufferTextureLayerIncorrectTextureType);
                 return false;
         }