Edit

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

Branch :

  • Show log

    Commit

  • Author : Yuly Novikov
    Date : 2021-03-02 19:04:57
    Hash : a6b16d29
    Message : Suppress UNINSTANTIATED_PARAMETERIZED_TEST failures on Ozone We only support ES2 on Ozone, so tests that depend on ES3 or ES31 support are not instantiated there. Bug: chromium:1183147 Change-Id: Id58bcd9b44a5b9a70b5ae8115e27c44f5dc81226 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2726550 Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Commit-Queue: Yuly Novikov <ynovikov@chromium.org>

  • src/tests/gl_tests/ShaderInterpTest.cpp
  • //
    // Copyright 2020 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.
    //
    // Tests for shader interpolation qualifiers
    //
    
    #include "common/mathutil.h"
    #include "test_utils/ANGLETest.h"
    #include "test_utils/gl_raii.h"
    
    using namespace angle;
    
    constexpr int kPixelColorThreshhold = 8;
    
    class ShaderInterpTest : public ANGLETest
    {
      protected:
        ShaderInterpTest() : ANGLETest()
        {
            setWindowWidth(128);
            setWindowHeight(128);
        }
    
        void draw(GLuint program, float skew)
        {
            glUseProgram(program);
    
            std::array<Vector4, 3> vertices;
            vertices[0] = {-1.0, -1.0, 0.0, 1.0};
            vertices[1] = {1.0, -1.0, 0.0, 1.0};
            vertices[2] = {0.0, 1.0 * skew, 0.0, skew};
    
            std::array<Vector4, 3> colors;
            colors[0] = {1.0, 0.0, 0.0, 1.0};
            colors[1] = {0.0, 1.0, 0.0, 1.0};
            colors[2] = {0.0, 0.0, 1.0, 1.0};
    
            GLint positionLocation = glGetAttribLocation(program, "position");
            GLint colorLocation    = glGetAttribLocation(program, "vertex_color");
    
            glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, vertices.data());
            glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors.data());
    
            glEnableVertexAttribArray(positionLocation);
            glEnableVertexAttribArray(colorLocation);
    
            glDrawArrays(GL_TRIANGLES, 0, 3);
        }
    };
    
    // Test that regular "smooth" interpolation works correctly
    TEST_P(ShaderInterpTest, Smooth)
    {
        const char *vertSrc = R"(#version 300 es
    precision highp float;
    in vec4 position;
    in vec4 vertex_color;
    smooth out vec4 interp_color;
    
    void main()
    {
        gl_Position = position;
        interp_color = vertex_color;
    }
    )";
        const char *fragSrc = R"(#version 300 es
    precision highp float;
    smooth in vec4 interp_color;
    out vec4 fragColor;
    
    void main()
    {
        fragColor = interp_color;
    }
    )";
    
        // iOS chokes on the "smooth" qualifier.
        // TODO(anglebug.com/5491): Add shader compiler workaround that omits "smooth".
        ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());
    
        ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
        glClear(GL_COLOR_BUFFER_BIT);
        draw(program, 1.0);
        EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(62, 64, 128, 255), kPixelColorThreshhold);
    
        glClear(GL_COLOR_BUFFER_BIT);
        draw(program, 2.0);
        EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(83, 86, 86, 255), kPixelColorThreshhold);
    }
    
    // Test that uninterpolated "Flat" interpolation works correctly
    TEST_P(ShaderInterpTest, Flat)
    {
        // TODO: anglebug.com/4085
        // No vendors currently support VK_EXT_provoking_vertex, which is necessary for conformant flat
        // shading. SwiftShader does technically support this extension, but as it has not yet been
        // ratified by Khronos, the vulkan validation layers do not recognize the create info struct,
        // causing it to be stripped and thus causing the extension to behave as if it is disabled.
        ANGLE_SKIP_TEST_IF(IsVulkan());
    
        // http://anglebug.com/5232. Metal doesn't support last provoking vertex yet.
        ANGLE_SKIP_TEST_IF(IsMetal());
    
        const char *vertSrc = R"(#version 300 es
    precision highp float;
    in vec4 position;
    in vec4 vertex_color;
    flat out vec4 interp_color;
    
    void main()
    {
        gl_Position = position;
        interp_color = vertex_color;
    }
    )";
        const char *fragSrc = R"(#version 300 es
    precision highp float;
    flat in vec4 interp_color;
    out vec4 fragColor;
    
    void main()
    {
        fragColor = interp_color;
    }
    )";
    
        ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
        glClear(GL_COLOR_BUFFER_BIT);
        draw(program, 1.0);
        GLColor smooth_reference;
        glReadPixels(64, 64, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &smooth_reference);
        EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor(0, 0, 255, 255));
    }
    
    // Test that "noperspective" interpolation correctly interpolates in screenspace
    TEST_P(ShaderInterpTest, NoPerspective)
    {
        ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_shader_noperspective_interpolation"));
    
        const char *vertSrcSmooth = R"(#version 300 es
    precision highp float;
    in vec4 position;
    in vec4 vertex_color;
    smooth out vec4 interp_color;
    
    void main()
    {
        gl_Position = position;
        interp_color = vertex_color;
    }
    )";
        const char *fragSrcSmooth = R"(#version 300 es
    precision highp float;
    smooth in vec4 interp_color;
    out vec4 fragColor;
    
    void main()
    {
        fragColor = interp_color;
    }
    )";
        ANGLE_GL_PROGRAM(programSmooth, vertSrcSmooth, fragSrcSmooth);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        draw(programSmooth, 1.0);
        GLColor smooth_reference;
        glReadPixels(64, 64, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &smooth_reference);
    
        const char *vertSrcNoPerspective = R"(#version 300 es
    #extension GL_NV_shader_noperspective_interpolation : require
    
    #ifndef GL_NV_shader_noperspective_interpolation
    #error GL_NV_shader_noperspective_interpolation is not defined
    #endif
    
    precision highp float;
    in vec4 position;
    in vec4 vertex_color;
    noperspective out vec4 interp_color;
    
    void main()
    {
        gl_Position = position;
        interp_color = vertex_color;
    }
    )";
        const char *fragSrcNoPerspective = R"(#version 300 es
    #extension GL_NV_shader_noperspective_interpolation : require
    
    #ifndef GL_NV_shader_noperspective_interpolation
    #error GL_NV_shader_noperspective_interpolation is not defined
    #endif
    
    precision highp float;
    noperspective in vec4 interp_color;
    out vec4 fragColor;
    
    void main()
    {
        fragColor = interp_color;
    }
    )";
        ANGLE_GL_PROGRAM(programNoPerspective, vertSrcNoPerspective, fragSrcNoPerspective);
        glClear(GL_COLOR_BUFFER_BIT);
        draw(programNoPerspective, 1.0);
        EXPECT_PIXEL_COLOR_EQ(64, 64, smooth_reference);
    
        glClear(GL_COLOR_BUFFER_BIT);
        draw(programNoPerspective, 2.0);
        EXPECT_PIXEL_COLOR_EQ(64, 64, smooth_reference);
    }
    
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShaderInterpTest);
    ANGLE_INSTANTIATE_TEST_ES3(ShaderInterpTest);