ES31: Impl program pipeline object management entries for GL backend.

The program pipeline object management entries are:
GenProgramPipelines
DeleteProgramPipelines
BindProgramPipeline
IsProgramPipeline

BUG:angleproject:2123

Change-Id: I114d054b90caf2ee3f9befef7439552a1c309bc4
Reviewed-on: https://chromium-review.googlesource.com/629978
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/tests/gl_tests/ProgramPipelineTest.cpp b/src/tests/gl_tests/ProgramPipelineTest.cpp
new file mode 100644
index 0000000..059b503
--- /dev/null
+++ b/src/tests/gl_tests/ProgramPipelineTest.cpp
@@ -0,0 +1,116 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ProgramPipelineTest:
+//   Various tests related to Program Pipeline.
+//
+
+#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
+
+using namespace angle;
+
+namespace
+{
+
+class ProgramPipelineTest : public ANGLETest
+{
+  protected:
+    ProgramPipelineTest()
+    {
+        setWindowWidth(64);
+        setWindowHeight(64);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+};
+
+// Verify that program pipeline is not supported in version lower than ES31.
+TEST_P(ProgramPipelineTest, GenerateProgramPipelineObject)
+{
+    GLuint pipeline;
+    glGenProgramPipelines(1, &pipeline);
+    if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
+    {
+        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+    }
+    else
+    {
+        EXPECT_GL_NO_ERROR();
+
+        glDeleteProgramPipelines(1, &pipeline);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+class ProgramPipelineTest31 : public ProgramPipelineTest
+{
+};
+
+// Test generate or delete program pipeline.
+TEST_P(ProgramPipelineTest31, GenOrDeleteProgramPipelineTest)
+{
+    GLuint pipeline;
+    glGenProgramPipelines(-1, &pipeline);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+    glGenProgramPipelines(0, &pipeline);
+    EXPECT_GL_NO_ERROR();
+
+    glDeleteProgramPipelines(-1, &pipeline);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+    glDeleteProgramPipelines(0, &pipeline);
+    EXPECT_GL_NO_ERROR();
+}
+
+// Test BindProgramPipeline.
+TEST_P(ProgramPipelineTest31, BindProgramPipelineTest)
+{
+    glBindProgramPipeline(0);
+    EXPECT_GL_NO_ERROR();
+
+    glBindProgramPipeline(2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    GLuint pipeline;
+    glGenProgramPipelines(1, &pipeline);
+    glBindProgramPipeline(pipeline);
+    EXPECT_GL_NO_ERROR();
+
+    glDeleteProgramPipelines(1, &pipeline);
+    glBindProgramPipeline(pipeline);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// Test IsProgramPipeline
+TEST_P(ProgramPipelineTest31, IsProgramPipelineTest)
+{
+    EXPECT_EQ(GL_FALSE, glIsProgramPipeline(0));
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_EQ(GL_FALSE, glIsProgramPipeline(2));
+    EXPECT_GL_NO_ERROR();
+
+    GLuint pipeline;
+    glGenProgramPipelines(1, &pipeline);
+    glBindProgramPipeline(pipeline);
+    EXPECT_EQ(GL_TRUE, glIsProgramPipeline(pipeline));
+    EXPECT_GL_NO_ERROR();
+
+    glBindProgramPipeline(0);
+    glDeleteProgramPipelines(1, &pipeline);
+    EXPECT_EQ(GL_FALSE, glIsProgramPipeline(pipeline));
+    EXPECT_GL_NO_ERROR();
+}
+
+ANGLE_INSTANTIATE_TEST(ProgramPipelineTest,
+                       ES3_OPENGL(),
+                       ES3_OPENGLES(),
+                       ES31_OPENGL(),
+                       ES31_OPENGLES());
+ANGLE_INSTANTIATE_TEST(ProgramPipelineTest31, ES31_OPENGL(), ES31_OPENGLES());
+
+}  // namespace