Edit

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

Branch :

  • Show log

    Commit

  • Author : Mohan Maiya
    Date : 2020-03-19 16:30:21
    Hash : ca2b6e1f
    Message : Vulkan: Implement EXT_shader_non_constant_global_initializers Enables the translator to handle non-constant global initializers in all essl versions iff the shader enables the extension to do so. Bug: angleproject:4468 Test: angle_end2end_tests --gtest_filter=ShaderNonConstGlobalInitializerTest.* Change-Id: I8f138c12fc83d2f38ff8f45ca9133222b01e4087 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2102959 Reviewed-by: Tobin Ehlis <tobine@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>

  • src/tests/gl_tests/ShaderNonConstGlobalInitializerTest.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 GL_EXT_shader_non_constant_global_initializers
    //
    
    #include "common/mathutil.h"
    #include "test_utils/ANGLETest.h"
    #include "test_utils/gl_raii.h"
    
    using namespace angle;
    
    class ShaderNonConstGlobalInitializerTest : public ANGLETest
    {
      protected:
        ShaderNonConstGlobalInitializerTest() : ANGLETest()
        {
            setWindowWidth(128);
            setWindowHeight(128);
        }
    
        void draw(GLuint 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, 0.0, 2.0};
    
            GLint positionLocation = glGetAttribLocation(program, "a_position");
    
            glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, vertices.data());
    
            glEnableVertexAttribArray(positionLocation);
    
            glDrawArrays(GL_TRIANGLES, 0, 3);
        }
    };
    
    // Tests that the extension is disabled if not explicitly enabled- non constant initializers should
    // be forbidden in all cases unless this extension is explicitly requested
    TEST_P(ShaderNonConstGlobalInitializerTest, Disabled)
    {
        const char *fragSrc = R"(#version 100
    
    precision lowp float;
    
    uniform float nondeterministic_uniform;
    
    float nonConstInitializer();
    
    float nonConstGlobal = nonConstInitializer();
    float sideEffectGlobal = 0.0;
    
    float nonConstInitializer() {
        sideEffectGlobal = 1.0;
        return nondeterministic_uniform;
    }
    
    void main()
    {
        gl_FragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
    }
    )";
    
        GLShader badFragment(GL_FRAGMENT_SHADER);
        glShaderSource(badFragment, 1, &fragSrc, nullptr);
        glCompileShader(badFragment);
    
        GLint compileResult;
        glGetShaderiv(badFragment, GL_COMPILE_STATUS, &compileResult);
        EXPECT_EQ(compileResult, 0);
    
        EXPECT_GL_NO_ERROR();
    }
    
    // Test that non constant initializers are evaluated correctly in ESSL 100
    TEST_P(ShaderNonConstGlobalInitializerTest, v100)
    {
        ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_non_constant_global_initializers"));
    
        const char *fragSrc = R"(#version 100
    #extension GL_EXT_shader_non_constant_global_initializers : require
    
    precision lowp float;
    
    #ifndef GL_EXT_shader_non_constant_global_initializers
    #error GL_EXT_shader_non_constant_global_initializers is not defined
    #endif
    
    uniform float nondeterministic_uniform;
    
    float nonConstInitializer();
    
    float nonConstGlobal = nonConstInitializer();
    float sideEffectGlobal = 0.0;
    
    float nonConstInitializer() {
        sideEffectGlobal = 1.0;
        return nondeterministic_uniform;
    }
    
    void main()
    {
        gl_FragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
    }
    )";
    
        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), fragSrc);
        EXPECT_GL_NO_ERROR();
    
        glUseProgram(program);
        glUniform1f(glGetUniformLocation(program, "nondeterministic_uniform"), 1.0f);
        ASSERT_GL_NO_ERROR();
    
        draw(program);
        EXPECT_GL_NO_ERROR();
    
        EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::white);
    }
    
    // Test that non constant initializers are evaluated correctly in ESSL 300
    TEST_P(ShaderNonConstGlobalInitializerTest, v300es)
    {
        ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_non_constant_global_initializers"));
    
        const char *fragSrc = R"(#version 300 es
    #extension GL_EXT_shader_non_constant_global_initializers : require
    
    precision highp float;
    out vec4 fragColor;
    
    #ifndef GL_EXT_shader_non_constant_global_initializers
    #error GL_EXT_shader_non_constant_global_initializers is not defined
    #endif
    
    uniform float nondeterministic_uniform;
    
    float nonConstInitializer();
    
    float nonConstGlobal = nonConstInitializer();
    float sideEffectGlobal = 0.0;
    
    float nonConstInitializer() {
        sideEffectGlobal = 1.0;
        return nondeterministic_uniform;
    }
    
    void main()
    {
        fragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
    }
    )";
    
        ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fragSrc);
        EXPECT_GL_NO_ERROR();
    
        glUseProgram(program);
        glUniform1f(glGetUniformLocation(program, "nondeterministic_uniform"), 1.0f);
        ASSERT_GL_NO_ERROR();
    
        draw(program);
        EXPECT_GL_NO_ERROR();
    
        EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::white);
    }
    
    ANGLE_INSTANTIATE_TEST_ES3(ShaderNonConstGlobalInitializerTest);