Refactoring VertexArrays

BUG=angle:676
Change-Id: If17b05ab667d79adcaacfbd1811ed92c0ce47fff
Reviewed-on: https://chromium-review.googlesource.com/203294
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 342ac28..6d5f329 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -786,7 +786,7 @@
 
 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
 {
-    return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
+    return getCurrentVertexArray()->getVertexAttribute(attribNum).pointer;
 }
 
 void Context::setPackAlignment(GLint alignment)
@@ -873,7 +873,7 @@
     // Although the spec states VAO state is not initialized until the object is bound,
     // we create it immediately. The resulting behaviour is transparent to the application,
     // since it's not currently possible to access the state until the object is bound.
-    mVertexArrayMap[handle] = new VertexArray(mRenderer, handle);
+    mVertexArrayMap[handle] = new VertexArray(mRenderer->createVertexArray(), handle, MAX_VERTEX_ATTRIBS);
 
     return handle;
 }
@@ -1210,7 +1210,7 @@
 {
     if (!getVertexArray(vertexArray))
     {
-        mVertexArrayMap[vertexArray] = new VertexArray(mRenderer, vertexArray);
+        mVertexArrayMap[vertexArray] = new VertexArray(mRenderer->createVertexArray(), vertexArray, MAX_VERTEX_ATTRIBS);
     }
 
     mState.vertexArray = vertexArray;
@@ -3728,8 +3728,8 @@
         for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
         {
             const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
-            gl::Buffer *boundBuffer = vertexAttrib.mBoundBuffer.get();
-            if (vertexAttrib.mArrayEnabled && boundBuffer && boundBuffer->mapped())
+            gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
+            if (vertexAttrib.enabled && boundBuffer && boundBuffer->mapped())
             {
                 return true;
             }
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index d448361..870ed02 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -62,7 +62,7 @@
 class Query;
 class ResourceManager;
 class Buffer;
-class VertexAttribute;
+struct VertexAttribute;
 class VertexArray;
 class Sampler;
 class TransformFeedback;
diff --git a/src/libGLESv2/DynamicHLSL.h b/src/libGLESv2/DynamicHLSL.h
index dbbdbc0..69c4ec4 100644
--- a/src/libGLESv2/DynamicHLSL.h
+++ b/src/libGLESv2/DynamicHLSL.h
@@ -25,7 +25,7 @@
 class VertexShader;
 struct VariableLocation;
 struct LinkedVarying;
-class VertexAttribute;
+struct VertexAttribute;
 struct VertexFormat;
 struct ShaderVariable;
 struct Varying;
diff --git a/src/libGLESv2/VertexArray.cpp b/src/libGLESv2/VertexArray.cpp
index bd2df39..249ae19 100644
--- a/src/libGLESv2/VertexArray.cpp
+++ b/src/libGLESv2/VertexArray.cpp
@@ -9,31 +9,34 @@
 
 #include "libGLESv2/VertexArray.h"
 #include "libGLESv2/Buffer.h"
+#include "libGLESv2/renderer/VertexArrayImpl.h"
 
 namespace gl
 {
 
-VertexArray::VertexArray(rx::Renderer *renderer, GLuint id)
-    : RefCountObject(id)
+VertexArray::VertexArray(rx::VertexArrayImpl *impl, GLuint id, size_t maxAttribs)
+    : RefCountObject(id),
+      mVertexArray(impl),
+      mVertexAttributes(maxAttribs)
 {
 }
 
 VertexArray::~VertexArray()
 {
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    for (size_t i = 0; i < getMaxAttribs(); i++)
     {
-        mVertexAttributes[i].mBoundBuffer.set(NULL);
+        mVertexAttributes[i].buffer.set(NULL);
     }
     mElementArrayBuffer.set(NULL);
 }
 
 void VertexArray::detachBuffer(GLuint bufferName)
 {
-    for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+    for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++)
     {
-        if (mVertexAttributes[attribute].mBoundBuffer.id() == bufferName)
+        if (mVertexAttributes[attribute].buffer.id() == bufferName)
         {
-            mVertexAttributes[attribute].mBoundBuffer.set(NULL);
+            mVertexAttributes[attribute].buffer.set(NULL);
         }
     }
 
@@ -43,29 +46,44 @@
     }
 }
 
-const VertexAttribute& VertexArray::getVertexAttribute(unsigned int attributeIndex) const
+const VertexAttribute& VertexArray::getVertexAttribute(size_t attributeIndex) const
 {
-    ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);
+    ASSERT(attributeIndex < getMaxAttribs());
     return mVertexAttributes[attributeIndex];
 }
 
 void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor)
 {
-    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
-    mVertexAttributes[index].mDivisor = divisor;
+    ASSERT(index < getMaxAttribs());
+    mVertexAttributes[index].divisor = divisor;
+    mVertexArray->setAttributeDivisor(index, divisor);
 }
 
 void VertexArray::enableAttribute(unsigned int attributeIndex, bool enabledState)
 {
-    ASSERT(attributeIndex < gl::MAX_VERTEX_ATTRIBS);
-    mVertexAttributes[attributeIndex].mArrayEnabled = enabledState;
+    ASSERT(attributeIndex < getMaxAttribs());
+    mVertexAttributes[attributeIndex].enabled = enabledState;
+    mVertexArray->enableAttribute(attributeIndex, enabledState);
 }
 
 void VertexArray::setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
                                     bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
 {
-    ASSERT(attributeIndex < gl::MAX_VERTEX_ATTRIBS);
-    mVertexAttributes[attributeIndex].setState(boundBuffer, size, type, normalized, pureInteger, stride, pointer);
+    ASSERT(attributeIndex < getMaxAttribs());
+    mVertexAttributes[attributeIndex].buffer.set(boundBuffer);
+    mVertexAttributes[attributeIndex].size = size;
+    mVertexAttributes[attributeIndex].type = type;
+    mVertexAttributes[attributeIndex].normalized = normalized;
+    mVertexAttributes[attributeIndex].pureInteger = pureInteger;
+    mVertexAttributes[attributeIndex].stride = stride;
+    mVertexAttributes[attributeIndex].pointer = pointer;
+    mVertexArray->setAttribute(attributeIndex, mVertexAttributes[attributeIndex]);
+}
+
+void VertexArray::setElementArrayBuffer(Buffer *buffer)
+{
+    mElementArrayBuffer.set(buffer);
+    mVertexArray->setElementArrayBuffer(buffer);
 }
 
 }
