ES31: Add glGetProgramResourceName API

Add API entry and validation checks(GLES 3.1 section 7.3).
Add the first 2 interfaces(PROGRAM_INPUT and PROGRAM_OUTPUT) implementation.

BUG=angleproject:1920

Change-Id: Ide7d5ad40a611a091c3dffab47fd31da57b69f1d
Reviewed-on: https://chromium-review.googlesource.com/457523
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/validationES31.cpp b/src/libANGLE/validationES31.cpp
index 005d491..4176e82 100644
--- a/src/libANGLE/validationES31.cpp
+++ b/src/libANGLE/validationES31.cpp
@@ -41,6 +41,33 @@
     }
 }
 
+bool ValidateProgramResourceIndex(const Program *programObject,
+                                  GLenum programInterface,
+                                  GLuint index)
+{
+    switch (programInterface)
+    {
+        case GL_PROGRAM_INPUT:
+            return (index < static_cast<GLuint>(programObject->getActiveAttributeCount()));
+
+        case GL_PROGRAM_OUTPUT:
+            return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
+
+        // TODO(Jie): more interfaces.
+        case GL_UNIFORM:
+        case GL_UNIFORM_BLOCK:
+        case GL_TRANSFORM_FEEDBACK_VARYING:
+        case GL_BUFFER_VARIABLE:
+        case GL_SHADER_STORAGE_BLOCK:
+            UNIMPLEMENTED();
+            return false;
+
+        default:
+            UNREACHABLE();
+            return false;
+    }
+}
+
 }  // anonymous namespace
 
 bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data)
@@ -700,4 +727,46 @@
     return true;
 }
 
+bool ValidateGetProgramResourceName(Context *context,
+                                    GLuint program,
+                                    GLenum programInterface,
+                                    GLuint index,
+                                    GLsizei bufSize,
+                                    GLsizei *length,
+                                    GLchar *name)
+{
+    if (context->getClientVersion() < ES_3_1)
+    {
+        context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.1."));
+        return false;
+    }
+
+    Program *programObject = GetValidProgram(context, program);
+    if (programObject == nullptr)
+    {
+        return false;
+    }
+
+    if (!ValidateNamedProgramInterface(programInterface))
+    {
+        context->handleError(
+            Error(GL_INVALID_ENUM, "Invalid program interface: 0x%X", programInterface));
+        return false;
+    }
+
+    if (!ValidateProgramResourceIndex(programObject, programInterface, index))
+    {
+        context->handleError(Error(GL_INVALID_VALUE, "Invalid index: %d", index));
+        return false;
+    }
+
+    if (bufSize < 0)
+    {
+        context->handleError(Error(GL_INVALID_VALUE, "Invalid bufSize: %d", bufSize));
+        return false;
+    }
+
+    return true;
+}
+
 }  // namespace gl