Hash :
ca2b6e1f
Author :
Date :
2020-03-19T16:30:21
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>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
//
// 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);