\ No newline at end of file
diff --git a/src/libGLESv2/VertexArray.h b/src/libGLESv2/VertexArray.h
index ecfe7ad..1ea3c38 100644
--- a/src/libGLESv2/VertexArray.h
+++ b/src/libGLESv2/VertexArray.h
@@ -20,6 +20,7 @@
 namespace rx
 {
 class Renderer;
+class VertexArrayImpl;
 }
 
 namespace gl
@@ -29,23 +30,25 @@
 class VertexArray : public RefCountObject
 {
   public:
-    VertexArray(rx::Renderer *renderer, GLuint id);
+    VertexArray(rx::VertexArrayImpl *impl, GLuint id, size_t maxAttribs);
     ~VertexArray();
 
-    const VertexAttribute& getVertexAttribute(unsigned int attributeIndex) const;
+    const VertexAttribute& getVertexAttribute(size_t attributeIndex) const;
     void detachBuffer(GLuint bufferName);
     void setVertexAttribDivisor(GLuint index, GLuint divisor);
     void enableAttribute(unsigned int attributeIndex, bool enabledState);
     void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
                            bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
 
-    const VertexAttribute* getVertexAttributes() const { return mVertexAttributes; }
+    const VertexAttribute* getVertexAttributes() const { return mVertexAttributes.data(); }
     Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); }
-    void setElementArrayBuffer(Buffer *elementArrayBuffer) { mElementArrayBuffer.set(elementArrayBuffer); }
+    void setElementArrayBuffer(Buffer *buffer);
     GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); }
+    size_t getMaxAttribs() const { return mVertexAttributes.size(); }
 
   private:
-    VertexAttribute mVertexAttributes[MAX_VERTEX_ATTRIBS];
+    rx::VertexArrayImpl *mVertexArray;
+    std::vector<VertexAttribute> mVertexAttributes;
     BindingPointer<Buffer> mElementArrayBuffer;
 };
 
