ES31: Add link validation on geometry shader itself

This patch intends to support program link validation on geometry
shader itself. A link error should occur when linking a program with
a geometry shader that lacks input primitive or output primitive or
the declaration of 'max_vertices'.

This patch also adds the support of linking a program with geometry
shader in angle_end2end_tests.

BUG=angleproject:1941
TEST=angle_end2end_tests
     dEQP-GLES31.functional.shaders.linkage.es31.geometry.varying.rules.unspecified_*

Change-Id: I25fb08514753102f5dd3ab86211c05d2ca4fd185
Reviewed-on: https://chromium-review.googlesource.com/898842
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/util/shader_utils.cpp b/util/shader_utils.cpp
index 3b6dffa..a9962dd 100644
--- a/util/shader_utils.cpp
+++ b/util/shader_utils.cpp
@@ -122,6 +122,17 @@
     const std::vector<std::string> &transformFeedbackVaryings,
     GLenum bufferMode)
 {
+    return CompileProgramWithGSAndTransformFeedback(vsSource, "", fsSource,
+                                                    transformFeedbackVaryings, bufferMode);
+}
+
+GLuint CompileProgramWithGSAndTransformFeedback(
+    const std::string &vsSource,
+    const std::string &gsSource,
+    const std::string &fsSource,
+    const std::vector<std::string> &transformFeedbackVaryings,
+    GLenum bufferMode)
+{
     GLuint program = glCreateProgram();
 
     GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
@@ -141,6 +152,21 @@
     glAttachShader(program, fs);
     glDeleteShader(fs);
 
+    if (!gsSource.empty())
+    {
+        GLuint gs = CompileShader(GL_GEOMETRY_SHADER_EXT, gsSource);
+        if (gs == 0)
+        {
+            glDeleteShader(vs);
+            glDeleteShader(fs);
+            glDeleteProgram(program);
+            return 0;
+        }
+
+        glAttachShader(program, gs);
+        glDeleteShader(gs);
+    }
+
     if (transformFeedbackVaryings.size() > 0)
     {
         std::vector<const char *> constCharTFVaryings;
@@ -161,8 +187,16 @@
 
 GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource)
 {
+    return CompileProgramWithGS(vsSource, "", fsSource);
+}
+
+GLuint CompileProgramWithGS(const std::string &vsSource,
+                            const std::string &gsSource,
+                            const std::string &fsSource)
+{
     std::vector<std::string> emptyVector;
-    return CompileProgramWithTransformFeedback(vsSource, fsSource, emptyVector, GL_NONE);
+    return CompileProgramWithGSAndTransformFeedback(vsSource, gsSource, fsSource, emptyVector,
+                                                    GL_NONE);
 }
 
 GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)