Add varying packing validation for WebGL.
This CL moves the varying packing from the D3D layer up to Program.
This is necessary for WebGL validation, and gives us consistency
for the various back-ends. There may be some additional cleanup work
on the VaryingPacking class, because it does some work that is D3D-
specific.
WebGL requires strict varying packing. Instead of allowing success
unconditionally, it's an explicit error to succeed to pack a set of
varyings that the sample algorithm would fail to pack.
Introduce a new packing mode option to the varying packing class to
handle this different packing style, while keeping our old more
relaxed packing method for ES code.
BUG=angleproject:1675
Change-Id: I674ae685ba573cc2ad7d9dfb7441efa8cb2d55fc
Reviewed-on: https://chromium-review.googlesource.com/423254
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index 12a339e..7719436 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -1357,7 +1357,12 @@
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
- VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
+ // Special case: because arrays of mat2 are packed as small grids of two rows by two columns,
+ // we should be aware that when we're packing into an odd number of varying registers the
+ // last row will be empty and can not fit the final vec2 arrary.
+ GLint maxVec2Arrays = (maxVaryings >> 1) << 1;
+
+ VaryingTestBase(0, 0, 0, maxVec2Arrays, 0, 0, 0, 0, false, false, false, true);
}
// Verify shader source with a fixed length that is less than the null-terminated length will compile.
@@ -2520,6 +2525,73 @@
ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
}
+class WebGLGLSLTest : public GLSLTest
+{
+ protected:
+ WebGLGLSLTest() { setWebGLCompatibilityEnabled(true); }
+};
+
+TEST_P(WebGLGLSLTest, MaxVaryingVec4PlusFragCoord)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
+ // This test should fail, since we are really using (maxVaryings + 1) varyings.
+ VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
+}
+
+TEST_P(WebGLGLSLTest, MaxVaryingVec4PlusPointCoord)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
+ // This test should fail, since we are really using (maxVaryings + 1) varyings.
+ VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
+}
+
+TEST_P(WebGLGLSLTest, MaxPlusOneVaryingVec3)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
+}
+
+TEST_P(WebGLGLSLTest, MaxPlusOneVaryingVec3Array)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
+}
+
+TEST_P(WebGLGLSLTest, MaxVaryingVec3AndOneVec2)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
+}
+
+TEST_P(WebGLGLSLTest, MaxPlusOneVaryingVec2)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
+}
+
+TEST_P(WebGLGLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false,
+ false);
+}
+
} // anonymous namespace
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
@@ -2534,3 +2606,5 @@
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
+
+ANGLE_INSTANTIATE_TEST(WebGLGLSLTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());