Edit

kc3-lang/angle/src/tests/gl_tests/PackUnpackTest.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/PackUnpackTest.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.
    //
    // PackUnpackTest:
    //   Tests the corrrectness of opengl 4.1 emulation of pack/unpack built-in functions.
    //
    
    #include "test_utils/ANGLETest.h"
    
    using namespace angle;
    
    namespace
    {
    
    class PackUnpackTest : public ANGLETest
    {
      protected:
        PackUnpackTest()
        {
            setWindowWidth(16);
            setWindowHeight(16);
            setConfigRedBits(8);
            setConfigGreenBits(8);
            setConfigBlueBits(8);
            setConfigAlphaBits(8);
        }
    
        void SetUp() override
        {
            ANGLETest::SetUp();
    
            // Vertex Shader source
            const std::string vs =
                R"(#version 300 es
                precision mediump float;
                in vec4 position;
    
                void main()
                {
                    gl_Position = position;
                })";
    
            // Fragment Shader source
            const std::string sNormFS =
                R"(#version 300 es
                precision mediump float;
                uniform mediump vec2 v;
                layout(location = 0) out mediump vec4 fragColor;
    
                void main()
                {
                    uint u = packSnorm2x16(v);
                    vec2 r = unpackSnorm2x16(u);
                    fragColor = vec4(r, 0.0, 1.0);
                })";
    
            // Fragment Shader source
            const std::string uNormFS =
                R"(#version 300 es
                precision mediump float;
                uniform mediump vec2 v;
                layout(location = 0) out mediump vec4 fragColor;
    
                void main()
                {
                    uint u = packUnorm2x16(v);
                    vec2 r = unpackUnorm2x16(u);
                    fragColor = vec4(r, 0.0, 1.0);
                })";
    
            // Fragment Shader source
            const std::string halfFS =
                R"(#version 300 es
                precision mediump float;
                uniform mediump vec2 v;
                layout(location = 0) out mediump vec4 fragColor;
    
                 void main()
                 {
                     uint u = packHalf2x16(v);
                     vec2 r = unpackHalf2x16(u);
                     fragColor = vec4(r, 0.0, 1.0);
                 })";
    
            mSNormProgram = CompileProgram(vs, sNormFS);
            mUNormProgram = CompileProgram(vs, uNormFS);
            mHalfProgram = CompileProgram(vs, halfFS);
            if (mSNormProgram == 0 || mUNormProgram == 0 || mHalfProgram == 0)
            {
                FAIL() << "shader compilation failed.";
            }
    
            glGenTextures(1, &mOffscreenTexture2D);
            glBindTexture(GL_TEXTURE_2D, mOffscreenTexture2D);
            glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, getWindowWidth(), getWindowHeight());
    
            glGenFramebuffers(1, &mOffscreenFramebuffer);
            glBindFramebuffer(GL_FRAMEBUFFER, mOffscreenFramebuffer);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mOffscreenTexture2D, 0);
    
            glViewport(0, 0, 16, 16);
    
            const GLfloat color[] = { 1.0f, 1.0f, 0.0f, 1.0f };
            glClearBufferfv(GL_COLOR, 0, color);
        }
    
        void TearDown() override
        {
            glDeleteTextures(1, &mOffscreenTexture2D);
            glDeleteFramebuffers(1, &mOffscreenFramebuffer);
            glDeleteProgram(mSNormProgram);
            glDeleteProgram(mUNormProgram);
            glDeleteProgram(mHalfProgram);
    
            ANGLETest::TearDown();
        }
    
        void compareBeforeAfter(GLuint program, float input1, float input2)
        {
            compareBeforeAfter(program, input1, input2, input1, input2);
        }
    
        void compareBeforeAfter(GLuint program, float input1, float input2, float expect1, float expect2)
        {
            GLint vec2Location = glGetUniformLocation(program, "v");
    
            glUseProgram(program);
            glUniform2f(vec2Location, input1, input2);
    
            drawQuad(program, "position", 0.5f);
    
            ASSERT_GL_NO_ERROR();
    
            GLfloat p[2] = { 0 };
            glReadPixels(8, 8, 1, 1, GL_RG, GL_FLOAT, p);
    
            ASSERT_GL_NO_ERROR();
    
            static const double epsilon = 0.0005;
            EXPECT_NEAR(p[0], expect1, epsilon);
            EXPECT_NEAR(p[1], expect2, epsilon);
        }
    
        GLuint mSNormProgram;
        GLuint mUNormProgram;
        GLuint mHalfProgram;
        GLuint mOffscreenFramebuffer;
        GLuint mOffscreenTexture2D;
    };
    
    // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating normal floating numbers.
    TEST_P(PackUnpackTest, PackUnpackSnormNormal)
    {
        // Expect the shader to output the same value as the input
        compareBeforeAfter(mSNormProgram, 0.5f, -0.2f);
        compareBeforeAfter(mSNormProgram, -0.35f, 0.75f);
        compareBeforeAfter(mSNormProgram, 0.00392f, -0.99215f);
        compareBeforeAfter(mSNormProgram, 1.0f, -0.00392f);
    }
    
    // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating normal floating
    // numbers.
    TEST_P(PackUnpackTest, PackUnpackUnormNormal)
    {
        // Expect the shader to output the same value as the input
        compareBeforeAfter(mUNormProgram, 0.5f, 0.2f, 0.5f, 0.2f);
        compareBeforeAfter(mUNormProgram, 0.35f, 0.75f, 0.35f, 0.75f);
        compareBeforeAfter(mUNormProgram, 0.00392f, 0.99215f, 0.00392f, 0.99215f);
        compareBeforeAfter(mUNormProgram, 1.0f, 0.00392f, 1.0f, 0.00392f);
    }
    
    // Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating normal floating numbers.
    TEST_P(PackUnpackTest, PackUnpackHalfNormal)
    {
        // TODO(cwallez) figure out why it is broken on Intel on Mac
    #if defined(ANGLE_PLATFORM_APPLE)
        if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
        {
            std::cout << "Test skipped on Intel on Mac." << std::endl;
            return;
        }
    #endif
    
        // Expect the shader to output the same value as the input
        compareBeforeAfter(mHalfProgram, 0.5f, -0.2f);
        compareBeforeAfter(mHalfProgram, -0.35f, 0.75f);
        compareBeforeAfter(mHalfProgram, 0.00392f, -0.99215f);
        compareBeforeAfter(mHalfProgram, 1.0f, -0.00392f);
    }
    
    // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating subnormal floating numbers.
    TEST_P(PackUnpackTest, PackUnpackSnormSubnormal)
    {
        // Expect the shader to output the same value as the input
        compareBeforeAfter(mSNormProgram, 0.00001f, -0.00001f);
    }
    
    // Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating subnormal
    // floating numbers.
    TEST_P(PackUnpackTest, PackUnpackUnormSubnormal)
    {
        // Expect the shader to output the same value as the input for positive numbers and clamp
        // to [0, 1]
        compareBeforeAfter(mUNormProgram, 0.00001f, -0.00001f, 0.00001f, 0.0f);
    }
    
    // Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating subnormal floating numbers.
    TEST_P(PackUnpackTest, PackUnpackHalfSubnormal)
    {
        // Expect the shader to output the same value as the input
        compareBeforeAfter(mHalfProgram, 0.00001f, -0.00001f);
    }
    
    // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating zero floating numbers.
    TEST_P(PackUnpackTest, PackUnpackSnormZero)
    {
        // Expect the shader to output the same value as the input
        compareBeforeAfter(mSNormProgram, 0.00000f, -0.00000f);
    }
    
    // Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating zero floating
    // numbers.
    TEST_P(PackUnpackTest, PackUnpackUnormZero)
    {
        compareBeforeAfter(mUNormProgram, 0.00000f, -0.00000f, 0.00000f, 0.00000f);
    }
    
    // Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating zero floating numbers.
    TEST_P(PackUnpackTest, PackUnpackHalfZero)
    {
        // Expect the shader to output the same value as the input
        compareBeforeAfter(mHalfProgram, 0.00000f, -0.00000f);
    }
    
    // Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating overflow floating
    // numbers.
    TEST_P(PackUnpackTest, PackUnpackUnormOverflow)
    {
        // Expect the shader to clamp the input to [0, 1]
        compareBeforeAfter(mUNormProgram, 67000.0f, -67000.0f, 1.0f, 0.0f);
    }
    
    // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating overflow floating numbers.
    TEST_P(PackUnpackTest, PackUnpackSnormOverflow)
    {
        // Expect the shader to clamp the input to [-1, 1]
        compareBeforeAfter(mSNormProgram, 67000.0f, -67000.0f, 1.0f, -1.0f);
    }
    
    // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
    ANGLE_INSTANTIATE_TEST(PackUnpackTest,
                           ES3_OPENGL(3, 3),
                           ES3_OPENGL(4, 0),
                           ES3_OPENGL(4, 1),
                           ES3_OPENGL(4, 2),
                           ES3_OPENGL(4, 3),
                           ES3_OPENGL(4, 4),
                           ES3_OPENGL(4, 5),
                           ES3_OPENGLES());
    }