Edit

kc3-lang/angle/src/tests/gl_tests/CopyCompressedTextureTest.cpp

Branch :

  • Show log

    Commit

  • Author : Geoff Lang
    Date : 2016-04-20 11:13:22
    Hash : 47110bf4
    Message : Implement CHROMIUM_copy_compressed_texture for D3D11. BUG=angleproject:1356 Change-Id: Id563997d2921cf558c52a781ae66d8bde58d1f2f Reviewed-on: https://chromium-review.googlesource.com/339847 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>

  • src/tests/gl_tests/CopyCompressedTextureTest.cpp
  • //
    // Copyright 2016 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // CopyCompressedTextureTest.cpp: Tests of the GL_CHROMIUM_copy_compressed_texture extension
    
    #include "test_utils/ANGLETest.h"
    
    namespace angle
    {
    
    class CopyCompressedTextureTest : public ANGLETest
    {
      protected:
        CopyCompressedTextureTest()
        {
            setWindowWidth(256);
            setWindowHeight(256);
            setConfigRedBits(8);
            setConfigGreenBits(8);
            setConfigBlueBits(8);
            setConfigAlphaBits(8);
        }
    
        void SetUp() override
        {
            ANGLETest::SetUp();
    
            glGenTextures(2, mTextures);
    
            mProgram = CompileProgram(
                "attribute vec2 a_position;\n"
                "varying vec2 v_texcoord;\n"
                "void main()\n"
                "{\n"
                "   gl_Position = vec4(a_position, 0.0, 1.0);\n"
                "   v_texcoord = (a_position + 1.0) * 0.5;\n"
                "}\n",
                "precision mediump float;\n"
                "uniform sampler2D u_texture;\n"
                "varying vec2 v_texcoord;\n"
                "void main()\n"
                "{\n"
                "    gl_FragColor = texture2D(u_texture, v_texcoord);\n"
                "}\n");
            ASSERT_NE(0u, mProgram);
    
            if (extensionEnabled("GL_CHROMIUM_copy_compressed_texture"))
            {
                glCompressedCopyTextureCHROMIUM =
                    reinterpret_cast<PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC>(
                        eglGetProcAddress("glCompressedCopyTextureCHROMIUM"));
            }
        }
    
        void TearDown() override
        {
            glDeleteTextures(2, mTextures);
            glDeleteProgram(mProgram);
    
            ANGLETest::TearDown();
        }
    
        bool checkExtensions() const
        {
            if (!extensionEnabled("GL_CHROMIUM_copy_compressed_texture"))
            {
                std::cout
                    << "Test skipped because GL_CHROMIUM_copy_compressed_texture is not available."
                    << std::endl;
                return false;
            }
    
            EXPECT_NE(nullptr, glCompressedCopyTextureCHROMIUM);
            if (glCompressedCopyTextureCHROMIUM == nullptr)
            {
                return false;
            }
    
            return true;
        }
    
        GLuint mProgram     = 0;
        GLuint mTextures[2] = {0, 0};
    
        PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC glCompressedCopyTextureCHROMIUM = nullptr;
    };
    
    namespace
    {
    
    const GLColor &CompressedImageColor = GLColor::red;
    
    // Single compressed ATC block of source pixels all set to:
    // CompressedImageColor.
    const uint8_t CompressedImageATC[8] = {0x0, 0x7c, 0x0, 0xf8, 0x55, 0x55, 0x55, 0x55};
    
    // Single compressed ATCIA block of source pixels all set to:
    // CompressedImageColor.
    const uint8_t CompressedImageATCIA[16] = {0xff, 0xff, 0x0, 0x0,  0x0,  0x0,  0x0,  0x0,
                                              0x0,  0x7c, 0x0, 0xf8, 0x55, 0x55, 0x55, 0x55};
    
    // Single compressed DXT1 block of source pixels all set to:
    // CompressedImageColor.
    const uint8_t CompressedImageDXT1[8] = {0x00, 0xf8, 0x00, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa};
    
    // Single compressed DXT5 block of source pixels all set to:
    // CompressedImageColor.
    const uint8_t CompressedImageDXT5[16] = {0xff, 0xff, 0x0, 0x0,  0x0,  0x0,  0x0,  0x0,
                                             0x0,  0xf8, 0x0, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa};
    
    // Single compressed DXT1 block of source pixels all set to:
    // CompressedImageColor.
    const uint8_t CompressedImageETC1[8] = {0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0};
    
    }  // anonymous namespace
    
    // Test to ensure that the basic functionality of the extension works.
    TEST_P(CopyCompressedTextureTest, Basic)
    {
        if (!checkExtensions())
        {
            return;
        }
    
        if (!extensionEnabled("GL_EXT_texture_compression_dxt1"))
        {
            std::cout << "Test skipped because GL_EXT_texture_compression_dxt1 is not available."
                      << std::endl;
            return;
        }
    
        glBindTexture(GL_TEXTURE_2D, mTextures[0]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
                               sizeof(CompressedImageDXT1), CompressedImageDXT1);
        ASSERT_GL_NO_ERROR();
    
        glBindTexture(GL_TEXTURE_2D, mTextures[1]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
        ASSERT_GL_NO_ERROR();
    
        // Load texture.
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, mTextures[1]);
        GLint textureLoc = glGetUniformLocation(mProgram, "u_texture");
        glUseProgram(mProgram);
        glUniform1i(textureLoc, 0);
    
        // Draw.
        drawQuad(mProgram, "a_position", 0.5f);
    
        EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, CompressedImageColor);
        ASSERT_GL_NO_ERROR();
    }
    
    // Test validation of compressed formats
    TEST_P(CopyCompressedTextureTest, InternalFormat)
    {
        if (!checkExtensions())
        {
            return;
        }
    
        struct Data
        {
            GLint format;
            const uint8_t *data;
            GLsizei dataSize;
    
            Data() : Data(GL_NONE, nullptr, 0) {}
            Data(GLint format, const uint8_t *data, GLsizei dataSize)
                : format(format), data(data), dataSize(dataSize)
            {
            }
        };
        std::vector<Data> supportedFormats;
    
        if (extensionEnabled("GL_AMD_compressed_ATC_texture"))
        {
            supportedFormats.push_back(
                Data(GL_ATC_RGB_AMD, CompressedImageATC, sizeof(CompressedImageATC)));
            supportedFormats.push_back(Data(GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD, CompressedImageATCIA,
                                            sizeof(CompressedImageATCIA)));
        }
        if (extensionEnabled("GL_EXT_texture_compression_dxt1"))
        {
            supportedFormats.push_back(Data(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, CompressedImageDXT1,
                                            sizeof(CompressedImageDXT1)));
        }
        if (extensionEnabled("GL_ANGLE_texture_compression_dxt5"))
        {
            supportedFormats.push_back(Data(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, CompressedImageDXT5,
                                            sizeof(CompressedImageDXT5)));
        }
        if (extensionEnabled("GL_OES_compressed_ETC1_RGB8_texture"))
        {
            supportedFormats.push_back(
                Data(GL_ETC1_RGB8_OES, CompressedImageETC1, sizeof(CompressedImageETC1)));
        }
    
        for (const auto &supportedFormat : supportedFormats)
        {
            glBindTexture(GL_TEXTURE_2D, mTextures[0]);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glCompressedTexImage2D(GL_TEXTURE_2D, 0, supportedFormat.format, 4, 4, 0,
                                   supportedFormat.dataSize, supportedFormat.data);
            ASSERT_GL_NO_ERROR();
    
            glBindTexture(GL_TEXTURE_2D, mTextures[1]);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
            ASSERT_GL_NO_ERROR();
        }
    }
    
    // Test that uncompressed textures generate errors when copying
    TEST_P(CopyCompressedTextureTest, InternalFormatNotSupported)
    {
        if (!checkExtensions())
        {
            return;
        }
    
        glBindTexture(GL_TEXTURE_2D, mTextures[0]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
        ASSERT_GL_NO_ERROR();
    
        glBindTexture(GL_TEXTURE_2D, mTextures[1]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();
    
        // Check that the GL_RGBA format reports an error.
        glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    }
    
    // Test validation of texture IDs
    TEST_P(CopyCompressedTextureTest, InvalidTextureIds)
    {
        if (!checkExtensions())
        {
            return;
        }
    
        glBindTexture(GL_TEXTURE_2D, mTextures[0]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
                               sizeof(CompressedImageDXT1), CompressedImageDXT1);
        ASSERT_GL_NO_ERROR();
    
        glBindTexture(GL_TEXTURE_2D, mTextures[1]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();
    
        glCompressedCopyTextureCHROMIUM(mTextures[0], 99993);
        EXPECT_GL_ERROR(GL_INVALID_VALUE);
    
        glCompressedCopyTextureCHROMIUM(99994, mTextures[1]);
        EXPECT_GL_ERROR(GL_INVALID_VALUE);
    
        glCompressedCopyTextureCHROMIUM(99995, 99996);
        EXPECT_GL_ERROR(GL_INVALID_VALUE);
    
        glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
        EXPECT_GL_NO_ERROR();
    }
    
    // Test that only 2D textures are valid
    TEST_P(CopyCompressedTextureTest, BindingPoints)
    {
        if (!checkExtensions())
        {
            return;
        }
    
        glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[0]);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
             face++)
        {
            glCompressedTexImage2D(face, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
                                   sizeof(CompressedImageDXT1), CompressedImageDXT1);
        }
        ASSERT_GL_NO_ERROR();
    
        glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[1]);
        glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();
    
        glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
        EXPECT_GL_ERROR(GL_INVALID_VALUE);
    }
    
    // Test the destination texture cannot be immutable
    TEST_P(CopyCompressedTextureTest, Immutable)
    {
        if (!checkExtensions() || getClientMajorVersion() < 3)
        {
            return;
        }
    
        glBindTexture(GL_TEXTURE_2D, mTextures[0]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
                               sizeof(CompressedImageDXT1), CompressedImageDXT1);
        ASSERT_GL_NO_ERROR();
    
        glBindTexture(GL_TEXTURE_2D, mTextures[1]);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();
    
        glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    }
    
    // Use this to select which configurations (e.g. which renderer, which GLES major version) these
    // tests should be run against.
    ANGLE_INSTANTIATE_TEST(CopyCompressedTextureTest,
                           ES2_D3D9(),
                           ES2_D3D11(),
                           ES3_D3D11(),
                           ES2_OPENGL(),
                           ES3_OPENGL(),
                           ES2_OPENGLES(),
                           ES3_OPENGLES());
    
    }  // namespace angle