diff --git a/src/libGLESv2/VertexAttribute.cpp b/src/libGLESv2/VertexAttribute.cpp
new file mode 100644
index 0000000..7d011ef
--- /dev/null
+++ b/src/libGLESv2/VertexAttribute.cpp
@@ -0,0 +1,56 @@
+#include "precompiled.h"
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Implementation of the state class for mananging GLES 3 Vertex Array Objects.
+//
+
+#include "libGLESv2/VertexAttribute.h"
+
+namespace gl
+{
+
+VertexAttribute::VertexAttribute()
+    : enabled(false),
+      type(GL_FLOAT),
+      size(4),
+      normalized(false),
+      pureInteger(false),
+      stride(0),
+      pointer(NULL),
+      divisor(0)
+{
+}
+
+size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib)
+{
+    GLuint size = attrib.size;
+    switch (attrib.type)
+    {
+      case GL_BYTE:                        return size * sizeof(GLbyte);
+      case GL_UNSIGNED_BYTE:               return size * sizeof(GLubyte);
+      case GL_SHORT:                       return size * sizeof(GLshort);
+      case GL_UNSIGNED_SHORT:              return size * sizeof(GLushort);
+      case GL_INT:                         return size * sizeof(GLint);
+      case GL_UNSIGNED_INT:                return size * sizeof(GLuint);
+      case GL_INT_2_10_10_10_REV:          return 4;
+      case GL_UNSIGNED_INT_2_10_10_10_REV: return 4;
+      case GL_FIXED:                       return size * sizeof(GLfixed);
+      case GL_HALF_FLOAT:                  return size * sizeof(GLhalf);
+      case GL_FLOAT:                       return size * sizeof(GLfloat);
+      default: UNREACHABLE();              return size * sizeof(GLfloat);
+    }
+}
+
+size_t ComputeVertexAttributeStride(const VertexAttribute& attrib)
+{
+    if (!attrib.enabled)
+    {
+        return 16;
+    }
+    return attrib.stride ? attrib.stride : ComputeVertexAttributeTypeSize(attrib);
+}
+
+}
\ No newline at end of file
diff --git a/src/libGLESv2/VertexAttribute.h b/src/libGLESv2/VertexAttribute.h
index e9364d6..e9757b6 100644
--- a/src/libGLESv2/VertexAttribute.h
+++ b/src/libGLESv2/VertexAttribute.h
@@ -14,95 +14,58 @@
 namespace gl
 {
 
-class VertexAttribute
+struct VertexAttribute
 {
-  public:
-    VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mPureInteger(false),
-                        mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0)
-    {
-    }
+    bool enabled; // From glEnable/DisableVertexAttribArray
 
-    int typeSize() const
-    {
-        switch (mType)
-        {
-          case GL_BYTE:                        return mSize * sizeof(GLbyte);
-          case GL_UNSIGNED_BYTE:               return mSize * sizeof(GLubyte);
-          case GL_SHORT:                       return mSize * sizeof(GLshort);
-          case GL_UNSIGNED_SHORT:              return mSize * sizeof(GLushort);
-          case GL_INT:                         return mSize * sizeof(GLint);
-          case GL_UNSIGNED_INT:                return mSize * sizeof(GLuint);
-          case GL_INT_2_10_10_10_REV:          return 4;
-          case GL_UNSIGNED_INT_2_10_10_10_REV: return 4;
-          case GL_FIXED:                       return mSize * sizeof(GLfixed);
-          case GL_HALF_FLOAT:                  return mSize * sizeof(GLhalf);
-          case GL_FLOAT:                       return mSize * sizeof(GLfloat);
-          default: UNREACHABLE();              return mSize * sizeof(GLfloat);
-        }
-    }
-
-    GLsizei stride() const
-    {
-        return (mArrayEnabled ? (mStride ? mStride : typeSize()) : 16);
-    }
-
-    void setState(gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
-                  bool pureInteger, GLsizei stride, const void *pointer)
-    {
-        mBoundBuffer.set(boundBuffer);
-        mSize = size;
-        mType = type;
-        mNormalized = normalized;
-        mPureInteger = pureInteger;
-        mStride = stride;
-        mPointer = pointer;
-    }
-
-    template <typename T>
-    T querySingleParameter(GLenum pname) const
-    {
-        switch (pname)
-        {
-          case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
-            return static_cast<T>(mArrayEnabled ? GL_TRUE : GL_FALSE);
-          case GL_VERTEX_ATTRIB_ARRAY_SIZE:
-            return static_cast<T>(mSize);
-          case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
-            return static_cast<T>(mStride);
-          case GL_VERTEX_ATTRIB_ARRAY_TYPE:
-            return static_cast<T>(mType);
-          case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
-            return static_cast<T>(mNormalized ? GL_TRUE : GL_FALSE);
-          case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
-            return static_cast<T>(mBoundBuffer.id());
-          case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
-            return static_cast<T>(mDivisor);
-          case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
-            return static_cast<T>(mPureInteger ? GL_TRUE : GL_FALSE);
-          default:
-            UNREACHABLE();
-            return static_cast<T>(0);
-        }
-    }
-
-    // From glVertexAttribPointer
-    GLenum mType;
-    GLint mSize;
-    bool mNormalized;
-    bool mPureInteger;
-    GLsizei mStride;   // 0 means natural stride
+    GLenum type;
+    GLuint size;
+    bool normalized;
+    bool pureInteger;
+    GLuint stride; // 0 means natural stride
 
     union
     {
-        const void *mPointer;
-        intptr_t mOffset;
+        const GLvoid *pointer;
+        GLintptr offset;
     };
+    BindingPointer<Buffer> buffer; // Captured when glVertexAttribPointer is called.
 
-    BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
-    bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
-    unsigned int mDivisor;
+    GLuint divisor;
+
+    VertexAttribute();
 };
 
