diff options
Diffstat (limited to 'src/tests/gl_tests/GLSLTest.cpp')
-rw-r--r-- | src/tests/gl_tests/GLSLTest.cpp | 132 |
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( |