ES31 program query: support TRANSFORM_FEEDBACK_VARYING

TRANSFORM_FEEDBACK_VARYING corresponds to the set of output variables
in the last non-fragment stage of program that would be captured when
transform feedback is active. The resources enumerated by this query
are listed as specified by the most recent call to
TransformFeedbackVaryings before the last call to LinkProgram.
This mainly collects these resources for query.

BUG=angleproject:1920
TEST=angle_end2end_tests:ProgramInterfaceTest*
     dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.*

Change-Id: I0655b12c6d82cef1b44d4ca57ea55bb60d1f78fb
Reviewed-on: https://chromium-review.googlesource.com/770450
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/queryutils.cpp b/src/libANGLE/queryutils.cpp
index 020db1a..eb97859 100644
--- a/src/libANGLE/queryutils.cpp
+++ b/src/libANGLE/queryutils.cpp
@@ -512,6 +512,28 @@
     }
 }
 
+GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
+                                                  GLuint index,
+                                                  const GLenum prop)
+{
+    const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
+    switch (prop)
+    {
+        case GL_TYPE:
+            return clampCast<GLint>(tfVariable.type);
+
+        case GL_ARRAY_SIZE:
+            return clampCast<GLint>(tfVariable.size());
+
+        case GL_NAME_LENGTH:
+            return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
+
+        default:
+            UNREACHABLE();
+            return GL_INVALID_VALUE;
+    }
+}
+
 GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
 {
     switch (programInterface)
@@ -537,10 +559,8 @@
         case GL_SHADER_STORAGE_BLOCK:
             return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_TRANSFORM_FEEDBACK_VARYING:
-            UNIMPLEMENTED();
-            return 0;
+            return clampCast<GLint>(program->getTransformFeedbackVaryingCount());
 
         default:
             UNREACHABLE();
@@ -592,10 +612,9 @@
                 FindMaxSize(program->getState().getShaderStorageBlocks(), &InterfaceBlock::name);
             break;
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_TRANSFORM_FEEDBACK_VARYING:
-            UNIMPLEMENTED();
-            return 0;
+            maxNameLength = clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength() - 1);
+            break;
 
         default:
             UNREACHABLE();
@@ -968,7 +987,7 @@
             *params = program->getTransformFeedbackBufferMode();
             break;
         case GL_TRANSFORM_FEEDBACK_VARYINGS:
-            *params = program->getTransformFeedbackVaryingCount();
+            *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
             break;
         case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
             *params = program->getTransformFeedbackVaryingMaxLength();
@@ -1471,10 +1490,8 @@
         case GL_UNIFORM_BLOCK:
             return program->getUniformBlockIndex(name);
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_TRANSFORM_FEEDBACK_VARYING:
-            UNIMPLEMENTED();
-            return GL_INVALID_INDEX;
+            return program->getTransformFeedbackVaryingResourceIndex(name);
 
         default:
             UNREACHABLE();
@@ -1515,9 +1532,8 @@
             program->getActiveUniformBlockName(index, bufSize, length, name);
             break;
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_TRANSFORM_FEEDBACK_VARYING:
-            UNIMPLEMENTED();
+            program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
             break;
 
         default:
@@ -1602,10 +1618,10 @@
                 GetAtomicCounterBufferResourceProperty(program, index, props[i], params, bufSize,
                                                        &pos);
                 break;
-            // TODO(jie.a.chen@intel.com): more interfaces.
+
             case GL_TRANSFORM_FEEDBACK_VARYING:
-                UNIMPLEMENTED();
-                params[i] = GL_INVALID_VALUE;
+                params[i] = GetTransformFeedbackVaryingResourceProperty(program, index, props[i]);
+                ++pos;
                 break;
 
             default: