ES31: Implement Vertex Attrib Binding entry points

This patch intends to implement all entry points related to Vertex
Attrib Binding.

(1) Add entry points and validation code on following APIs:
   - VertexAttribFormat
   - VertexAttribIFormat
   - VertexAttribBinding
   - BindVertexBuffer
   - VertexBindingDivisor
(2) Add queries on following parameters:
   - VERTEX_ATTRIB_BINDING
   - VERTEX_ATTRIB_RELATIVE_OFFSET
   - VERTEX_BINDING_DIVISOR
   - VERTEX_BINDING_OFFSET
   - VERTEX_BINDING_STRIDE
   - VERTEX_BINDING_BUFFER

BUG=angleproject:1593

TEST=angle_end2end_tests
TEST=angle_unittests
TEST=dEQP-GLES31.functional.state_query.integer.max_vertex_attrib_relative_offset_*
TEST=dEQP-GLES31.functional.state_query.integer.max_vertex_attrib_bindings_*
TEST=dEQP-GLES31.functional.state_query.integer.max_vertex_attrib_stride_*
TEST=dEQP-GLES31.functional.state_query.vertex_attribute_binding.*
TEST=dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.vertex_attrib_pointer
TEST=dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.vertex_attrib_format
TEST=dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.vertex_attrib_i_format

Change-Id: I4b477a82df6aad89b89b088580a06d66963e6666
Reviewed-on: https://chromium-review.googlesource.com/446124
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index c47824c..f2c23f6 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -1041,6 +1041,45 @@
     return false;
 }
 
+void State::setElementArrayBuffer(Buffer *buffer)
+{
+    getVertexArray()->setElementArrayBuffer(buffer);
+    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+void State::bindVertexBuffer(GLuint bindingIndex,
+                             Buffer *boundBuffer,
+                             GLintptr offset,
+                             GLsizei stride)
+{
+    getVertexArray()->bindVertexBuffer(bindingIndex, boundBuffer, offset, stride);
+    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+void State::setVertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
+{
+    getVertexArray()->setVertexAttribBinding(attribIndex, bindingIndex);
+    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+void State::setVertexAttribFormat(GLuint attribIndex,
+                                  GLint size,
+                                  GLenum type,
+                                  bool normalized,
+                                  bool pureInteger,
+                                  GLuint relativeOffset)
+{
+    getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
+                                            relativeOffset);
+    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+void State::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
+{
+    getVertexArray()->setVertexBindingDivisor(bindingIndex, divisor);
+    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
 void State::setProgram(const Context *context, Program *newProgram)
 {
     if (mProgram != newProgram)
@@ -1936,6 +1975,22 @@
           ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
           *data = mAtomicCounterBuffers[index].id();
           break;
+      case GL_VERTEX_BINDING_BUFFER:
+          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+          *data = mVertexArray->getVertexBinding(index).buffer.id();
+          break;
+      case GL_VERTEX_BINDING_DIVISOR:
+          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+          *data = mVertexArray->getVertexBinding(index).divisor;
+          break;
+      case GL_VERTEX_BINDING_OFFSET:
+          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+          *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).offset);
+          break;
+      case GL_VERTEX_BINDING_STRIDE:
+          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+          *data = mVertexArray->getVertexBinding(index).stride;
+          break;
       default:
           UNREACHABLE();
           break;