ES31: Add glGetProgramInterfaceiv API

Add API entry and validation checks(GLES 3.1 section 7.3).
Add the first 4 interfaces(PROGRAM_INPUT, PROGRAM_OUTPUT,
UNIFORM and UNIFORM_BLOCK) implementation.

BUG=angleproject:1920
TEST=angle_end2end_tests:ProgramInterfaceTestES31.*

Change-Id: Iab80ba332e2a5e2b3e677039359e60a420e3d6b0
Reviewed-on: https://chromium-review.googlesource.com/642729
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/validationES31.cpp b/src/libANGLE/validationES31.cpp
index 09719ce..cbf44e7 100644
--- a/src/libANGLE/validationES31.cpp
+++ b/src/libANGLE/validationES31.cpp
@@ -1153,7 +1153,7 @@
 {
     if (context->getClientVersion() < ES_3_1)
     {
-        context->handleError(InvalidOperation() << "Context does not support GLES3.1.");
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
@@ -1198,4 +1198,67 @@
     return true;
 }
 
+bool ValidateGetProgramInterfaceiv(Context *context,
+                                   GLuint program,
+                                   GLenum programInterface,
+                                   GLenum pname,
+                                   GLint *params)
+{
+    if (context->getClientVersion() < ES_3_1)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
+        return false;
+    }
+
+    Program *programObject = GetValidProgram(context, program);
+    if (programObject == nullptr)
+    {
+        return false;
+    }
+
+    if (!ValidateProgramInterface(programInterface))
+    {
+        context->handleError(InvalidEnum() << "Invalid program interface.");
+        return false;
+    }
+
+    switch (pname)
+    {
+        case GL_ACTIVE_RESOURCES:
+        case GL_MAX_NAME_LENGTH:
+        case GL_MAX_NUM_ACTIVE_VARIABLES:
+            break;
+
+        default:
+            context->handleError(InvalidEnum() << "Unknown property of program interface.");
+            return false;
+    }
+
+    if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
+    {
+        context->handleError(InvalidOperation()
+                             << "Active atomic counter resources are not assigned name strings.");
+        return false;
+    }
+
+    if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
+    {
+        switch (programInterface)
+        {
+            case GL_ATOMIC_COUNTER_BUFFER:
+            case GL_SHADER_STORAGE_BLOCK:
+            case GL_UNIFORM_BLOCK:
+                break;
+
+            default:
+                context->handleError(
+                    InvalidOperation()
+                    << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
+                return false;
+        }
+    }
+
+    return true;
+}
+
 }  // namespace gl