Edit

kc3-lang/angle/src/tests/compiler_tests/EXT_blend_func_extended_test.cpp

Branch :

  • Show log

    Commit

  • Author : Yunchao He
    Date : 2017-04-21 12:15:49
    Hash : 4f285443
    Message : Refactoring: replace NULL by nullptr for pointers (2nd CL). This CL mainly handles the pointer comparisons (== or !=). BUG=angleproject:2001 Change-Id: I25ac3b61032e7ad91459a1c6541cadc87cf9b160 Reviewed-on: https://chromium-review.googlesource.com/483935 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/tests/compiler_tests/EXT_blend_func_extended_test.cpp
  • //
    // Copyright (c) 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.
    //
    // EXT_blend_func_extended.cpp:
    //   Test for EXT_blend_func_extended_test
    //
    
    #include "angle_gl.h"
    #include "gtest/gtest.h"
    #include "GLSLANG/ShaderLang.h"
    
    using testing::Combine;
    using testing::Values;
    using testing::make_tuple;
    
    namespace
    {
    const char ESSLVersion100[] = "#version 100\n";
    const char ESSLVersion300[] = "#version 300 es\n";
    const char ESSLVersion310[] = "#version 310 es\n";
    const char EXTBFEPragma[]   = "#extension GL_EXT_blend_func_extended : require\n";
    
    const char ESSL100_SimpleShader1[] =
        "precision mediump float;\n"
        "void main() { \n"
        "    gl_FragColor = vec4(1.0);\n"
        "    gl_SecondaryFragColorEXT = vec4(gl_MaxDualSourceDrawBuffersEXT / 10);\n"
        "}\n";
    
    // Shader that tests only the access to gl_MaxDualSourceDrawBuffersEXT.
    const char ESSL100_MaxDualSourceAccessShader[] =
        "precision mediump float;\n"
        "void main() { gl_FragColor = vec4(gl_MaxDualSourceDrawBuffersEXT / 10); }\n";
    
    // Shader that writes to SecondaryFragData.
    const char ESSL100_FragDataShader[] =
        "#extension GL_EXT_draw_buffers : require\n"
        "precision mediump float;\n"
        "void main() {\n"
        "    gl_FragData[gl_MaxDrawBuffers - 1] = vec4(1.0);\n"
        "    gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1);\n"
        "}\n";
    
    // Shader that writes to SecondaryFragColor and SecondaryFragData does not compile.
    const char ESSL100_ColorAndDataWriteFailureShader1[] =
        "precision mediump float;\n"
        "void main() {\n"
        "    gl_SecondaryFragColorEXT = vec4(1.0);\n"
        "    gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT] = vec4(0.1);\n"
        "}\n";
    
    // Shader that writes to FragColor and SecondaryFragData does not compile.
    const char ESSL100_ColorAndDataWriteFailureShader2[] =
        "precision mediump float;\n"
        "void main() {\n"
        "    gl_FragColor = vec4(1.0);\n"
        "    gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT] = vec4(0.1);\n"
        "}\n";
    
    // Shader that writes to FragData and SecondaryFragColor.
    const char ESSL100_ColorAndDataWriteFailureShader3[] =
        "#extension GL_EXT_draw_buffers : require\n"
        "precision mediump float;\n"
        "void main() {\n"
        "    gl_SecondaryFragColorEXT = vec4(1.0);\n"
        "    gl_FragData[gl_MaxDrawBuffers] = vec4(0.1);\n"
        "}\n";
    
    // In GLSL version 300 es, the gl_MaxDualSourceDrawBuffersEXT is available.
    const char ESSL300_MaxDualSourceAccessShader[] =
        "precision mediump float;\n"
        "layout(location = 0) out mediump vec4 fragColor;"
        "void main() {\n"
        "    fragColor = vec4(gl_MaxDualSourceDrawBuffersEXT / 10);\n"
        "}\n";
    
    // In GLSL version 300 es, the only way to write a correct shader is to require the extension and
    // then leave the locations unspecified. The caller will then bind the variables with the extension
    // binding functions.
    const char ESSL300_LocationAndUnspecifiedOutputShader[] =
        "precision mediump float;\n"
        "layout(location = 0) out mediump vec4 fragColor;"
        "out mediump vec4 secondaryFragColor;"
        "void main() {\n"
        "    fragColor = vec4(1.0);\n"
        "    secondaryFragColor = vec4(1.0);\n"
        "}\n";
    
    const char ESSL300_TwoUnspecifiedLocationOutputsShader[] =
        "precision mediump float;\n"
        "out mediump vec4 fragColor;"
        "out mediump vec4 secondaryFragColor;"
        "void main() {\n"
        "    fragColor = vec4(1.0);\n"
        "    secondaryFragColor = vec4(1.0);\n"
        "}\n";
    
    // Shader that is correct in GLSL ES 3.10 fails when used in version 300 es.
    const char ESSL310_LocationIndexShader[] =
        "precision mediump float;\n"
        "layout(location = 0) out mediump vec4 fragColor;"
        "layout(location = 0, index = 1) out mediump vec4 secondaryFragColor;"
        "void main() {\n"
        "   fragColor = vec4(1);\n"
        "   secondaryFragColor = vec4(1);\n"
        "}\n";
    
    // Shader that specifies index layout qualifier but not location fails to compile. Currently fails
    // to compile due to version 310 es not being supported.
    const char ESSL310_LocationIndexFailureShader[] =
        "precision mediump float;\n"
        "layout(location = 0) out mediump vec4 fragColor;"
        "layout(index = 1) out mediump vec4 secondaryFragColor;"
        "void main() {\n"
        "   fragColor = vec4(1.0);\n"
        "   secondaryFragColor = vec4(1.0);\n"
        "}\n";
    
    class EXTBlendFuncExtendedTest
        : public testing::TestWithParam<testing::tuple<ShShaderSpec, const char *, const char *>>
    {
      protected:
        virtual void SetUp()
        {
            sh::InitBuiltInResources(&mResources);
            // EXT_draw_buffers is used in some of the shaders for test purposes.
            mResources.EXT_draw_buffers = 1;
            mResources.NV_draw_buffers  = 2;
    
            mCompiler = nullptr;
        }
    
        virtual void TearDown() { DestroyCompiler(); }
        void DestroyCompiler()
        {
            if (mCompiler)
            {
                sh::Destruct(mCompiler);
                mCompiler = nullptr;
            }
        }
    
        void InitializeCompiler()
        {
            DestroyCompiler();
            mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, testing::get<0>(GetParam()),
                                              SH_GLSL_COMPATIBILITY_OUTPUT, &mResources);
            ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
        }
    
        testing::AssertionResult TestShaderCompile(const char *pragma)
        {
            return TestShaderCompile(testing::get<1>(GetParam()),  // Version.
                                     pragma,
                                     testing::get<2>(GetParam())  // Shader.
                                     );
        }
    
        testing::AssertionResult TestShaderCompile(const char *version,
                                                   const char *pragma,
                                                   const char *shader)
        {
            const char *shaderStrings[] = {version, pragma, shader};
            bool success                = sh::Compile(mCompiler, shaderStrings, 3, 0);
            if (success)
            {
                return ::testing::AssertionSuccess() << "Compilation success";
            }
            return ::testing::AssertionFailure() << sh::GetInfoLog(mCompiler);
        }
    
      protected:
        ShBuiltInResources mResources;
        ShHandle mCompiler;
    };
    
    // Extension flag is required to compile properly. Expect failure when it is
    // not present.
    TEST_P(EXTBlendFuncExtendedTest, CompileFailsWithoutExtension)
    {
        mResources.EXT_blend_func_extended = 0;
        InitializeCompiler();
        EXPECT_FALSE(TestShaderCompile(EXTBFEPragma));
    }
    
    // Extension directive is required to compile properly. Expect failure when
    // it is not present.
    TEST_P(EXTBlendFuncExtendedTest, CompileFailsWithExtensionWithoutPragma)
    {
        mResources.EXT_blend_func_extended  = 1;
        mResources.MaxDualSourceDrawBuffers = 1;
        InitializeCompiler();
        EXPECT_FALSE(TestShaderCompile(""));
    }
    
    // With extension flag and extension directive, compiling succeeds.
    // Also test that the extension directive state is reset correctly.
    TEST_P(EXTBlendFuncExtendedTest, CompileSucceedsWithExtensionAndPragma)
    {
        mResources.EXT_blend_func_extended  = 1;
        mResources.MaxDualSourceDrawBuffers = 1;
        InitializeCompiler();
        EXPECT_TRUE(TestShaderCompile(EXTBFEPragma));
        // Test reset functionality.
        EXPECT_FALSE(TestShaderCompile(""));
        EXPECT_TRUE(TestShaderCompile(EXTBFEPragma));
    }
    
    // The SL #version 100 shaders that are correct work similarly
    // in both GL2 and GL3, with and without the version string.
    INSTANTIATE_TEST_CASE_P(CorrectESSL100Shaders,
                            EXTBlendFuncExtendedTest,
                            Combine(Values(SH_GLES2_SPEC, SH_GLES3_SPEC),
                                    Values("", ESSLVersion100),
                                    Values(ESSL100_SimpleShader1,
                                           ESSL100_MaxDualSourceAccessShader,
                                           ESSL100_FragDataShader)));
    
    INSTANTIATE_TEST_CASE_P(CorrectESSL300Shaders,
                            EXTBlendFuncExtendedTest,
                            Combine(Values(SH_GLES3_SPEC),
                                    Values(ESSLVersion300),
                                    Values(ESSL300_MaxDualSourceAccessShader,
                                           ESSL300_LocationAndUnspecifiedOutputShader,
                                           ESSL300_TwoUnspecifiedLocationOutputsShader)));
    
    class EXTBlendFuncExtendedCompileFailureTest : public EXTBlendFuncExtendedTest
    {
    };
    
    TEST_P(EXTBlendFuncExtendedCompileFailureTest, CompileFails)
    {
        // Expect compile failure due to shader error, with shader having correct pragma.
        mResources.EXT_blend_func_extended  = 1;
        mResources.MaxDualSourceDrawBuffers = 1;
        InitializeCompiler();
        EXPECT_FALSE(TestShaderCompile(EXTBFEPragma));
    }
    
    // Incorrect #version 100 shaders fail.
    INSTANTIATE_TEST_CASE_P(IncorrectESSL100Shaders,
                            EXTBlendFuncExtendedCompileFailureTest,
                            Combine(Values(SH_GLES2_SPEC),
                                    Values(ESSLVersion100),
                                    Values(ESSL100_ColorAndDataWriteFailureShader1,
                                           ESSL100_ColorAndDataWriteFailureShader2,
                                           ESSL100_ColorAndDataWriteFailureShader3)));
    
    // Correct #version 300 es shaders fail in GLES2 context, regardless of version string.
    INSTANTIATE_TEST_CASE_P(CorrectESSL300Shaders,
                            EXTBlendFuncExtendedCompileFailureTest,
                            Combine(Values(SH_GLES2_SPEC),
                                    Values("", ESSLVersion100, ESSLVersion300),
                                    Values(ESSL300_LocationAndUnspecifiedOutputShader,
                                           ESSL300_TwoUnspecifiedLocationOutputsShader)));
    
    // Correct #version 100 shaders fail when used with #version 300 es.
    INSTANTIATE_TEST_CASE_P(CorrectESSL100Shaders,
                            EXTBlendFuncExtendedCompileFailureTest,
                            Combine(Values(SH_GLES3_SPEC),
                                    Values(ESSLVersion300),
                                    Values(ESSL100_SimpleShader1, ESSL100_FragDataShader)));
    
    // Incorrect #version 310 es always fails.
    INSTANTIATE_TEST_CASE_P(IncorrectESSL310Shaders,
                            EXTBlendFuncExtendedCompileFailureTest,
                            Combine(Values(SH_GLES3_SPEC),
                                    Values(ESSLVersion300, ESSLVersion310),
                                    Values(ESSL310_LocationIndexFailureShader)));
    
    // Correct #version 310 es fails in #version 300 es.
    INSTANTIATE_TEST_CASE_P(
        CorrectESSL310ShadersInESSL300,
        EXTBlendFuncExtendedCompileFailureTest,
        Values(make_tuple(SH_GLES3_SPEC, &ESSLVersion300[0], &ESSL310_LocationIndexShader[0])));
    
    // Correct #version 310 es fails in #version 310 es, due to 3.1 not being supported.
    INSTANTIATE_TEST_CASE_P(
        CorrectESSL310Shaders,
        EXTBlendFuncExtendedCompileFailureTest,
        Values(make_tuple(SH_GLES3_SPEC, &ESSLVersion310[0], &ESSL310_LocationIndexShader[0])));
    
    }  // namespace