Edit

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

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2016-02-26 14:37:57
    Hash : 7b591905
    Message : D3D11: Use blit SRV format for blits blitSRVFormat stores the format that is used with ANGLE's internal blit shaders. By default, it is the same as the normal SRV format. For integer textures with a red channel, the RTV format is used instead. This makes it possible to change the storage format and the SRV format for the integer textures without affecting the blit format. The blitSRVFormat is used when doing blits in Blit11::copyTexture(). An exception is made for depth/stencil renderbuffer blit - in these cases it is okay to assume that the regular SRV format works for blitting. In the future the regular SRV format for integer textures will be changed to be different from their blit SRV format. TEST=angle_end2end_tests dEQP-GLES3.functional.fbo.blit.* (no regression) dEQP-GLES3.functional.texture.swizzle.* (no regression) BUG=angleproject:1244 Change-Id: Ie0e790e58ec054b64ef5983a09dbfc7754f269ca Reviewed-on: https://chromium-review.googlesource.com/327104 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);
    
            GLenum swizzles[] =
            {
                GL_RED,
                GL_GREEN,
                GL_BLUE,
                GL_ALPHA,
                GL_ZERO,
                GL_ONE,
            };
    
            for (int r = 0; r < 6; r++)
            {
                for (int g = 0; g < 6; g++)
                {
                    for (int b = 0; b < 6; b++)
                    {
                        for (int a = 0; a < 6; a++)
                        {
                            swizzlePermutation permutation;
                            permutation.swizzleRed = swizzles[r];
                            permutation.swizzleGreen = swizzles[g];
                            permutation.swizzleBlue = swizzles[b];
                            permutation.swizzleAlpha = swizzles[a];
                            mPermutations.push_back(permutation);
                        }
                    }
                }
            }
        }
    
        void SetUp() override
        {
            ANGLETest::SetUp();
    
            const std::string vertexShaderSource = SHADER_SOURCE
            (
                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 = SHADER_SOURCE
            (
                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 (size_t i = 0; i < mPermutations.size(); i++)
            {
                const swizzlePermutation& permutation = mPermutations[i];
    
                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)
    {
        GLfloat data[] = {0.7f};
        init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, A32F_2D)
    {
        GLfloat data[] = {
            0.4f,
        };
        init2DTexture(GL_ALPHA, GL_ALPHA, GL_FLOAT, data);
        runTest2D();
    }
    
    TEST_P(SwizzleTest, LA32F_2D)
    {
        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();
    }
    
    // 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