Generate an error if no XFB varyings are in use
GLES specifies an error if BeginTransformFeedback is called when no
binding points would be used.
BUG=angleproject:2184
TEST=angle_end2end_tests
Change-Id: Ie4489b5ba63885e718dafdcdaacc02b603959be3
Reviewed-on: https://chromium-review.googlesource.com/719136
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/libANGLE/ErrorStrings.h b/src/libANGLE/ErrorStrings.h
index 9129f25..e056093 100644
--- a/src/libANGLE/ErrorStrings.h
+++ b/src/libANGLE/ErrorStrings.h
@@ -125,6 +125,8 @@
ERRMSG(NegativeStart, "Cannot have negative start.");
ERRMSG(NegativeStride, "Cannot have negative stride.");
ERRMSG(NoSuchPath, "No such path object.");
+ERRMSG(NoTransformFeedbackOutputVariables,
+ "The active program has specified no output variables to record.");
ERRMSG(NoZeroDivisor, "At least one enabled attribute must have a divisor of zero.");
ERRMSG(ObjectNotGenerated, "Object cannot be used because it has not been generated.");
ERRMSG(OffsetMustBeMultipleOfType, "Offset must be a multiple of the passed in datatype.");
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index 4f9c1e1..37a76d3 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -2139,6 +2139,20 @@
}
}
+ auto program = context->getGLState().getProgram();
+
+ if (!program)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
+ return false;
+ }
+
+ if (program->getTransformFeedbackVaryingCount() == 0)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoTransformFeedbackOutputVariables);
+ return false;
+ }
+
return true;
}
diff --git a/src/tests/gl_tests/TransformFeedbackTest.cpp b/src/tests/gl_tests/TransformFeedbackTest.cpp
index 47e17c6..dc7df16 100644
--- a/src/tests/gl_tests/TransformFeedbackTest.cpp
+++ b/src/tests/gl_tests/TransformFeedbackTest.cpp
@@ -1321,6 +1321,52 @@
ASSERT_GL_NO_ERROR();
}
+// Test that calling BeginTransformFeedback when no program is currentwill generate an
+// INVALID_OPERATION error.
+TEST_P(TransformFeedbackTest, NoCurrentProgram)
+{
+ glUseProgram(0);
+ glBeginTransformFeedback(GL_TRIANGLES);
+
+ // GLES 3.0.5 section 2.15.2: "The error INVALID_OPERATION is also generated by
+ // BeginTransformFeedback if no binding points would be used, either because no program object
+ // is active or because the active program object has specified no output variables to record."
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// Test that calling BeginTransformFeedback when no transform feedback varyings are in use will
+// generate an INVALID_OPERATION error.
+TEST_P(TransformFeedbackTest, NoTransformFeedbackVaryingsInUse)
+{
+ const std::string &vertexShaderSource =
+ "#version 300 es\n"
+ "in vec4 a_position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = a_position;\n"
+ "}\n";
+
+ const std::string &fragmentShaderSource =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(0);\n"
+ "}\n";
+
+ ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
+
+ glUseProgram(program);
+ glBeginTransformFeedback(GL_TRIANGLES);
+
+ // GLES 3.0.5 section 2.15.2: "The error INVALID_OPERATION is also generated by
+ // BeginTransformFeedback if no binding points would be used, either because no program object
+ // is active or because the active program object has specified no output variables to record."
+
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(TransformFeedbackTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());