+template <typename T>
+T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname)
+{
+  switch (pname)
+  {
+    case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+      return static_cast<T>(attrib.enabled ? GL_TRUE : GL_FALSE);
+    case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+      return static_cast<T>(attrib.size);
+    case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+      return static_cast<T>(attrib.stride);
+    case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+      return static_cast<T>(attrib.type);
+    case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+      return static_cast<T>(attrib.normalized ? GL_TRUE : GL_FALSE);
+    case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+      return static_cast<T>(attrib.buffer.id());
+    case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+      return static_cast<T>(attrib.divisor);
+    case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+      return static_cast<T>(attrib.pureInteger ? GL_TRUE : GL_FALSE);
+    default:
+      UNREACHABLE();
+      return static_cast<T>(0);
+  }
+}
+
+size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib);
+size_t ComputeVertexAttributeStride(const VertexAttribute& attrib);
+
 struct VertexAttribCurrentValueData
 {
     union
diff --git a/src/libGLESv2/angletypes.cpp b/src/libGLESv2/angletypes.cpp
index acb3da8..d86f19a 100644
--- a/src/libGLESv2/angletypes.cpp
+++ b/src/libGLESv2/angletypes.cpp
@@ -90,15 +90,15 @@
     }
 }
 
-VertexFormat::VertexFormat(const VertexAttribute &attribute)
-    : mType(attribute.mType),
-      mNormalized(attribute.mNormalized ? GL_TRUE : GL_FALSE),
-      mComponents(attribute.mSize),
-      mPureInteger(attribute.mPureInteger)
+VertexFormat::VertexFormat(const VertexAttribute &attrib)
+    : mType(attrib.type),
+      mNormalized(attrib.normalized ? GL_TRUE : GL_FALSE),
+      mComponents(attrib.size),
+      mPureInteger(attrib.pureInteger)
 {
     // Ensure we aren't initializing a vertex format which should be using
     // the current-value type
-    ASSERT(attribute.mArrayEnabled);
+    ASSERT(attrib.enabled);
 
     // Float data can not be normalized, so ignore the user setting
     if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED)
@@ -107,13 +107,13 @@
     }
 }
 
-VertexFormat::VertexFormat(const VertexAttribute &attribute, GLenum currentValueType)
-    : mType(attribute.mType),
-      mNormalized(attribute.mNormalized ? GL_TRUE : GL_FALSE),
-      mComponents(attribute.mSize),
-      mPureInteger(attribute.mPureInteger)
+VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueType)
+    : mType(attrib.type),
+      mNormalized(attrib.normalized ? GL_TRUE : GL_FALSE),
+      mComponents(attrib.size),
+      mPureInteger(attrib.pureInteger)
 {
-    if (!attribute.mArrayEnabled)
+    if (!attrib.enabled)
     {
         mType = currentValueType;
         mNormalized = GL_FALSE;
diff --git a/src/libGLESv2/angletypes.h b/src/libGLESv2/angletypes.h
index 0e91279..314472a 100644
--- a/src/libGLESv2/angletypes.h
+++ b/src/libGLESv2/angletypes.h
@@ -16,7 +16,7 @@
 {
 class Buffer;
 class ProgramBinary;
-class VertexAttribute;
+struct VertexAttribute;
 struct VertexAttribCurrentValueData;
 
 enum TextureType
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index d2d14c1..64ec9e7 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -22,6 +22,7 @@
 #include "libGLESv2/Query.h"
 #include "libGLESv2/Context.h"
 #include "libGLESv2/VertexArray.h"
+#include "libGLESv2/VertexAttribute.h"
 #include "libGLESv2/TransformFeedback.h"
 
 #include "libGLESv2/validationES.h"
@@ -3860,7 +3861,7 @@
             }
             else
             {
-                *params = attribState.querySingleParameter<GLfloat>(pname);
+                *params = gl::QuerySingleVertexAttributeParameter<GLfloat>(attribState, pname);
             }
         }
     }
@@ -3903,7 +3904,7 @@
             }
             else
             {
-                *params = attribState.querySingleParameter<GLint>(pname);
+                *params = gl::QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
             }
         }
     }
@@ -7437,7 +7438,7 @@
             }
             else
             {
-                *params = attribState.querySingleParameter<GLint>(pname);
+                *params = gl::QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
             }
         }
     }
@@ -7485,7 +7486,7 @@
             }
             else
             {
-                *params = attribState.querySingleParameter<GLuint>(pname);
+                *params = gl::QuerySingleVertexAttributeParameter<GLuint>(attribState, pname);
             }
         }
     }
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 3d1e294..cb20bac 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -30,7 +30,7 @@
 class InfoLog;
 class ProgramBinary;
 struct LinkedVarying;
-class VertexAttribute;
+struct VertexAttribute;
 class Buffer;
 class Texture;
 class Framebuffer;
@@ -47,6 +47,7 @@
 class IndexBuffer;
 class QueryImpl;
 class FenceImpl;
+class VertexArrayImpl;
 class BufferStorage;
 struct TranslatedIndexData;
 class ShaderExecutable;
@@ -233,6 +234,9 @@
     virtual IndexBuffer *createIndexBuffer() = 0;
     virtual BufferStorage *createBufferStorage() = 0;
 
+    // Vertex Array creation
+    virtual VertexArrayImpl *createVertexArray() = 0;
+
     // Query and Fence creation
     virtual QueryImpl *createQuery(GLenum type) = 0;
     virtual FenceImpl *createFence() = 0;
