ES31: Implement Vertex Attrib Binding on D3D11

This patch implements Vertex Attrib Binding on D3D11 and enables all
the test cases related to Vertex Attrib Binding on D3D11 back-ends.

On D3D11 back-ends the information in both GL vertex attributes and
bindings should be updated together. When a binding is dirty, we need
to find out and update all the attributes that are using this binding.
To speed up this process, this patch adds a map from each binding to
all the attrib indexes that are using this binding. This map may be
updated when VertexAttribBinding is implicitly or explicitly called.
With this map we can easily get all the attributes that should be
updated with the current dirty binding.

This patch also removes some unused variables in VertexArray11.cpp.

BUG=angleproject:2700
TEST=dEQP-GLES31.functional.vertex_attribute_binding.*
     angle_end2end_tests

Change-Id: I9a28ec357fd3aba835812cecc410cfa4e3734f0c
Reviewed-on: https://chromium-review.googlesource.com/1048980
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/VertexArray.cpp b/src/libANGLE/VertexArray.cpp
index 4cc474d..2cd9b49 100644
--- a/src/libANGLE/VertexArray.cpp
+++ b/src/libANGLE/VertexArray.cpp
@@ -24,6 +24,7 @@
     for (size_t i = 0; i < maxAttribs; i++)
     {
         mVertexAttributes.emplace_back(static_cast<GLuint>(i));
+        mBindingToAttributeMasks[i].set(i);
     }
 }
 
@@ -41,6 +42,31 @@
     return (mNullPointerClientMemoryAttribsMask & mEnabledAttributesMask).any();
 }
 
+AttributesMask VertexArrayState::getBindingToAttributeMasks(GLuint bindingIndex) const
+{
+    ASSERT(bindingIndex < MAX_VERTEX_ATTRIB_BINDINGS);
+    return mBindingToAttributeMasks[bindingIndex];
+}
+
+// Set an attribute using a new binding.
+void VertexArrayState::setAttribBinding(size_t attribIndex, GLuint newBindingIndex)
+{
+    ASSERT(attribIndex < MAX_VERTEX_ATTRIBS && newBindingIndex < MAX_VERTEX_ATTRIB_BINDINGS);
+
+    // Update the binding-attribute map.
+    const GLuint oldBindingIndex = mVertexAttributes[attribIndex].bindingIndex;
+    ASSERT(oldBindingIndex != newBindingIndex);
+
+    ASSERT(mBindingToAttributeMasks[oldBindingIndex].test(attribIndex) &&
+           !mBindingToAttributeMasks[newBindingIndex].test(attribIndex));
+
+    mBindingToAttributeMasks[oldBindingIndex].reset(attribIndex);
+    mBindingToAttributeMasks[newBindingIndex].set(attribIndex);
+
+    // Set the attribute using the new binding.
+    mVertexAttributes[attribIndex].bindingIndex = newBindingIndex;
+}
+
 // VertexArray implementation.
 VertexArray::VertexArray(rx::GLImplFactory *factory,
                          GLuint id,
@@ -185,11 +211,11 @@
     {
         // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable.
         ASSERT(context->getClientVersion() >= ES_3_1);
-        mState.mVertexAttributes[attribIndex].bindingIndex = bindingIndex;
+
+        mState.setAttribBinding(attribIndex, bindingIndex);
 
         setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_BINDING);
     }
-    mState.mVertexAttributes[attribIndex].bindingIndex = static_cast<GLuint>(bindingIndex);
 }
 
 void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)