Edit

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

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2017-09-18 13:32:29
    Hash : a20af6d7
    Message : Use C++11 raw string literals instead of SHADER_SOURCE macro This is better in many ways: 1. It doesn't confuse clang format 2. \n doesn't need to be included after preprocessor directives like the version directive. 3. It's using built-in functionality instead of something custom. Raw string literals should be the preferred way to include shader source in C++ files going forward. BUG=angleproject:2157 TEST=angle_end2end_tests Change-Id: I8b236a6e2d5c25d920297e5bc5b5b143eddeba1f Reviewed-on: https://chromium-review.googlesource.com/671046 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>

  • src/tests/gl_tests/SwizzleTest.cpp
  • //
    // Copyright 2015 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.
    //
    
    #include "test_utils/ANGLETest.h"
    
    #include <vector>
    
    using namespace angle;
    
    namespace
    {
    
    class SwizzleTest : public ANGLETest
    {
      protected:
        SwizzleTest()
        {
            setWindowWidth(128);
            setWindowHeight(128);
            setConfigRedBits(8);
            setConfigGreenBits(8);
            setConfigBlueBits(8);
            setConfigAlphaBits(8);
    
            constexpr GLenum swizzles[] = {
                GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE,
            };
    
            // Only use every 13th swizzle permutation, use a prime number to make sure the permuations
            // are somewhat evenly distributed.  Reduces the permuations from 1296 to 100.
            constexpr size_t swizzleReductionFactor = 13;
    
            size_t swizzleCount = 0;
            for (GLenum r : swizzles)
            {
                for (GLenum g : swizzles)
                {
                    for (GLenum b : swizzles)
                    {
                        for (GLenum a : swizzles)
                        {
                            swizzleCount++;
                            if (swizzleCount % swizzleReductionFactor != 0)
                            {
                                continue;
                            }
    
                            swizzlePermutation permutation;
                            permutation.swizzleRed   = r;
                            permutation.swizzleGreen = g;
                            permutation.swizzleBlue  = b;
                            permutation.swizzleAlpha = a;
                            mPermutations.push_back(permutation);
                        }
                    }
                }
            }
        }
    
        void SetUp() override
        {
            ANGLETest::SetUp();
    
            const std::string vertexShaderSource =
                R"(precision highp float;
                attribute vec4 position;
                varying vec2 texcoord;
    
                void main()
                {
                    gl_Position = position;
                    texcoord = (position.xy * 0.5) + 0.5;
                })";
    
            const std::string fragmentShaderSource =
                R"(precision highp float;
                uniform sampler2D tex;
                varying vec2 texcoord;
    
                void main()
                {
                    gl_FragColor = texture2D(tex, texcoord);
                })";
    
            mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
            ASSERT_NE(0u, mProgram);
    
            mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
            ASSERT_NE(-1, mTextureUniformLocation);
    
            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            ASSERT_GL_NO_ERROR();
        }
    
        void TearDown() override
        {
            glDeleteProgram(mProgram);
            glDeleteTextures(1, &mTexture);
    
            ANGLETest::TearDown();
        }
    
        template <typename T>
        void init2DTexture(GLenum internalFormat, GLenum dataFormat, GLenum dataType, const T* data)
        {
            glGenTextures(1, &mTexture);
            glBindTexture(GL_TEXTURE_2D, mTexture);
            glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, dataFormat, dataType, data);
    
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        }
    
        void init2DCompressedTexture(GLenum internalFormat, GLsizei width, GLsizei height, GLsizei dataSize, const GLubyte* data)
        {
            glGenTextures(1, &mTexture);
            glBindTexture(GL_TEXTURE_2D, mTexture);
            glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, dataSize, data);
    
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        }
    
        GLubyte getExpectedValue(GLenum swizzle, GLubyte unswizzled[4])
        {
            switch (swizzle)
            {
              case GL_RED:   return unswizzled[0];
              case GL_GREEN: return unswizzled[1];
              case GL_BLUE:  return unswizzled[2];
              case GL_ALPHA: return unswizzled[3];
              case GL_ZERO:  return 0;
              case GL_ONE:   return 255;
              default:       return 0;
            }
        }
    
        void runTest2D()
        {
            // TODO(jmadill): Figure out why this fails on Intel.
            if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
            {
                std::cout << "Test skipped on Intel." << std::endl;
                return;
            }
    
            glUseProgram(mProgram);
            glBindTexture(GL_TEXTURE_2D, mTexture);
            glUniform1i(mTextureUniformLocation, 0);
    
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
    
            glClear(GL_COLOR_BUFFER_BIT);
            drawQuad(mProgram, "position", 0.5f);
    
            GLubyte unswizzled[4];
            glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &unswizzled);
    
            ASSERT_GL_NO_ERROR();
    
            for (const auto &permutation : mPermutations)
            {
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, permutation.swizzleRed);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, permutation.swizzleGreen);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, permutation.swizzleBlue);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, permutation.swizzleAlpha);
    
                glClear(GL_COLOR_BUFFER_BIT);
                drawQuad(mProgram, "position", 0.5f);
    
                EXPECT_PIXEL_EQ(0, 0,
                                getExpectedValue(permutation.swizzleRed, unswizzled),
                                getExpectedValue(permutation.swizzleGreen, unswizzled),
                                getExpectedValue(permutation.swizzleBlue, unswizzled),
                                getExpectedValue(permutation.swizzleAlpha, unswizzled));
    
                ASSERT_GL_NO_ERROR();
            }
        }
    
        GLuint mProgram;
        GLint mTextureUniformLocation;
    
        GLuint mTexture;
    
        struct swizzlePermutation
        {
            GLenum swizzleRed;
            GLenum swizzleGreen;
            GLenum swizzleBlue;
            GLenum swizzleAlpha;
        };
        std::vector<swizzlePermutation> mPermutations;
    };
    
    class SwizzleIntegerTest : public SwizzleTest
    {
      protected:
        void SetUp() override
        {
            ANGLETest::SetUp();
    
            const std::string vertexShaderSource =
                "#version 300 es\n"
                "precision highp float;\n"
                "in vec4 position;\n"
                "out vec2 texcoord;\n"
                "\n"
                "void main()\n"
                "{\n"
                "    gl_Position = position;\n"
                "    texcoord = (position.xy * 0.5) + 0.5;\n"
                "}\n";
    
            const std::string fragmentShaderSource =
                "#version 300 es\n"
                "precision highp float;\n"
                "precision highp usampler2D;\n"
                "uniform usampler2D tex;\n"
                "in vec2 texcoord;\n"
                "out vec4 my_FragColor;\n"
                "\n"
                "void main()\n"
                "{\n"
                "    uvec4 s = texture(tex, texcoord);\n"
                "    if (s[0] == 1u) s[0] = 255u;\n"
                "    if (s[1] == 1u) s[1] = 255u;\n"
                "    if (s[2] == 1u) s[2] = 255u;\n"
                "    if (s[3] == 1u) s[3] = 255u;\n"
                "    my_FragColor = vec4(s) / 255.0;\n"
                "}\n";
    
            mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
            ASSERT_NE(0u, mProgram);
    
            mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
            ASSERT_NE(-1, mTextureUniformLocation);
    
            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            ASSERT_GL_NO_ERROR();
        }
    };
    
    TEST_P(SwizzleTest, RGBA8_2D)
    {
        GLubyte data[] = { 1, 64, 128, 200 };
        init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, RGB8_2D)
    {
        GLubyte data[] = { 77, 66, 55 };
        init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, RG8_2D)
    {
        GLubyte data[] = { 11, 99 };
        init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, R8_2D)
    {
        GLubyte data[] = { 2 };
        init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, RGB10_A2_2D)
    {
        GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)};
        init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, RGBA32F_2D)
    {
        GLfloat data[] = { 0.25f, 0.5f, 0.75f, 0.8f };
        init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, RGB32F_2D)
    {
        GLfloat data[] = { 0.1f, 0.2f, 0.3f };
        init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, RG32F_2D)
    {
        GLfloat data[] = { 0.9f, 0.1f  };
        init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, R32F_2D)
    {
        GLfloat data[] = { 0.5f };
        init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, D32F_2D)
    {
        GLfloat data[] = { 0.5f };
        init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, D16_2D)
    {
        GLushort data[] = { 0xFF };
        init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, D24_2D)
    {
        GLuint data[] = { 0xFFFF };
        init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, L8_2D)
    {
        GLubyte data[] = {0x77};
        init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, A8_2D)
    {
        GLubyte data[] = {0x55};
        init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, LA8_2D)
    {
        GLubyte data[] = {0x77, 0x66};
        init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, L32F_2D)
    {
        if (!extensionEnabled("GL_OES_texture_float"))
        {
            std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
            return;
        }
    
        GLfloat data[] = {0.7f};
        init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, A32F_2D)
    {
        if (!extensionEnabled("GL_OES_texture_float"))
        {
            std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
            return;
        }
    
        GLfloat data[] = {
            0.4f,
        };
        init2DTexture(GL_ALPHA, GL_ALPHA, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, LA32F_2D)
    {
        if (!extensionEnabled("GL_OES_texture_float"))
        {
            std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
            return;
        }
    
        GLfloat data[] = {
            0.5f, 0.6f,
        };
        init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT, data);
        runTest2D();
    }
    
    #include "media/pixel.inl"
    
    TEST_P(SwizzleTest, CompressedDXT_2D)
    {
        if (!extensionEnabled("GL_EXT_texture_compression_dxt1"))
        {
            std::cout << "Test skipped due to missing GL_EXT_texture_compression_dxt1." << std::endl;
            return;
        }
    
        init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, pixel_0_size, pixel_0_data);
        runTest2D();
    }
    
    TEST_P(SwizzleIntegerTest, RGB8UI_2D)
    {
        GLubyte data[] = {77, 66, 55};
        init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
        runTest2D();
    }
    
    // Test that updating the texture data still generates the correct swizzles
    TEST_P(SwizzleTest, SubUpdate)
    {
        GLColor data(1, 64, 128, 200);
        init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data);
    
        glUseProgram(mProgram);
        glBindTexture(GL_TEXTURE_2D, mTexture);
        glUniform1i(mTextureUniformLocation, 0);
    
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
    
        glClear(GL_COLOR_BUFFER_BIT);
        drawQuad(mProgram, "position", 0.5f);
    
        GLColor expectedData(data.R, data.R, data.R, data.R);
        EXPECT_PIXEL_COLOR_EQ(0, 0, expectedData);
    
        GLColor updateData(32, 234, 28, 232);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &updateData);
    
        glClear(GL_COLOR_BUFFER_BIT);
        drawQuad(mProgram, "position", 0.5f);
    
        GLColor expectedUpdateData(updateData.R, updateData.R, updateData.R, updateData.R);
        EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
    }
    
    // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
    ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGL(3, 3), ES3_OPENGLES());
    ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest,
                           ES3_D3D11(),
                           ES3_OPENGL(),
                           ES3_OPENGL(3, 3),
                           ES3_OPENGLES());
    
    } // namespace