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/validationES2.cpp b/src/libANGLE/validationES2.cpp
index c24fa48..ebe6352 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -3935,56 +3935,33 @@
                                  GLsizei stride,
                                  const GLvoid *ptr)
 {
-    if (index >= MAX_VERTEX_ATTRIBS)
+    if (!ValidateVertexFormatBase(context, index, size, type, false))
     {
-        context->handleError(Error(GL_INVALID_VALUE, "Invalid index value."));
         return false;
     }
 
-    if (size < 1 || size > 4)
-    {
-        context->handleError(Error(GL_INVALID_VALUE, "Invalide size value."));
-        return false;
-    }
-
-    switch (type)
-    {
-        case GL_BYTE:
-        case GL_UNSIGNED_BYTE:
-        case GL_SHORT:
-        case GL_UNSIGNED_SHORT:
-        case GL_FIXED:
-        case GL_FLOAT:
-            break;
-
-        case GL_HALF_FLOAT:
-        case GL_INT:
-        case GL_UNSIGNED_INT:
-        case GL_INT_2_10_10_10_REV:
-        case GL_UNSIGNED_INT_2_10_10_10_REV:
-            if (context->getClientMajorVersion() < 3)
-            {
-                context->handleError(
-                    Error(GL_INVALID_ENUM, "Vertex type not supported before OpenGL ES 3.0."));
-                return false;
-            }
-            break;
-
-        default:
-            context->handleError(Error(GL_INVALID_ENUM, "Invalid vertex type."));
-            return false;
-    }
-
     if (stride < 0)
     {
-        context->handleError(Error(GL_INVALID_VALUE, "Invalid stride."));
+        context->handleError(Error(GL_INVALID_VALUE, "stride cannot be negative."));
         return false;
     }
 
-    if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
+    const Caps &caps = context->getCaps();
+    if (context->getClientVersion() >= ES_3_1)
     {
-        context->handleError(Error(GL_INVALID_OPERATION, "Invalid size for a sized vertex type."));
-        return false;
+        if (stride > caps.maxVertexAttribStride)
+        {
+            context->handleError(
+                Error(GL_INVALID_VALUE, "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE."));
+            return false;
+        }
+
+        if (index >= caps.maxVertexAttribBindings)
+        {
+            context->handleError(
+                Error(GL_INVALID_VALUE, "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS."));
+            return false;
+        }
     }
 
     // [OpenGL ES 3.0.2] Section 2.8 page 24:
@@ -3993,11 +3970,11 @@
     // and the pointer argument is not NULL.
     bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
                              context->getGLState().getVertexArray()->id() == 0;
-    if (!nullBufferAllowed && context->getGLState().getArrayBufferId() == 0 && ptr != NULL)
+    if (!nullBufferAllowed && context->getGLState().getArrayBufferId() == 0 && ptr != nullptr)
     {
         context->handleError(
             Error(GL_INVALID_OPERATION,
-                  "Pointer is null with a non-zero VAO bound and zero bound to GL_ARRAY_BUFFER."));
+                  "Client data cannot be used with a non-default vertex array object."));
         return false;
     }