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/src/libANGLE/Shader.cpp b/src/libANGLE/Shader.cpp
index d732b40..5d0a258 100644
--- a/src/libANGLE/Shader.cpp
+++ b/src/libANGLE/Shader.cpp
@@ -101,10 +101,7 @@
       mShaderType(shaderType),
       mShaderVersion(100),
       mNumViews(-1),
-      mGeometryShaderInputPrimitiveType(GL_INVALID_VALUE),
-      mGeometryShaderOutputPrimitiveType(GL_INVALID_VALUE),
       mGeometryShaderInvocations(1),
-      mGeometryShaderMaxVertices(-1),
       mCompileStatus(CompileStatus::NOT_COMPILED)
 {
     mLocalSize.fill(-1);
@@ -302,10 +299,10 @@
     mState.mActiveAttributes.clear();
     mState.mActiveOutputVariables.clear();
     mState.mNumViews = -1;
-    mState.mGeometryShaderInputPrimitiveType  = GL_INVALID_VALUE;
-    mState.mGeometryShaderOutputPrimitiveType = GL_INVALID_VALUE;
-    mState.mGeometryShaderInvocations         = 1;
-    mState.mGeometryShaderMaxVertices         = -1;
+    mState.mGeometryShaderInputPrimitiveType.reset();
+    mState.mGeometryShaderOutputPrimitiveType.reset();
+    mState.mGeometryShaderMaxVertices.reset();
+    mState.mGeometryShaderInvocations = 1;
 
     mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
     mBoundCompiler.set(context, context->getCompiler());
@@ -426,12 +423,22 @@
             mState.mInputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
             mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
 
-            mState.mGeometryShaderInputPrimitiveType =
-                sh::GetGeometryShaderInputPrimitiveType(compilerHandle);
-            mState.mGeometryShaderOutputPrimitiveType =
-                sh::GetGeometryShaderOutputPrimitiveType(compilerHandle);
+            if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle))
+            {
+                mState.mGeometryShaderInputPrimitiveType =
+                    sh::GetGeometryShaderInputPrimitiveType(compilerHandle);
+            }
+            if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle))
+            {
+                mState.mGeometryShaderOutputPrimitiveType =
+                    sh::GetGeometryShaderOutputPrimitiveType(compilerHandle);
+            }
+            if (sh::HasValidGeometryShaderMaxVertices(compilerHandle))
+            {
+                mState.mGeometryShaderMaxVertices =
+                    sh::GetGeometryShaderMaxVertices(compilerHandle);
+            }
             mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
-            mState.mGeometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle);
             break;
         }
         default:
@@ -580,6 +587,30 @@
     return mState.mNumViews;
 }
 
+Optional<GLenum> Shader::getGeometryShaderInputPrimitiveType(const Context *context)
+{
+    resolveCompile(context);
+    return mState.mGeometryShaderInputPrimitiveType;
+}
+
+Optional<GLenum> Shader::getGeometryShaderOutputPrimitiveType(const Context *context)
+{
+    resolveCompile(context);
+    return mState.mGeometryShaderOutputPrimitiveType;
+}
+
+int Shader::getGeometryShaderInvocations(const Context *context)
+{
+    resolveCompile(context);
+    return mState.mGeometryShaderInvocations;
+}
+
+Optional<GLint> Shader::getGeometryShaderMaxVertices(const Context *context)
+{
+    resolveCompile(context);
+    return mState.mGeometryShaderMaxVertices;
+}
+
 const std::string &Shader::getCompilerResourcesString() const
 {
     ASSERT(mBoundCompiler.get());