1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // Tests for GL_EXT_shader_non_constant_global_initializers
7*8975f5c5SAndroid Build Coastguard Worker //
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
12*8975f5c5SAndroid Build Coastguard Worker
13*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard Worker class ShaderNonConstGlobalInitializerTest : public ANGLETest<>
16*8975f5c5SAndroid Build Coastguard Worker {
17*8975f5c5SAndroid Build Coastguard Worker protected:
ShaderNonConstGlobalInitializerTest()18*8975f5c5SAndroid Build Coastguard Worker ShaderNonConstGlobalInitializerTest() : ANGLETest()
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker setWindowWidth(128);
21*8975f5c5SAndroid Build Coastguard Worker setWindowHeight(128);
22*8975f5c5SAndroid Build Coastguard Worker }
23*8975f5c5SAndroid Build Coastguard Worker
draw(GLuint program)24*8975f5c5SAndroid Build Coastguard Worker void draw(GLuint program)
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker std::array<Vector4, 3> vertices;
27*8975f5c5SAndroid Build Coastguard Worker vertices[0] = {-1.0, -1.0, 0.0, 1.0};
28*8975f5c5SAndroid Build Coastguard Worker vertices[1] = {1.0, -1.0, 0.0, 1.0};
29*8975f5c5SAndroid Build Coastguard Worker vertices[2] = {0.0, 1.0, 0.0, 2.0};
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker GLint positionLocation = glGetAttribLocation(program, "a_position");
32*8975f5c5SAndroid Build Coastguard Worker
33*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, vertices.data());
34*8975f5c5SAndroid Build Coastguard Worker
35*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(positionLocation);
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, 0, 3);
38*8975f5c5SAndroid Build Coastguard Worker }
39*8975f5c5SAndroid Build Coastguard Worker };
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Worker // Tests that the extension is disabled if not explicitly enabled- non constant initializers should
42*8975f5c5SAndroid Build Coastguard Worker // be forbidden in all cases unless this extension is explicitly requested
TEST_P(ShaderNonConstGlobalInitializerTest,Disabled)43*8975f5c5SAndroid Build Coastguard Worker TEST_P(ShaderNonConstGlobalInitializerTest, Disabled)
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker const char *fragSrc = R"(#version 100
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Worker precision lowp float;
48*8975f5c5SAndroid Build Coastguard Worker
49*8975f5c5SAndroid Build Coastguard Worker uniform float nondeterministic_uniform;
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard Worker float nonConstInitializer();
52*8975f5c5SAndroid Build Coastguard Worker
53*8975f5c5SAndroid Build Coastguard Worker float nonConstGlobal = nonConstInitializer();
54*8975f5c5SAndroid Build Coastguard Worker float sideEffectGlobal = 0.0;
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard Worker float nonConstInitializer() {
57*8975f5c5SAndroid Build Coastguard Worker sideEffectGlobal = 1.0;
58*8975f5c5SAndroid Build Coastguard Worker return nondeterministic_uniform;
59*8975f5c5SAndroid Build Coastguard Worker }
60*8975f5c5SAndroid Build Coastguard Worker
61*8975f5c5SAndroid Build Coastguard Worker void main()
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
64*8975f5c5SAndroid Build Coastguard Worker }
65*8975f5c5SAndroid Build Coastguard Worker )";
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Worker GLShader badFragment(GL_FRAGMENT_SHADER);
68*8975f5c5SAndroid Build Coastguard Worker glShaderSource(badFragment, 1, &fragSrc, nullptr);
69*8975f5c5SAndroid Build Coastguard Worker glCompileShader(badFragment);
70*8975f5c5SAndroid Build Coastguard Worker
71*8975f5c5SAndroid Build Coastguard Worker GLint compileResult;
72*8975f5c5SAndroid Build Coastguard Worker glGetShaderiv(badFragment, GL_COMPILE_STATUS, &compileResult);
73*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(compileResult, 0);
74*8975f5c5SAndroid Build Coastguard Worker
75*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
76*8975f5c5SAndroid Build Coastguard Worker }
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker // Test that non constant initializers are evaluated correctly in ESSL 100
TEST_P(ShaderNonConstGlobalInitializerTest,v100)79*8975f5c5SAndroid Build Coastguard Worker TEST_P(ShaderNonConstGlobalInitializerTest, v100)
80*8975f5c5SAndroid Build Coastguard Worker {
81*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_non_constant_global_initializers"));
82*8975f5c5SAndroid Build Coastguard Worker
83*8975f5c5SAndroid Build Coastguard Worker const char *fragSrc = R"(#version 100
84*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_shader_non_constant_global_initializers : require
85*8975f5c5SAndroid Build Coastguard Worker
86*8975f5c5SAndroid Build Coastguard Worker precision lowp float;
87*8975f5c5SAndroid Build Coastguard Worker
88*8975f5c5SAndroid Build Coastguard Worker #ifndef GL_EXT_shader_non_constant_global_initializers
89*8975f5c5SAndroid Build Coastguard Worker #error GL_EXT_shader_non_constant_global_initializers is not defined
90*8975f5c5SAndroid Build Coastguard Worker #endif
91*8975f5c5SAndroid Build Coastguard Worker
92*8975f5c5SAndroid Build Coastguard Worker uniform float nondeterministic_uniform;
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker float nonConstInitializer();
95*8975f5c5SAndroid Build Coastguard Worker
96*8975f5c5SAndroid Build Coastguard Worker float nonConstGlobal = nonConstInitializer();
97*8975f5c5SAndroid Build Coastguard Worker float sideEffectGlobal = 0.0;
98*8975f5c5SAndroid Build Coastguard Worker
99*8975f5c5SAndroid Build Coastguard Worker float nonConstInitializer() {
100*8975f5c5SAndroid Build Coastguard Worker sideEffectGlobal = 1.0;
101*8975f5c5SAndroid Build Coastguard Worker return nondeterministic_uniform;
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker
104*8975f5c5SAndroid Build Coastguard Worker void main()
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker )";
109*8975f5c5SAndroid Build Coastguard Worker
110*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), fragSrc);
111*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker glUseProgram(program);
114*8975f5c5SAndroid Build Coastguard Worker glUniform1f(glGetUniformLocation(program, "nondeterministic_uniform"), 1.0f);
115*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
116*8975f5c5SAndroid Build Coastguard Worker
117*8975f5c5SAndroid Build Coastguard Worker draw(program);
118*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
119*8975f5c5SAndroid Build Coastguard Worker
120*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::white);
121*8975f5c5SAndroid Build Coastguard Worker }
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker // Test that non constant initializers are evaluated correctly in ESSL 300
TEST_P(ShaderNonConstGlobalInitializerTest,v300es)124*8975f5c5SAndroid Build Coastguard Worker TEST_P(ShaderNonConstGlobalInitializerTest, v300es)
125*8975f5c5SAndroid Build Coastguard Worker {
126*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_non_constant_global_initializers"));
127*8975f5c5SAndroid Build Coastguard Worker
128*8975f5c5SAndroid Build Coastguard Worker const char *fragSrc = R"(#version 300 es
129*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_shader_non_constant_global_initializers : require
130*8975f5c5SAndroid Build Coastguard Worker
131*8975f5c5SAndroid Build Coastguard Worker precision highp float;
132*8975f5c5SAndroid Build Coastguard Worker out vec4 fragColor;
133*8975f5c5SAndroid Build Coastguard Worker
134*8975f5c5SAndroid Build Coastguard Worker #ifndef GL_EXT_shader_non_constant_global_initializers
135*8975f5c5SAndroid Build Coastguard Worker #error GL_EXT_shader_non_constant_global_initializers is not defined
136*8975f5c5SAndroid Build Coastguard Worker #endif
137*8975f5c5SAndroid Build Coastguard Worker
138*8975f5c5SAndroid Build Coastguard Worker uniform float nondeterministic_uniform;
139*8975f5c5SAndroid Build Coastguard Worker
140*8975f5c5SAndroid Build Coastguard Worker float nonConstInitializer();
141*8975f5c5SAndroid Build Coastguard Worker
142*8975f5c5SAndroid Build Coastguard Worker float nonConstGlobal = nonConstInitializer();
143*8975f5c5SAndroid Build Coastguard Worker float sideEffectGlobal = 0.0;
144*8975f5c5SAndroid Build Coastguard Worker
145*8975f5c5SAndroid Build Coastguard Worker float nonConstInitializer() {
146*8975f5c5SAndroid Build Coastguard Worker sideEffectGlobal = 1.0;
147*8975f5c5SAndroid Build Coastguard Worker return nondeterministic_uniform;
148*8975f5c5SAndroid Build Coastguard Worker }
149*8975f5c5SAndroid Build Coastguard Worker
150*8975f5c5SAndroid Build Coastguard Worker void main()
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker fragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
153*8975f5c5SAndroid Build Coastguard Worker }
154*8975f5c5SAndroid Build Coastguard Worker )";
155*8975f5c5SAndroid Build Coastguard Worker
156*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fragSrc);
157*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
158*8975f5c5SAndroid Build Coastguard Worker
159*8975f5c5SAndroid Build Coastguard Worker glUseProgram(program);
160*8975f5c5SAndroid Build Coastguard Worker glUniform1f(glGetUniformLocation(program, "nondeterministic_uniform"), 1.0f);
161*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
162*8975f5c5SAndroid Build Coastguard Worker
163*8975f5c5SAndroid Build Coastguard Worker draw(program);
164*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
165*8975f5c5SAndroid Build Coastguard Worker
166*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::white);
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShaderNonConstGlobalInitializerTest);
170*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(ShaderNonConstGlobalInitializerTest);