D3D9: Improve varying packing failure mode.
D3D9 has a special limitation on varying packing, where each
variable takes up a full register width, and cannot share space
with other packed varyings.
A bug was counting registers incorrectly on D3D9. Fix this by
introducing a new limitation exposed to the ANGLE front-end via
the gl::Limitations structure. Now varying packing will fail
correctly in the ANGLE linking front-end with a more descriptive
error message, as such:
"Could not pack varying blah"
"Note: Additional non-conformant packing restrictions are enforced on D3D9."
Also change the packing so that input built-in variables are
counted towards varying limits (e.g. gl_PointSize), except for
gl_Position. On D3D9 we don't pack gl_PointSize, since it is
used in a special extra PSIZE register.
Also update some tests to be more robust.
Bug: chromium:804799
Change-Id: I9027266a8b66a28626f038f259bff42ebf09dcd2
Reviewed-on: https://chromium-review.googlesource.com/889898
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index 9066773..c736579 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -1297,29 +1297,62 @@
VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
}
-TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
+// Verify we can pack registers with one builtin varying.
+TEST_P(GLSLTest, MaxVaryingVec4_OneBuiltin)
{
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
- // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
+ // Generate shader code that uses gl_FragCoord.
+ VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 1, 0, true, false, false, true);
+}
+
+// Verify we can pack registers with two builtin varyings.
+TEST_P(GLSLTest, MaxVaryingVec4_TwoBuiltins)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ // Generate shader code that uses gl_FragCoord and gl_PointCoord.
VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
}
-TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
+// Verify we can pack registers with three builtin varyings.
+TEST_P(GLSLTest, MaxVaryingVec4_ThreeBuiltins)
{
- // TODO(geofflang): Figure out why this fails on OpenGL AMD (http://anglebug.com/1291)
- if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
- {
- std::cout << "Test disabled on OpenGL." << std::endl;
- return;
- }
-
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
// Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
- VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
+ VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 3, 0, true, true, true, true);
+}
+
+// This covers a problematic case in D3D9 - we are limited by the number of available semantics,
+// rather than total register use.
+TEST_P(GLSLTest, MaxVaryingsSpecialCases)
+{
+ ANGLE_SKIP_TEST_IF(!IsD3D9());
+
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ VaryingTestBase(maxVaryings, 0, 0, 0, 0, 0, 0, 0, true, false, false, false);
+ VaryingTestBase(maxVaryings - 1, 0, 0, 0, 0, 0, 0, 0, true, true, false, false);
+ VaryingTestBase(maxVaryings - 2, 0, 0, 0, 0, 0, 0, 0, true, true, false, true);
+
+ // Special case for gl_PointSize: we get it for free on D3D9.
+ VaryingTestBase(maxVaryings - 2, 0, 0, 0, 0, 0, 0, 0, true, true, true, true);
+}
+
+// This covers a problematic case in D3D9 - we are limited by the number of available semantics,
+// rather than total register use.
+TEST_P(GLSLTest, MaxMinusTwoVaryingVec2PlusOneSpecialVariable)
+{
+ GLint maxVaryings = 0;
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+ // Generate shader code that uses gl_FragCoord.
+ VaryingTestBase(0, 0, maxVaryings, 0, 0, 0, 0, 0, true, false, false, !IsD3D9());
}
TEST_P(GLSLTest, MaxVaryingVec3)
@@ -1338,45 +1371,27 @@
VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
}
-// Disabled because of a failure in D3D9
+// Only fails on D3D9 because of packing limitations.
TEST_P(GLSLTest, MaxVaryingVec3AndOneFloat)
{
- if (IsD3D9())
- {
- std::cout << "Test disabled on D3D9." << std::endl;
- return;
- }
-
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
- VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
+ VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, !IsD3D9());
}
-// Disabled because of a failure in D3D9
+// Only fails on D3D9 because of packing limitations.
TEST_P(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
{
- if (IsD3D9())
- {
- std::cout << "Test disabled on D3D9." << std::endl;
- return;
- }
-
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
- VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
+ VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, !IsD3D9());
}
-// Disabled because of a failure in D3D9
+// Only fails on D3D9 because of packing limitations.
TEST_P(GLSLTest, TwiceMaxVaryingVec2)
{
- if (IsD3D9())
- {
- std::cout << "Test disabled on D3D9." << std::endl;
- return;
- }
-
if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
{
// TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
@@ -1397,7 +1412,7 @@
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
- VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
+ VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, !IsD3D9());
}
// Disabled because of a failure in D3D9