Edit

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

Branch :

  • Show log

    Commit

  • Author : Stuart Morgan
    Date : 2019-08-14 12:25:12
    Hash : 9d737966
    Message : Standardize copyright notices to project style For all "ANGLE Project" copyrights, standardize to the format specified by the style guide. Changes: - "Copyright (c)" and "Copyright(c)" changed to just "Copyright". - Removed the second half of date ranges ("Y1Y1-Y2Y2"->"Y1Y1"). - Fixed a small number of files that had no copyright date using the initial commit year from the version control history. - Fixed one instance of copyright being "The ANGLE Project" rather than "The ANGLE Project Authors" These changes are applied both to the copyright of source file, and where applicable to copyright statements that are generated by templates. BUG=angleproject:3811 Change-Id: I973dd65e4ef9deeba232d5be74c768256a0eb2e5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1754397 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>

  • src/tests/compiler_tests/ShCompile_test.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.
    //
    // ShCompile_test.cpp
    //   Test the sh::Compile interface with different parameters.
    //
    
    #include <clocale>
    #include "GLSLANG/ShaderLang.h"
    #include "angle_gl.h"
    #include "common/angleutils.h"
    #include "common/platform.h"
    #include "gtest/gtest.h"
    
    class ShCompileTest : public testing::Test
    {
      public:
        ShCompileTest() {}
    
      protected:
        void SetUp() override
        {
            sh::InitBuiltInResources(&mResources);
            mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL_SPEC,
                                              SH_GLSL_COMPATIBILITY_OUTPUT, &mResources);
            ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
        }
    
        void TearDown() override
        {
            if (mCompiler)
            {
                sh::Destruct(mCompiler);
                mCompiler = nullptr;
            }
        }
    
        void testCompile(const char **shaderStrings, int stringCount, bool expectation)
        {
            ShCompileOptions options      = SH_OBJECT_CODE | SH_VARIABLES | SH_INIT_OUTPUT_VARIABLES;
            bool success                  = sh::Compile(mCompiler, shaderStrings, stringCount, options);
            const std::string &compileLog = sh::GetInfoLog(mCompiler);
            EXPECT_EQ(expectation, success) << compileLog;
        }
    
        ShBuiltInResources mResources;
    
        class ScopedRestoreDefaultLocale : angle::NonCopyable
        {
          public:
            ScopedRestoreDefaultLocale();
            ~ScopedRestoreDefaultLocale();
    
          private:
            std::locale defaultLocale;
        };
    
      public:
        ShHandle mCompiler;
    };
    
    ShCompileTest::ScopedRestoreDefaultLocale::ScopedRestoreDefaultLocale()
    {
        defaultLocale = std::locale();
    }
    
    ShCompileTest::ScopedRestoreDefaultLocale::~ScopedRestoreDefaultLocale()
    {
        std::locale::global(defaultLocale);
    }
    
    class ShCompileComputeTest : public ShCompileTest
    {
      public:
        ShCompileComputeTest() {}
    
      protected:
        void SetUp() override
        {
            sh::InitBuiltInResources(&mResources);
            mCompiler = sh::ConstructCompiler(GL_COMPUTE_SHADER, SH_WEBGL3_SPEC,
                                              SH_GLSL_COMPATIBILITY_OUTPUT, &mResources);
            ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
        }
    };
    
    // Test calling sh::Compile with compute shader source string.
    TEST_F(ShCompileComputeTest, ComputeShaderString)
    {
        constexpr char kComputeShaderString[] =
            R"(#version 310 es
            layout(local_size_x=1) in;
            void main()
            {
            })";
    
        const char *shaderStrings[] = {kComputeShaderString};
    
        testCompile(shaderStrings, 1, true);
    }
    
    // Test calling sh::Compile with more than one shader source string.
    TEST_F(ShCompileTest, MultipleShaderStrings)
    {
        const std::string &shaderString1 =
            "precision mediump float;\n"
            "void main() {\n";
        const std::string &shaderString2 =
            "    gl_FragColor = vec4(0.0);\n"
            "}";
    
        const char *shaderStrings[] = {shaderString1.c_str(), shaderString2.c_str()};
    
        testCompile(shaderStrings, 2, true);
    }
    
    // Test calling sh::Compile with a tokens split into different shader source strings.
    TEST_F(ShCompileTest, TokensSplitInShaderStrings)
    {
        const std::string &shaderString1 =
            "precision mediump float;\n"
            "void ma";
        const std::string &shaderString2 =
            "in() {\n"
            "#i";
        const std::string &shaderString3 =
            "f 1\n"
            "    gl_FragColor = vec4(0.0);\n"
            "#endif\n"
            "}";
    
        const char *shaderStrings[] = {shaderString1.c_str(), shaderString2.c_str(),
                                       shaderString3.c_str()};
    
        testCompile(shaderStrings, 3, true);
    }
    
    // Parsing floats in shaders can run afoul of locale settings.
    // Eg. in de_DE, `strtof("1.9")` will yield `1.0f`. (It's expecting "1,9")
    TEST_F(ShCompileTest, DecimalSepLocale)
    {
        // Locale names are platform dependent, add platform-specific names of locales to be tested here
        const std::string availableLocales[] = {
            "de_DE",
            "de-DE",
            "de_DE.UTF-8",
            "de_DE.ISO8859-1",
            "de_DE.ISO8859-15",
            "de_DE@euro",
            "de_DE.88591",
            "de_DE.88591.en",
            "de_DE.iso88591",
            "de_DE.ISO-8859-1",
            "de_DE.ISO_8859-1",
            "de_DE.iso885915",
            "de_DE.ISO-8859-15",
            "de_DE.ISO_8859-15",
            "de_DE.8859-15",
            "de_DE.8859-15@euro",
    #if !defined(_WIN32)
            // TODO(https://crbug.com/972372): Add this test back on Windows once the
            // CRT no longer throws on code page sections ('ISO-8859-15@euro') that
            // are >= 16 characters long.
            "de_DE.ISO-8859-15@euro",
    #endif
            "de_DE.UTF-8@euro",
            "de_DE.utf8",
            "German_germany",
            "German_Germany",
            "German_Germany.1252",
            "German_Germany.UTF-8",
            "German",
            // One ubuntu tester doesn't have a german locale, but da_DK.utf8 has similar float
            // representation
            "da_DK.utf8"
        };
    
        const auto localeExists = [](const std::string name) {
            return bool(setlocale(LC_ALL, name.c_str()));
        };
    
        const char kSource[] = R"(
        void main()
        {
            gl_FragColor = vec4(1.9);
        })";
        const char *parts[]  = {kSource};
    
        int testedLocales = 0;
    
        // Ensure the locale is reset after the test runs.
        ScopedRestoreDefaultLocale restoreLocale;
    
        for (const std::string &locale : availableLocales)
        {
            // If the locale doesn't exist on the testing platform, the locale constructor will fail,
            // throwing an exception
            // We use setlocale() (through localeExists) to test whether a locale
            // exists before calling the locale constructor
            if (localeExists(locale))
            {
                std::locale localizedLoc(locale);
    
                // std::locale::global() must be used instead of setlocale() to affect new streams'
                // default locale
                std::locale::global(std::locale::classic());
                sh::Compile(mCompiler, parts, 1, SH_OBJECT_CODE);
                std::string referenceOut = sh::GetObjectCode(mCompiler);
                EXPECT_NE(referenceOut.find("1.9"), std::string::npos)
                    << "float formatted incorrectly with classic locale";
    
                sh::ClearResults(mCompiler);
    
                std::locale::global(localizedLoc);
                sh::Compile(mCompiler, parts, 1, SH_OBJECT_CODE);
                std::string localizedOut = sh::GetObjectCode(mCompiler);
                EXPECT_NE(localizedOut.find("1.9"), std::string::npos)
                    << "float formatted incorrectly with locale (" << localizedLoc.name() << ") set";
    
                ASSERT_EQ(referenceOut, localizedOut)
                    << "different output with locale (" << localizedLoc.name() << ") set";
    
                testedLocales++;
            }
        }
    }
    
    // For testing Desktop GL Shaders
    class ShCompileDesktopGLTest : public ShCompileTest
    {
      public:
        ShCompileDesktopGLTest() {}
    
      protected:
        void SetUp() override
        {
            sh::InitBuiltInResources(&mResources);
            mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_GL_COMPATIBILITY_SPEC,
                                              SH_GLSL_330_CORE_OUTPUT, &mResources);
            ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
        }
    };
    
    // Test calling sh::Compile with fragment shader source string
    TEST_F(ShCompileDesktopGLTest, DesktopGLString)
    {
        constexpr char kFragmentShaderString[] =
            R"(#version 330
            void main()
            {
            })";
    
        const char *shaderStrings[] = {kFragmentShaderString};
    
        testCompile(shaderStrings, 1, true);
    }
    
    // Test calling sh::Compile with core version
    TEST_F(ShCompileDesktopGLTest, FragmentShaderCoreVersion)
    {
        constexpr char kFragmentShaderString[] =
            R"(#version 330 core
            void main()
            {
            })";
    
        const char *shaderStrings[] = {kFragmentShaderString};
    
        testCompile(shaderStrings, 1, true);
    }
    
    // Implicit conversions in basic operations
    TEST_F(ShCompileDesktopGLTest, ImplicitConversionBasicOperation)
    {
        constexpr char kFragmentShaderString[] =
            R"(#version 330 core
            void main()
            {
                //float a = 1 + 1.5;
                //float b = 1 - 1.5;
                //float c = 1 * 1.5;
                //float d = 1 / 1.5;
                //float e = 1.5 + 1;
                //float f = 1.5 - 1;
                float g = 1.5 * 1;
                //float h = 1.5 / 1;
            })";
    
        const char *shaderStrings[] = {kFragmentShaderString};
    
        testCompile(shaderStrings, 1, true);
    }
    
    // Implicit conversions when assigning
    TEST_F(ShCompileDesktopGLTest, ImplicitConversionAssign)
    {
        constexpr char kFragmentShaderString[] =
            R"(#version 330 core
            void main()
            {
                float a = 1;
                uint b = 2u;
                a = b;
                a += b;
                a -= b;
                a *= b;
                a /= b;
            })";
    
        const char *shaderStrings[] = {kFragmentShaderString};
    
        testCompile(shaderStrings, 1, true);
    }
    
    // Implicit conversions for vectors
    TEST_F(ShCompileDesktopGLTest, ImplicitConversionVector)
    {
        constexpr char kFragmentShaderString[] =
            R"(#version 330 core
            void main()
            {
                vec3 a;
                ivec3 b = ivec3(1, 1, 1);
                a = b;
            })";
    
        const char *shaderStrings[] = {kFragmentShaderString};
    
        testCompile(shaderStrings, 1, true);
    }
    
    // Implicit conversions should not convert between ints and uints
    TEST_F(ShCompileDesktopGLTest, ImplicitConversionAssignFailed)
    {
        constexpr char kFragmentShaderString[] =
            R"(#version 330 core
            void main()
            {
                int a = 1;
                uint b = 2;
                a = b;
            })";
    
        const char *shaderStrings[] = {kFragmentShaderString};
    
        testCompile(shaderStrings, 1, false);
    }
    
    // GL shaders use implicit conversions between types
    // Testing internal implicit conversions
    TEST_F(ShCompileDesktopGLTest, ImplicitConversionFunction)
    {
        constexpr char kFragmentShaderString[] =
            R"(#version 330 core
            void main()
            {
                float cosTheta = clamp(0.5,0,1);
                float exp = pow(0.5,2);
            })";
    
        const char *shaderStrings[] = {kFragmentShaderString};
    
        testCompile(shaderStrings, 1, true);
    }