diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp index 0d2bf2a565..ff739e7e50 100644 --- a/src/libANGLE/renderer/gl/StateManagerGL.cpp +++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp @@ -2893,9 +2893,20 @@ void StateManagerGL::syncTransformFeedbackState(const gl::Context *context) TransformFeedbackGL *transformFeedbackGL = GetImplAs(transformFeedback); bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID()); + // TransformFeedbackGL::syncActiveState(true) rebinds the cached + // begin-time program so the native glBeginTransformFeedback links the + // correct varyings. Because begin() is lazy, this runs *inside* + // syncState after DIRTY_BIT_PROGRAM_BINDING has already bound the + // front-end program for the current draw, so the override must not + // outlive this call. Restore after syncPausedState so that, in the + // active+paused case (the only one where the two programs may differ), + // the native glPauseTransformFeedback has already run and glUseProgram + // is legal again. + const GLuint previousProgram = mProgram; transformFeedbackGL->syncActiveState(context, transformFeedback->isActive(), transformFeedback->getPrimitiveMode()); transformFeedbackGL->syncPausedState(transformFeedback->isPaused()); + useProgram(previousProgram); mCurrentTransformFeedback = transformFeedbackGL; } else