Validate ANGLE_multiview end-points

The patch adds validation for the ANGLE_multiview end-points
and propagates the calls to the unimplemented stubs in Context.

The patch also removes the
glFramebufferTextureMultiviewSideBySideRobustANGLE end-point
because the size of the viewport offsets buffer can trivially
be computed from the number of views.

BUG=angleproject:2062

Change-Id: I9a10bc00c19825e586d3df2750fabea4daf5ef8f
Reviewed-on: https://chromium-review.googlesource.com/573861
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/tests/gl_tests/FramebufferMultiviewTest.cpp b/src/tests/gl_tests/FramebufferMultiviewTest.cpp
index 9cf9185..4a4ce9a 100644
--- a/src/tests/gl_tests/FramebufferMultiviewTest.cpp
+++ b/src/tests/gl_tests/FramebufferMultiviewTest.cpp
@@ -14,7 +14,7 @@
 class FramebufferMultiviewTest : public ANGLETest
 {
   protected:
-    FramebufferMultiviewTest() : mFramebuffer(0), mTexture(0)
+    FramebufferMultiviewTest() : mFramebuffer(0), mTexture2D(0), mTexture2DArray(0)
     {
         setWindowWidth(128);
         setWindowHeight(128);
@@ -28,21 +28,22 @@
         glGenFramebuffers(1, &mFramebuffer);
         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
 
-        glGenTextures(1, &mTexture);
-        glBindTexture(GL_TEXTURE_2D, mTexture);
-        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA16F, 1, 1);
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
-
         glRequestExtensionANGLE = reinterpret_cast<PFNGLREQUESTEXTENSIONANGLEPROC>(
             eglGetProcAddress("glRequestExtensionANGLE"));
     }
 
     void TearDown() override
     {
-        if (mTexture != 0)
+        if (mTexture2D != 0)
         {
-            glDeleteTextures(1, &mTexture);
-            mTexture = 0;
+            glDeleteTextures(1, &mTexture2D);
+            mTexture2D = 0;
+        }
+
+        if (mTexture2DArray != 0)
+        {
+            glDeleteTextures(1, &mTexture2DArray);
+            mTexture2DArray = 0;
         }
 
         if (mFramebuffer != 0)
@@ -54,8 +55,41 @@
         ANGLETest::TearDown();
     }
 
+    void createTexture2D()
+    {
+        glGenTextures(1, &mTexture2D);
+        glBindTexture(GL_TEXTURE_2D, mTexture2D);
+        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA16F, 1, 1);
+        ASSERT_GL_NO_ERROR();
+    }
+
+    void createTexture2DArray()
+    {
+        glGenTextures(1, &mTexture2DArray);
+        glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture2DArray);
+        glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA16F, 1, 1, 2);
+        ASSERT_GL_NO_ERROR();
+    }
+
+    // Requests the ANGLE_multiview extension and returns true if the operation succeeds.
+    bool requestMultiviewExtension()
+    {
+        if (extensionRequestable("GL_ANGLE_multiview"))
+        {
+            glRequestExtensionANGLE("GL_ANGLE_multiview");
+        }
+
+        if (!extensionEnabled("GL_ANGLE_multiview"))
+        {
+            std::cout << "Test skipped due to missing GL_ANGLE_multiview." << std::endl;
+            return false;
+        }
+        return true;
+    }
+
     GLuint mFramebuffer;
-    GLuint mTexture;
+    GLuint mTexture2D;
+    GLuint mTexture2DArray;
     PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE = nullptr;
 };
 
@@ -63,17 +97,14 @@
 // state and that their corresponding default values are correctly set.
 TEST_P(FramebufferMultiviewTest, DefaultState)
 {
-    if (extensionRequestable("GL_ANGLE_multiview"))
+    if (!requestMultiviewExtension())
     {
-        glRequestExtensionANGLE("GL_ANGLE_multiview");
-    }
-
-    if (!extensionEnabled("GL_ANGLE_multiview"))
-    {
-        std::cout << "Test skipped due to missing GL_ANGLE_multiview." << std::endl;
         return;
     }
 
+    createTexture2D();
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
+
     GLint numViews = -1;
     glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                           GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
@@ -108,6 +139,9 @@
 // the ANGLE_multiview tokens results in an INVALID_ENUM error.
 TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries)
 {
+    createTexture2D();
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
+
     GLint numViews = -1;
     glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                           GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
@@ -133,4 +167,63 @@
     EXPECT_GL_ERROR(GL_INVALID_ENUM);
 }
 
+// Test that the correct errors are generated whenever glFramebufferTextureMultiviewSideBySideANGLE
+// is called with invalid arguments.
+TEST_P(FramebufferMultiviewTest, InvalidMultiviewSideBySideArguments)
+{
+    if (!requestMultiviewExtension())
+    {
+        return;
+    }
+
+    createTexture2D();
+    // Negative offsets.
+    int viewportOffsets[2] = {-1};
+    glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
+                                                 0, 1, &viewportOffsets[0]);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+    // Negative number of views.
+    viewportOffsets[0] = 0;
+    viewportOffsets[1] = 0;
+    glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
+                                                 0, -1, &viewportOffsets[0]);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+}
+
+// Test that the correct errors are generated whenever glFramebufferTextureMultiviewLayeredANGLE is
+// called with invalid arguments.
+TEST_P(FramebufferMultiviewTest, InvalidMultiviewLayeredArguments)
+{
+    if (!requestMultiviewExtension())
+    {
+        return;
+    }
+
+    createTexture2DArray();
+    // Negative base view index.
+    glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2DArray,
+                                              0, -1, 1);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+    // baseViewIndex + numViews is greater than MAX_TEXTURE_LAYERS.
+    GLint maxTextureLayers = 0;
+    glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
+    ASSERT_GL_NO_ERROR();
+    glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2DArray,
+                                              0, maxTextureLayers, 1);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+}
+
+// Test that an INVALID_OPERATION error is generated whenever the ANGLE_multiview extension is not
+// available.
+TEST_P(FramebufferMultiviewTest, ExtensionNotAvailableCheck)
+{
+    createTexture2D();
+    int viewportOffsets[2] = {0};
+    glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
+                                                 0, 1, &viewportOffsets[0]);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
 ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest, ES3_OPENGL());
\ No newline at end of file