diff --git a/src/libGLESv2/renderer/VertexArrayImpl.h b/src/libGLESv2/renderer/VertexArrayImpl.h
new file mode 100644
index 0000000..93f34e4
--- /dev/null
+++ b/src/libGLESv2/renderer/VertexArrayImpl.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexAttribImpl.h: Defines the abstract rx::VertexAttribImpl class.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
+#define LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/VertexAttribute.h"
+
+namespace rx
+{
+
+class VertexArrayImpl
+{
+  public:
+    virtual void setElementArrayBuffer(const gl::Buffer *buffer) = 0;
+    virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) = 0;
+    virtual void setAttributeDivisor(size_t idx, GLuint divisor) = 0;
+    virtual void enableAttribute(size_t idx, bool enabledState) = 0;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
diff --git a/src/libGLESv2/renderer/VertexBuffer.cpp b/src/libGLESv2/renderer/VertexBuffer.cpp
index 8adfb5b..87d023f 100644
--- a/src/libGLESv2/renderer/VertexBuffer.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer.cpp
@@ -127,10 +127,10 @@
     return true;
 }
 
-bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
+bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances)
 {
     unsigned int requiredSpace;
-    if (!mVertexBuffer->getSpaceRequired(attribute, count, instances, &requiredSpace))
+    if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace))
     {
         return false;
     }
