ES31: Implement creation and attaching geometry shader on OpenGL

This patch intends to implement the creation of a geometry shader
and attaching a geometry shader to a program on OpenGL back-ends.

This patch also adds all geometry shader related dEQP-GLES31 test
failures to deqp_gles31_test_expectations.txt.

BUG=angleproject:1941
TEST=angle_end2end_tests

Change-Id: Ib0b497030255b15dacd967e48bc59eef0009af46
Reviewed-on: https://chromium-review.googlesource.com/757979
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index ce40175..8296d50 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -430,6 +430,7 @@
       mAttachedFragmentShader(nullptr),
       mAttachedVertexShader(nullptr),
       mAttachedComputeShader(nullptr),
+      mAttachedGeometryShader(nullptr),
       mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS),
       mMaxActiveAttribLocation(0),
       mSamplerUniformRange(0, 0),
@@ -443,7 +444,8 @@
 
 ProgramState::~ProgramState()
 {
-    ASSERT(!mAttachedVertexShader && !mAttachedFragmentShader && !mAttachedComputeShader);
+    ASSERT(!mAttachedVertexShader && !mAttachedFragmentShader && !mAttachedComputeShader &&
+           !mAttachedGeometryShader);
 }
 
 const std::string &ProgramState::getLabel()
@@ -541,10 +543,16 @@
         mState.mAttachedComputeShader = nullptr;
     }
 
+    if (mState.mAttachedGeometryShader != nullptr)
+    {
+        mState.mAttachedGeometryShader->release(context);
+        mState.mAttachedGeometryShader = nullptr;
+    }
+
     mProgram->destroy(context);
 
     ASSERT(!mState.mAttachedVertexShader && !mState.mAttachedFragmentShader &&
-           !mState.mAttachedComputeShader);
+           !mState.mAttachedComputeShader && !mState.mAttachedGeometryShader);
     SafeDelete(mProgram);
 
     delete this;
@@ -585,6 +593,13 @@
             mState.mAttachedComputeShader->addRef();
             break;
         }
+        case GL_GEOMETRY_SHADER_EXT:
+        {
+            ASSERT(!mState.mAttachedGeometryShader);
+            mState.mAttachedGeometryShader = shader;
+            mState.mAttachedGeometryShader->addRef();
+            break;
+        }
         default:
             UNREACHABLE();
     }
@@ -615,6 +630,13 @@
             mState.mAttachedComputeShader = nullptr;
             break;
         }
+        case GL_GEOMETRY_SHADER_EXT:
+        {
+            ASSERT(mState.mAttachedGeometryShader == shader);
+            shader->release(context);
+            mState.mAttachedGeometryShader = nullptr;
+            break;
+        }
         default:
             UNREACHABLE();
     }
@@ -623,7 +645,7 @@
 int Program::getAttachedShadersCount() const
 {
     return (mState.mAttachedVertexShader ? 1 : 0) + (mState.mAttachedFragmentShader ? 1 : 0) +
-           (mState.mAttachedComputeShader ? 1 : 0);
+           (mState.mAttachedComputeShader ? 1 : 0) + (mState.mAttachedGeometryShader ? 1 : 0);
 }
 
 void Program::bindAttributeLocation(GLuint index, const char *name)
@@ -1119,6 +1141,15 @@
         }
     }
 
+    if (mState.mAttachedGeometryShader)
+    {
+        if (total < maxCount)
+        {
+            shaders[total] = mState.mAttachedGeometryShader->getHandle();
+            total++;
+        }
+    }
+
     if (count)
     {
         *count = total;