blob: 8b0b0fe2ad3ff73dc10f39b17204ed00791c8ac3 [file] [log] [blame]
//
// 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);