aboutsummaryrefslogtreecommitdiff
path: root/src/tests/gl_tests/GLSLTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/gl_tests/GLSLTest.cpp')
-rw-r--r--src/tests/gl_tests/GLSLTest.cpp132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index 4ff7f66e79..7b6e70d168 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -18318,6 +18318,138 @@ void main() {
EXPECT_EQ(0u, shader);
}
+// Test that passing large arrays to functions are compiled correctly. Regression test for the
+// SPIR-V generator that made a copy of the array to pass to the function, by decomposing and
+// reconstructing it (in the absence of OpCopyLogical), but the reconstruction instruction has a
+// length higher than can fit in SPIR-V.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArrayPassedToFunction)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+uniform Large { float a[65536]; };
+float f(float b[65536])
+{
+ b[0] = 1.0;
+ return b[0] + b[1];
+}
+out vec4 color;
+void main() {
+ color = vec4(f(a), 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
+// Make sure the shader in LargeInterfaceBlockArrayPassedToFunction works if the large local is
+// avoided.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArray)
+{
+ int maxUniformBlockSize = 0;
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
+ ANGLE_SKIP_TEST_IF(maxUniformBlockSize < 16384 * 4);
+
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+uniform Large { float a[16384]; };
+out vec4 color;
+void main() {
+ color = vec4(a[0], 0.0, 0.0, 1.0);
+})";
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+}
+
+// Similar to LargeInterfaceBlockArrayPassedToFunction, but the array is nested in a struct.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArrayPassedToFunction)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+struct S { float a[65536]; };
+uniform Large { S s; };
+float f(float b[65536])
+{
+ b[0] = 1.0;
+ return b[0] + b[1];
+}
+out vec4 color;
+void main() {
+ color = vec4(f(s.a), 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
+// Make sure the shader in LargeInterfaceBlockNestedArrayPassedToFunction works if the large local
+// is avoided.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArray)
+{
+ int maxUniformBlockSize = 0;
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
+ ANGLE_SKIP_TEST_IF(maxUniformBlockSize < 16384 * 4);
+
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+struct S { float a[16384]; };
+uniform Large { S s; };
+out vec4 color;
+void main() {
+ color = vec4(s.a[0], 0.0, 0.0, 1.0);
+})";
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+}
+
+// Similar to LargeInterfaceBlockArrayPassedToFunction, but the large array is copied to a local
+// variable instead.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArrayCopiedToLocal)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+uniform Large { float a[65536]; };
+out vec4 color;
+void main() {
+ float b[65536] = a;
+ color = vec4(b[0], 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
+// Similar to LargeInterfaceBlockArrayCopiedToLocal, but the array is nested in a struct
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArrayCopiedToLocal)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+struct S { float a[65536]; };
+uniform Large { S s; };
+out vec4 color;
+void main() {
+ S s2 = s;
+ color = vec4(s2.a[0], 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
+// Test that too large varyings are rejected.
+TEST_P(GLSLTest_ES3, LargeArrayVarying)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+in float a[65536];
+out vec4 color;
+void main() {
+ color = vec4(a[0], 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
} // anonymous namespace
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(