ES31: Add GL_SHADER_STORAGE_BUFFER_BINDING binding point

The affected APIs are below:
getIntegeri_v getInteger64i_v BindBuffer BindBufferBase BindBufferRange

BUG=angleproject:1951
TEST=dEQP-GLES31.functional.state_query.integer.shader_storage_buffer_binding_*
     dEQP-GLES31.functional.state_query.indexed.shader_storage_buffer_*

Change-Id: Ief7186b2ebe305f14e620c31841bc244f84429a5
Reviewed-on: https://chromium-review.googlesource.com/459093
Reviewed-by: Yunchao He <yunchao.he@intel.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index f2c23f6..ab813ec 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -179,6 +179,7 @@
         mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);
 
         mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
+        mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
     }
     if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
     {
@@ -270,6 +271,12 @@
         buf.set(nullptr);
     }
 
+    mGenericShaderStorageBuffer.set(nullptr);
+    for (auto &buf : mShaderStorageBuffers)
+    {
+        buf.set(nullptr);
+    }
+
     mProgram = NULL;
 
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
@@ -1230,6 +1237,26 @@
     return mAtomicCounterBuffers[index];
 }
 
+void State::setGenericShaderStorageBufferBinding(Buffer *buffer)
+{
+    mGenericShaderStorageBuffer.set(buffer);
+}
+
+void State::setIndexedShaderStorageBufferBinding(GLuint index,
+                                                 Buffer *buffer,
+                                                 GLintptr offset,
+                                                 GLsizeiptr size)
+{
+    ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+    mShaderStorageBuffers[index].set(buffer, offset, size);
+}
+
+const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
+{
+    ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+    return mShaderStorageBuffers[index];
+}
+
 void State::setCopyReadBufferBinding(Buffer *buffer)
 {
     mCopyReadBuffer.set(buffer);
@@ -1267,8 +1294,7 @@
       case GL_ATOMIC_COUNTER_BUFFER:
           return mGenericAtomicCounterBuffer.get();
       case GL_SHADER_STORAGE_BUFFER:
-          UNIMPLEMENTED();
-          return nullptr;
+          return mGenericShaderStorageBuffer.get();
       case GL_DRAW_INDIRECT_BUFFER:
           return mDrawIndirectBuffer.get();
       default: UNREACHABLE();            return NULL;
@@ -1277,10 +1303,10 @@
 
 void State::detachBuffer(GLuint bufferName)
 {
-    BindingPointer<Buffer> *buffers[] = {&mArrayBuffer,        &mGenericAtomicCounterBuffer,
-                                         &mCopyReadBuffer,     &mCopyWriteBuffer,
-                                         &mDrawIndirectBuffer, &mPack.pixelBuffer,
-                                         &mUnpack.pixelBuffer, &mGenericUniformBuffer};
+    BindingPointer<Buffer> *buffers[] = {
+        &mArrayBuffer,        &mGenericAtomicCounterBuffer, &mCopyReadBuffer,
+        &mCopyWriteBuffer,    &mDrawIndirectBuffer,         &mPack.pixelBuffer,
+        &mUnpack.pixelBuffer, &mGenericUniformBuffer,       &mGenericShaderStorageBuffer};
     for (auto buffer : buffers)
     {
         if (buffer->id() == bufferName)
@@ -1937,6 +1963,9 @@
       case GL_ATOMIC_COUNTER_BUFFER_BINDING:
           *params = mGenericAtomicCounterBuffer.id();
           break;
+      case GL_SHADER_STORAGE_BUFFER_BINDING:
+          *params = mGenericShaderStorageBuffer.id();
+          break;
       default:
         UNREACHABLE();
         break;
@@ -1975,6 +2004,10 @@
           ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
           *data = mAtomicCounterBuffers[index].id();
           break;
+      case GL_SHADER_STORAGE_BUFFER_BINDING:
+          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+          *data = mShaderStorageBuffers[index].id();
+          break;
       case GL_VERTEX_BINDING_BUFFER:
           ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
           *data = mVertexArray->getVertexBinding(index).buffer.id();
@@ -2025,6 +2058,14 @@
           ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
           *data = mAtomicCounterBuffers[index].getSize();
           break;
+      case GL_SHADER_STORAGE_BUFFER_START:
+          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+          *data = mShaderStorageBuffers[index].getOffset();
+          break;
+      case GL_SHADER_STORAGE_BUFFER_SIZE:
+          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+          *data = mShaderStorageBuffers[index].getSize();
+          break;
       default:
           UNREACHABLE();
           break;