Save layered multiview end-point's arguments into attachment's state

Handle glFramebufferTextureMultiviewLayeredANGLE calls by saving the
arguments into the attachment's state.

BUG=angleproject:2062
TEST=angle_end2end_tests

Change-Id: I9d7c0e00fe9e917ad2f9d903a39f30b2546dc7a3
Reviewed-on: https://chromium-review.googlesource.com/609960
Commit-Queue: Martin Radev <mradev@nvidia.com>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/gl_tests/FramebufferMultiviewTest.cpp b/src/tests/gl_tests/FramebufferMultiviewTest.cpp
index 0238d98..d392d54 100644
--- a/src/tests/gl_tests/FramebufferMultiviewTest.cpp
+++ b/src/tests/gl_tests/FramebufferMultiviewTest.cpp
@@ -281,7 +281,7 @@
     const GLint kOtherViewportOffsets[4] = {2, 0, 4, 0};
 
     // Set the 0th attachment and keep it as it is till the end of the test. The 1st or depth
-    // attachment will me modified to change the framebuffer's status.
+    // attachment will be modified to change the framebuffer's status.
     glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2,
                                                  &kViewportOffsets[0]);
     ASSERT_GL_NO_ERROR();
@@ -526,4 +526,109 @@
     EXPECT_PIXEL_EQ(3, 1, 255, 0, 0, 0);
 }
 
+// Test that glFramebufferTextureMultiviewLayeredANGLE modifies the internal multiview state.
+TEST_P(FramebufferMultiviewTest, ModifyLayeredState)
+{
+    if (!requestMultiviewExtension())
+    {
+        return;
+    }
+
+    GLFramebuffer multiviewFBO;
+    glBindFramebuffer(GL_FRAMEBUFFER, multiviewFBO);
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    ASSERT_GL_NO_ERROR();
+
+    glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1, 2);
+    ASSERT_GL_NO_ERROR();
+
+    GLint numViews = -1;
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                          GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
+                                          &numViews);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(2, numViews);
+
+    GLint baseViewIndex = -1;
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                          GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
+                                          &baseViewIndex);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(1, baseViewIndex);
+
+    GLint multiviewLayout = GL_NONE;
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                          GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
+                                          &multiviewLayout);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE, multiviewLayout);
+
+    GLint internalViewportOffsets[2] = {-1};
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                          GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
+                                          &internalViewportOffsets[0]);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(0, internalViewportOffsets[0]);
+    EXPECT_EQ(0, internalViewportOffsets[1]);
+}
+
+// Test framebuffer completeness status of a layered framebuffer with color attachments.
+TEST_P(FramebufferMultiviewTest, IncompleteViewTargetsLayered)
+{
+    if (!requestMultiviewExtension())
+    {
+        return;
+    }
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    // Set the 0th attachment and keep it as it is till the end of the test. The 1st color
+    // attachment will be modified to change the framebuffer's status.
+    glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 2);
+    ASSERT_GL_NO_ERROR();
+
+    GLTexture otherTexLayered;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, otherTexLayered);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    // Test framebuffer completeness when the base view index differs.
+    glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered,
+                                              0, 1, 2);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
+                     glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Test framebuffer completeness when the 1st attachment has a side-by-side layout.
+    const int kViewportOffsets[4] = {0, 0, 0, 0};
+    GLTexture otherTex2D;
+    glBindTexture(GL_TEXTURE_2D, otherTex2D);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTex2D,
+                                                 0, 2, kViewportOffsets);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
+                     glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Test framebuffer completeness when the 1st attachment has a normal layout.
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered, 0, 0);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE,
+                     glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Test that framebuffer is complete when the number of views, base view index and layouts are
+    // the same.
+    glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, otherTexLayered,
+                                              0, 0, 2);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+}
+
 ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest, ES3_OPENGL());
\ No newline at end of file