Add support for new internalformats in copyTextureCHROMIUM

This adds support in blit11::copyTexture for LUMA, LUMA_ALPHA, and ALPHA
formats as destinations. Added is handling for each case to match up
the corresponding shader. This required new premultiply and
unmultiply D3D11 shaders for some cases.

Changed copyTextureCHROMIUM validation to allow new formats.

Tests have been created to demonstrate using copyTextureCHROMIUM with
the new formats with default parameters, as well as with the
unpackPremultiply and unpackUnmultiply parameters.

BUG=:angleproject:2101

Change-Id: Id8cd303a46fe70710bc18172fc938552a6e4cfaf
diff --git a/src/tests/gl_tests/CopyTextureTest.cpp b/src/tests/gl_tests/CopyTextureTest.cpp
index 6762a46..b2d2e49 100644
--- a/src/tests/gl_tests/CopyTextureTest.cpp
+++ b/src/tests/gl_tests/CopyTextureTest.cpp
@@ -83,6 +83,10 @@
     PFNGLCOPYSUBTEXTURECHROMIUMPROC glCopySubTextureCHROMIUM = nullptr;
 };
 
+class CopyTextureTestDest : public CopyTextureTest
+{
+};
+
 class CopyTextureTestES3 : public CopyTextureTest
 {
 };
@@ -717,6 +721,290 @@
     }
 }
 
+// Test to ensure that CopyTexture works with LUMINANCE texture as a destination
+TEST_P(CopyTextureTestDest, Luminance)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 200u);
+    GLColor expectedPixels(50u, 50u, 50u, 255u);
+
+    // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
+    // texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
+// Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
+// UnpackPremultiply parameter
+TEST_P(CopyTextureTestDest, LuminanceMultiply)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 200u);
+    GLColor expectedPixels(39u, 39u, 39u, 255u);
+
+    // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
+    // texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
+                          GL_UNSIGNED_BYTE, false, true, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
+// Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
+// UnpackUnmultiply parameter
+TEST_P(CopyTextureTestDest, LuminanceUnmultiply)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 200u);
+    GLColor expectedPixels(64u, 64u, 64u, 255u);
+
+    // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
+    // texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
+                          GL_UNSIGNED_BYTE, false, false, true);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
+// Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination
+TEST_P(CopyTextureTestDest, LuminanceAlpha)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 200u);
+    GLColor expectedPixels(50u, 50u, 50u, 200u);
+
+    // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
+    // RGBA texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
+                 GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
+// Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
+// UnpackPremultiply parameter
+TEST_P(CopyTextureTestDest, LuminanceAlphaMultiply)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 200u);
+    GLColor expectedPixels(39u, 39u, 39u, 200u);
+
+    // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
+    // RGBA texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
+                 GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
+                          GL_UNSIGNED_BYTE, false, true, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
+// Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
+// UnpackUnmultiplyAlpha parameter
+TEST_P(CopyTextureTestDest, LuminanceAlphaUnmultiply)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 200u);
+    GLColor expectedPixels(64u, 64u, 64u, 200u);
+
+    // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
+    // RGBA texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
+                 GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
+                          GL_UNSIGNED_BYTE, false, false, true);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
+// Test to ensure that CopyTexture works with ALPHA texture as a destination
+TEST_P(CopyTextureTestDest, Alpha)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 155u);
+    GLColor expectedPixels(0u, 0u, 0u, 155u);
+
+    // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
+    // texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
+// Test to ensure that CopyTexture works with ALPHA texture as a destination with
+// UnpackPremultiplyAlpha parameter
+TEST_P(CopyTextureTestDest, AlphaMultiply)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 155u);
+    GLColor expectedPixels(0u, 0u, 0u, 155u);
+
+    // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
+    // texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
+                          GL_UNSIGNED_BYTE, false, true, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
+// Test to ensure that CopyTexture works with ALPHA texture as a destination with
+// UnpackUnmultiplyAlpha parameter
+TEST_P(CopyTextureTestDest, AlphaUnmultiply)
+{
+    if (!checkExtensions())
+    {
+        return;
+    }
+
+    GLColor originalPixels(50u, 100u, 150u, 155u);
+    GLColor expectedPixels(0u, 0u, 0u, 155u);
+
+    // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
+    // texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
+                          GL_UNSIGNED_BYTE, false, false, true);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
 // Test the newly added ES3 unorm formats
 TEST_P(CopyTextureTestES3, ES3UnormFormats)
 {
@@ -1087,6 +1375,7 @@
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
 // tests should be run against.
 ANGLE_INSTANTIATE_TEST(CopyTextureTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
+ANGLE_INSTANTIATE_TEST(CopyTextureTestDest, ES2_D3D11());
 ANGLE_INSTANTIATE_TEST(CopyTextureTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
 
 }  // namespace angle