@@ -157,7 +157,7 @@
 bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &attrib,
                                                   const gl::VertexAttribCurrentValueData &currentValue) const
 {
-    gl::Buffer *buffer = attrib.mBoundBuffer.get();
+    gl::Buffer *buffer = attrib.buffer.get();
     BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
 
     if (!storage || !storage->supportsDirectBinding())
@@ -171,7 +171,7 @@
     size_t alignment = 4;
     bool requiresConversion = false;
 
-    if (attrib.mType != GL_FLOAT)
+    if (attrib.type != GL_FLOAT)
     {
         gl::VertexFormat vertexFormat(attrib, currentValue.Type);
 
@@ -182,8 +182,8 @@
         requiresConversion = (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0;
     }
 
-    bool isAligned = (static_cast<size_t>(attrib.stride()) % alignment == 0) &&
-                     (static_cast<size_t>(attrib.mOffset) % alignment == 0);
+    bool isAligned = (static_cast<size_t>(ComputeVertexAttributeStride(attrib)) % alignment == 0) &&
+                     (static_cast<size_t>(attrib.offset) % alignment == 0);
 
     return !requiresConversion && isAligned;
 }
@@ -226,17 +226,17 @@
 {
 }
 
-bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute, unsigned int *outStreamOffset)
+bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attrib, unsigned int *outStreamOffset)
 {
     for (unsigned int element = 0; element < mCache.size(); element++)
     {
-        if (mCache[element].type == attribute.mType &&
-            mCache[element].size == attribute.mSize &&
-            mCache[element].stride == attribute.stride() &&
-            mCache[element].normalized == attribute.mNormalized &&
-            mCache[element].pureInteger == attribute.mPureInteger)
+        if (mCache[element].type == attrib.type &&
+            mCache[element].size == attrib.size &&
+            mCache[element].stride == ComputeVertexAttributeStride(attrib) &&
+            mCache[element].normalized == attrib.normalized &&
+            mCache[element].pureInteger == attrib.pureInteger)
         {
-            if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
+            if (mCache[element].attributeOffset == attrib.offset % ComputeVertexAttributeStride(attrib))
             {
                 if (outStreamOffset)
                 {
@@ -275,8 +275,8 @@
     unsigned int streamOffset;
     if (VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances, &streamOffset))
     {
-        int attributeOffset = attrib.mOffset % attrib.stride();
-        VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attrib.mPureInteger, attributeOffset, streamOffset };
+        int attributeOffset = attrib.offset % ComputeVertexAttributeStride(attrib);
+        VertexElement element = { attrib.type, attrib.size, ComputeVertexAttributeStride(attrib), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset };
         mCache.push_back(element);
 
         if (outStreamOffset)
diff --git a/src/libGLESv2/renderer/VertexBuffer.h b/src/libGLESv2/renderer/VertexBuffer.h
index d4cdf9e..d492de7 100644
--- a/src/libGLESv2/renderer/VertexBuffer.h
+++ b/src/libGLESv2/renderer/VertexBuffer.h
@@ -14,7 +14,7 @@
 
 namespace gl
 {
-class VertexAttribute;
+struct VertexAttribute;
 struct VertexAttribCurrentValueData;
 }
 
diff --git a/src/libGLESv2/renderer/VertexDataManager.cpp b/src/libGLESv2/renderer/VertexDataManager.cpp
index 6aad5eb..4381b80 100644
--- a/src/libGLESv2/renderer/VertexDataManager.cpp
+++ b/src/libGLESv2/renderer/VertexDataManager.cpp
@@ -27,7 +27,7 @@
 namespace rx
 {
 
-static int ElementsInBuffer(const gl::VertexAttribute &attribute, unsigned int size)
+static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size)
 {
     // Size cannot be larger than a GLsizei
     if (size > static_cast<unsigned int>(std::numeric_limits<int>::max()))
@@ -35,19 +35,19 @@
         size = static_cast<unsigned int>(std::numeric_limits<int>::max());
     }
 
-    GLsizei stride = attribute.stride();
-    return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
+    GLsizei stride = ComputeVertexAttributeStride(attrib);
+    return (size - attrib.offset % stride + (stride - ComputeVertexAttributeTypeSize(attrib))) / stride;
 }
 
-static int StreamingBufferElementCount(const gl::VertexAttribute &attribute, int vertexDrawCount, int instanceDrawCount)
+static int StreamingBufferElementCount(const gl::VertexAttribute &attrib, int vertexDrawCount, int instanceDrawCount)
 {
     // For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices.
     //
     // A vertex attribute with a positive divisor loads one instanced vertex for every set of
     // non-instanced vertices, and the instanced vertex index advances once every "mDivisor" instances.
-    if (instanceDrawCount > 0 && attribute.mDivisor > 0)
+    if (instanceDrawCount > 0 && attrib.divisor > 0)
     {
-        return instanceDrawCount / attribute.mDivisor;
+        return instanceDrawCount / attrib.divisor;
     }
 
     return vertexDrawCount;
@@ -100,9 +100,9 @@
     // Invalidate static buffers that don't contain matching attributes
     for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
     {
-        if (translated[i].active && attribs[i].mArrayEnabled)
+        if (translated[i].active && attribs[i].enabled)
         {
-            gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
+            gl::Buffer *buffer = attribs[i].buffer.get();
             StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
 
             if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) &&
@@ -116,9 +116,9 @@
     // Reserve the required space in the buffers
     for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
     {
-        if (translated[i].active && attribs[i].mArrayEnabled)
+        if (translated[i].active && attribs[i].enabled)
         {
-            gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
+            gl::Buffer *buffer = attribs[i].buffer.get();
             StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
             VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
 
@@ -160,11 +160,11 @@
     {
         if (translated[i].active)
         {
-            if (attribs[i].mArrayEnabled)
+            if (attribs[i].enabled)
             {
-                gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
+                gl::Buffer *buffer = attribs[i].buffer.get();
 
-                if (!buffer && attribs[i].mPointer == NULL)
+                if (!buffer && attribs[i].pointer == NULL)
                 {
                     // This is an application error that would normally result in a crash, but we catch it and return an error
                     ERR("An enabled vertex array has no buffer and no pointer.");
@@ -182,8 +182,8 @@
 
                 if (directStorage)
                 {
-                    outputElementSize = attribs[i].stride();
-                    streamOffset = attribs[i].mOffset + outputElementSize * start;
+                    outputElementSize = ComputeVertexAttributeStride(attribs[i]);
+                    streamOffset = attribs[i].offset + outputElementSize * start;
                 }
                 else if (staticBuffer)
                 {
@@ -196,7 +196,7 @@
                     {
                         // Convert the entire buffer
                         int totalCount = ElementsInBuffer(attribs[i], storage->getSize());
-                        int startIndex = attribs[i].mOffset / attribs[i].stride();
+                        int startIndex = attribs[i].offset / ComputeVertexAttributeStride(attribs[i]);
 
                         if (!staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount,
                                                                  0, &streamOffset))
@@ -205,8 +205,8 @@
                         }
                     }
 
-                    unsigned int firstElementOffset = (attribs[i].mOffset / attribs[i].stride()) * outputElementSize;
-                    unsigned int startOffset = (instances == 0 || attribs[i].mDivisor == 0) ? start * outputElementSize : 0;
+                    unsigned int firstElementOffset = (attribs[i].offset / ComputeVertexAttributeStride(attribs[i])) * outputElementSize;
+                    unsigned int startOffset = (instances == 0 || attribs[i].divisor == 0) ? start * outputElementSize : 0;
                     if (streamOffset + firstElementOffset + startOffset < streamOffset)
                     {
                         return GL_OUT_OF_MEMORY;
@@ -228,7 +228,7 @@
                 translated[i].storage = directStorage ? storage : NULL;
                 translated[i].vertexBuffer = vertexBuffer->getVertexBuffer();
                 translated[i].serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial();
-                translated[i].divisor = attribs[i].mDivisor;
+                translated[i].divisor = attribs[i].divisor;
 
                 translated[i].attribute = &attribs[i];
                 translated[i].currentValueType = currentValues[i].Type;
@@ -276,13 +276,13 @@
 
     for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
     {
-        if (translated[i].active && attribs[i].mArrayEnabled)
+        if (translated[i].active && attribs[i].enabled)
         {
-            gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
+            gl::Buffer *buffer = attribs[i].buffer.get();
 
             if (buffer)
             {
-                buffer->promoteStaticUsage(count * attribs[i].typeSize());
+                buffer->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(attribs[i]));
             }
         }
     }
diff --git a/src/libGLESv2/renderer/VertexDataManager.h b/src/libGLESv2/renderer/VertexDataManager.h
index 1a69245..2ce8f7f 100644
--- a/src/libGLESv2/renderer/VertexDataManager.h
+++ b/src/libGLESv2/renderer/VertexDataManager.h
@@ -16,7 +16,7 @@
 
 namespace gl
 {
-class VertexAttribute;
+struct VertexAttribute;
 class ProgramBinary;
 struct VertexAttribCurrentValueData;
 }
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index 5ff4c59..a90b2cd 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -31,6 +31,7 @@
 #include "libGLESv2/renderer/d3d11/Blit11.h"
 #include "libGLESv2/renderer/d3d11/Clear11.h"
 #include "libGLESv2/renderer/d3d11/PixelTransfer11.h"
+#include "libGLESv2/renderer/d3d11/VertexArray11.h"
 #include "libEGL/Display.h"
 
 // Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
@@ -2796,6 +2797,11 @@
     return new BufferStorage11(this);
 }
 
+VertexArrayImpl *Renderer11::createVertexArray()
+{
+    return new VertexArray11(this);
+}
+
 QueryImpl *Renderer11::createQuery(GLenum type)
 {
     return new Query11(this, type);
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d11/Renderer11.h
index 8fe39ab..e940599 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.h
@@ -189,6 +189,9 @@
     virtual IndexBuffer *createIndexBuffer();
     virtual BufferStorage *createBufferStorage();
 
+    // Vertex Array creation
+    virtual VertexArrayImpl *createVertexArray();
+
     // Query and Fence creation
     virtual QueryImpl *createQuery(GLenum type);
     virtual FenceImpl *createFence();
diff --git a/src/libGLESv2/renderer/d3d11/VertexArray11.h b/src/libGLESv2/renderer/d3d11/VertexArray11.h
new file mode 100644
index 0000000..abe96ea
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d11/VertexArray11.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexArray11.h: Defines the rx::VertexArray11 class which implements rx::VertexArrayImpl.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXARRAY11_H_
+#define LIBGLESV2_RENDERER_VERTEXARRAY11_H_
+
+#include "libGLESv2/renderer/VertexArrayImpl.h"
+#include "libGLESv2/renderer/d3d11/Renderer11.h"
+
+namespace rx
+{
+class Renderer11;
+
+class VertexArray11 : public VertexArrayImpl
+{
+  public:
+    VertexArray11(rx::Renderer11 *renderer)
+        : VertexArrayImpl(),
+          mRenderer(renderer)
+    {
+    }
+    virtual ~VertexArray11() { }
+
+    virtual void setElementArrayBuffer(const gl::Buffer *buffer) { }
+    virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) { }
+    virtual void setAttributeDivisor(size_t idx, GLuint divisor) { }
+    virtual void enableAttribute(size_t idx, bool enabledState) { }
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexArray11);
+
+    rx::Renderer11 *mRenderer;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXARRAY11_H_
diff --git a/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp b/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp
index d69668d..f6e252f 100644
--- a/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp
@@ -71,8 +71,8 @@
 {
     if (mBuffer)
     {
-        gl::Buffer *buffer = attrib.mBoundBuffer.get();
-        int inputStride = attrib.stride();
+        gl::Buffer *buffer = attrib.buffer.get();
+        int inputStride = ComputeVertexAttributeStride(attrib);
         ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
 
         D3D11_MAPPED_SUBRESOURCE mappedResource;
@@ -86,16 +86,16 @@
         char* output = reinterpret_cast<char*>(mappedResource.pData) + offset;
 
         const char *input = NULL;
-        if (attrib.mArrayEnabled)
+        if (attrib.enabled)
         {
             if (buffer)
             {
                 BufferStorage *storage = buffer->getStorage();
-                input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset);
+                input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset);
             }
             else
             {
-                input = static_cast<const char*>(attrib.mPointer);
+                input = static_cast<const char*>(attrib.pointer);
             }
         }
         else
@@ -103,7 +103,7 @@
             input = reinterpret_cast<const char*>(currentValue.FloatValues);
         }
 
-        if (instances == 0 || attrib.mDivisor == 0)
+        if (instances == 0 || attrib.divisor == 0)
         {
             input += inputStride * start;
         }
@@ -128,22 +128,22 @@
                                       GLsizei instances, unsigned int *outSpaceRequired) const
 {
     unsigned int elementCount = 0;
-    if (attrib.mArrayEnabled)
+    if (attrib.enabled)
     {
-        if (instances == 0 || attrib.mDivisor == 0)
+        if (instances == 0 || attrib.divisor == 0)
         {
             elementCount = count;
         }
         else
         {
-            if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1))
+            if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.divisor - 1))
             {
                 // Round up
-                elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.mDivisor);
+                elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.divisor);
             }
             else
             {
-                elementCount = instances / attrib.mDivisor;
+                elementCount = instances / attrib.divisor;
             }
         }
 
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
index 23eb2be..05916d8 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
@@ -30,6 +30,7 @@
 #include "libGLESv2/renderer/d3d9/BufferStorage9.h"
 #include "libGLESv2/renderer/d3d9/Query9.h"
 #include "libGLESv2/renderer/d3d9/Fence9.h"
+#include "libGLESv2/renderer/d3d9/VertexArray9.h"
 #include "libGLESv2/angletypes.h"
 
 #include "libEGL/Display.h"
@@ -611,6 +612,11 @@
     return new BufferStorage9();
 }
 
+VertexArrayImpl *Renderer9::createVertexArray()
+{
+    return new VertexArray9(this);
+}
+
 QueryImpl *Renderer9::createQuery(GLenum type)
 {
     return new Query9(this, type);
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d9/Renderer9.h
index ecf310d..71fc69f 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.h
@@ -191,6 +191,9 @@
     virtual IndexBuffer *createIndexBuffer();
     virtual BufferStorage *createBufferStorage();
 
+    // Vertex Array creation
+    virtual VertexArrayImpl *createVertexArray();
+
     // Query and Fence creation
     virtual QueryImpl *createQuery(GLenum type);
     virtual FenceImpl *createFence();
diff --git a/src/libGLESv2/renderer/d3d9/VertexArray9.h b/src/libGLESv2/renderer/d3d9/VertexArray9.h
new file mode 100644
index 0000000..bee63bb
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d9/VertexArray9.h
@@ -0,0 +1,43 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexArray9.h: Defines the rx::VertexArray9 class which implements rx::VertexArrayImpl.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXARRAY9_H_
+#define LIBGLESV2_RENDERER_VERTEXARRAY9_H_
+
+#include "libGLESv2/renderer/VertexArrayImpl.h"
+#include "libGLESv2/renderer/d3d9/Renderer9.h"
+
+namespace rx
+{
+class Renderer9;
+
+class VertexArray9 : public VertexArrayImpl
+{
+  public:
+    VertexArray9(rx::Renderer9 *renderer)
+        : VertexArrayImpl(),
+          mRenderer(renderer)
+    {
+    }
+
+    virtual ~VertexArray9() { }
+
+    virtual void setElementArrayBuffer(const gl::Buffer *buffer) { }
+    virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) { }
+    virtual void setAttributeDivisor(size_t idx, GLuint divisor) { }
+    virtual void enableAttribute(size_t idx, bool enabledState) { }
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexArray9);
+
+    rx::Renderer9 *mRenderer;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXARRAY9_H_
diff --git a/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp b/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp
index 42ddfca..be9f21a 100644
--- a/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp
+++ b/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp
@@ -70,10 +70,10 @@
 {
     if (mVertexBuffer)
     {
-        gl::Buffer *buffer = attrib.mBoundBuffer.get();
+        gl::Buffer *buffer = attrib.buffer.get();
 
-        int inputStride = attrib.stride();
-        int elementSize = attrib.typeSize();
+        int inputStride = gl::ComputeVertexAttributeStride(attrib);
+        int elementSize = gl::ComputeVertexAttributeTypeSize(attrib);
 
         DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
 
@@ -94,16 +94,16 @@
         }
 
         const char *input = NULL;
-        if (attrib.mArrayEnabled)
+        if (attrib.enabled)
         {
             if (buffer)
             {
                 BufferStorage *storage = buffer->getStorage();
-                input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset);
+                input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset);
             }
             else
             {
-                input = static_cast<const char*>(attrib.mPointer);
+                input = static_cast<const char*>(attrib.pointer);
             }
         }
         else
@@ -111,7 +111,7 @@
             input = reinterpret_cast<const char*>(currentValue.FloatValues);
         }
 
-        if (instances == 0 || attrib.mDivisor == 0)
+        if (instances == 0 || attrib.divisor == 0)
         {
             input += inputStride * start;
         }
@@ -205,23 +205,23 @@
     gl::VertexFormat vertexFormat(attrib, GL_FLOAT);
     unsigned int elementSize = d3d9::GetVertexElementSize(vertexFormat);
 
-    if (attrib.mArrayEnabled)
+    if (attrib.enabled)
     {
         unsigned int elementCount = 0;
-        if (instances == 0 || attrib.mDivisor == 0)
+        if (instances == 0 || attrib.divisor == 0)
         {
             elementCount = count;
         }
         else
         {
-            if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1))
+            if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.divisor - 1))
             {
                 // Round up
-                elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor;
+                elementCount = (static_cast<unsigned int>(instances) + (attrib.divisor - 1)) / attrib.divisor;
             }
             else
             {
-                elementCount = static_cast<unsigned int>(instances) / attrib.mDivisor;
+                elementCount = static_cast<unsigned int>(instances) / attrib.divisor;
             }
         }