Added conversion rules for GL_INT and GL_UNSIGNED_INT for VertexBuffer11.

TRAC #22693

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang

git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2118 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 39e3f28..471c3e8 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -654,12 +654,13 @@
 }
 
 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
-                                   GLsizei stride, const void *pointer)
+                                   bool pureInteger, GLsizei stride, const void *pointer)
 {
     mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
     mState.vertexAttribute[attribNum].mSize = size;
     mState.vertexAttribute[attribNum].mType = type;
     mState.vertexAttribute[attribNum].mNormalized = normalized;
+    mState.vertexAttribute[attribNum].mPureInteger = pureInteger;
     mState.vertexAttribute[attribNum].mStride = stride;
     mState.vertexAttribute[attribNum].mPointer = pointer;
 }
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index 7bd44c2..4d807d2 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -75,7 +75,8 @@
 class VertexAttribute
 {
   public:
-    VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0)
+    VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mPureInteger(false),
+                        mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0)
     {
         mCurrentValue.FloatValues[0] = 0.0f;
         mCurrentValue.FloatValues[1] = 0.0f;
@@ -108,6 +109,7 @@
     GLenum mType;
     GLint mSize;
     bool mNormalized;
+    bool mPureInteger;
     GLsizei mStride;   // 0 means natural stride
 
     union
@@ -280,7 +282,7 @@
     void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
     const VertexAttribute &getVertexAttribState(unsigned int attribNum);
     void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
-                              bool normalized, GLsizei stride, const void *pointer);
+                              bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
     const void *getVertexAttribPointer(unsigned int attribNum) const;
 
     void setUnpackAlignment(GLint alignment);
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 7d3a326..23d543b 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -6819,7 +6819,8 @@
 
         if (context)
         {
-            context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
+            context->setVertexAttribState(index, context->getArrayBuffer(), size, type,
+                                          normalized == GL_TRUE, false, stride, ptr);
         }
     }
     catch(std::bad_alloc&)
diff --git a/src/libGLESv2/renderer/VertexBuffer.cpp b/src/libGLESv2/renderer/VertexBuffer.cpp
index d2e0fc6..509dc53 100644
--- a/src/libGLESv2/renderer/VertexBuffer.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer.cpp
@@ -162,7 +162,8 @@
         if (mCache[element].type == attribute.mType &&
             mCache[element].size == attribute.mSize &&
             mCache[element].stride == attribute.stride() &&
-            mCache[element].normalized == attribute.mNormalized)
+            mCache[element].normalized == attribute.mNormalized &&
+            mCache[element].pureInteger == attribute.mPureInteger)
         {
             if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
             {
@@ -196,7 +197,7 @@
 int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
 {
     int attributeOffset = attrib.mOffset % attrib.stride();
-    VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, getWritePosition() };
+    VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attrib.mPureInteger, attributeOffset, getWritePosition() };
     mCache.push_back(element);
 
     return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
diff --git a/src/libGLESv2/renderer/VertexBuffer.h b/src/libGLESv2/renderer/VertexBuffer.h
index 6ca5eb0..50a0539 100644
--- a/src/libGLESv2/renderer/VertexBuffer.h
+++ b/src/libGLESv2/renderer/VertexBuffer.h
@@ -121,6 +121,7 @@
         GLint size;
         GLsizei stride;
         bool normalized;
+        bool pureInteger;
         int attributeOffset;
 
         unsigned int streamOffset;
diff --git a/src/libGLESv2/renderer/VertexBuffer11.cpp b/src/libGLESv2/renderer/VertexBuffer11.cpp
index 4d48dcf..c479ff1 100644
--- a/src/libGLESv2/renderer/VertexBuffer11.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer11.cpp
@@ -301,7 +301,7 @@
     }
 }
 
-const VertexBuffer11::VertexConverter VertexBuffer11::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] =
+const VertexBuffer11::VertexConverter VertexBuffer11::mFloatVertexTranslations[NUM_GL_FLOAT_VERTEX_ATTRIB_TYPES][2][4] =
 {
     { // GL_BYTE
         { // unnormalized
@@ -359,6 +359,34 @@
             { &copyVertexData<GLushort, 4, false, UINT16_MAX>, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 },
         },
     },
+    { // GL_INT
+        { // unnormalized
+            { &copyToFloatVertexData<GLint, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &copyToFloatVertexData<GLint, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &copyToFloatVertexData<GLint, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &copyToFloatVertexData<GLint, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+        { // normalized
+            { &copyToFloatVertexData<GLint, 1, true>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &copyToFloatVertexData<GLint, 2, true>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &copyToFloatVertexData<GLint, 3, true>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &copyToFloatVertexData<GLint, 4, true>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+    },
+    { // GL_UNSIGNED_INT
+        { // unnormalized
+            { &copyToFloatVertexData<GLuint, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &copyToFloatVertexData<GLuint, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &copyToFloatVertexData<GLuint, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &copyToFloatVertexData<GLuint, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+        { // normalized
+            { &copyToFloatVertexData<GLuint, 1, true>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &copyToFloatVertexData<GLuint, 2, true>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &copyToFloatVertexData<GLuint, 3, true>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &copyToFloatVertexData<GLuint, 4, true>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+    },
     { // GL_FIXED
         { // unnormalized
             { &copyFixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 },
@@ -403,24 +431,84 @@
     },
 };
 
+const VertexBuffer11::VertexConverter VertexBuffer11::mIntegerVertexTranslations[NUM_GL_INTEGER_VERTEX_ATTRIB_TYPES][4] =
+{
+    { // GL_BYTE
+        { &copyVertexData<GLbyte, 1, false, 1>, true, DXGI_FORMAT_R8_SINT, 1 },
+        { &copyVertexData<GLbyte, 2, false, 1>, true, DXGI_FORMAT_R8G8_SINT, 2 },
+        { &copyVertexData<GLbyte, 3, true, 1>, false, DXGI_FORMAT_R8G8B8A8_SINT, 4 },
+        { &copyVertexData<GLbyte, 4, false, 1>, true, DXGI_FORMAT_R8G8B8A8_SINT, 4 },
+    },
+    { // GL_UNSIGNED_BYTE
+        { &copyVertexData<GLubyte, 1, false, 1>, true, DXGI_FORMAT_R8_UINT, 1 },
+        { &copyVertexData<GLubyte, 2, false, 1>, true, DXGI_FORMAT_R8G8_UINT, 2 },
+        { &copyVertexData<GLubyte, 3, true, 1>, false, DXGI_FORMAT_R8G8B8A8_UINT, 4 },
+        { &copyVertexData<GLubyte, 4, false, 1>, true, DXGI_FORMAT_R8G8B8A8_UINT, 4 },
+    },
+    { // GL_SHORT
+        { &copyVertexData<GLshort, 1, false, 1>, true, DXGI_FORMAT_R16_SINT, 2 },
+        { &copyVertexData<GLshort, 2, false, 1>, true, DXGI_FORMAT_R16G16_SINT, 4 },
+        { &copyVertexData<GLshort, 3, true, 1>, false, DXGI_FORMAT_R16G16B16A16_SINT, 8 },
+        { &copyVertexData<GLshort, 4, false, 1>, true, DXGI_FORMAT_R16G16B16A16_SINT, 8 },
+    },
+    { // GL_UNSIGNED_SHORT
+        { &copyVertexData<GLushort, 1, false, 1>, true, DXGI_FORMAT_R16_UINT, 2 },
+        { &copyVertexData<GLushort, 2, false, 1>, true, DXGI_FORMAT_R16G16_UINT, 4 },
+        { &copyVertexData<GLushort, 3, true, 1>, false, DXGI_FORMAT_R16G16B16A16_UINT, 8 },
+        { &copyVertexData<GLushort, 4, false, 1>, true, DXGI_FORMAT_R16G16B16A16_UINT, 8 },
+    },
+    { // GL_INT
+        { &copyVertexData<GLint, 1, false, 1>, true, DXGI_FORMAT_R32_SINT, 4 },
+        { &copyVertexData<GLint, 2, false, 1>, true, DXGI_FORMAT_R32G32_SINT, 8 },
+        { &copyVertexData<GLint, 3, false, 1>, true, DXGI_FORMAT_R32G32B32_SINT, 12 },
+        { &copyVertexData<GLint, 4, false, 1>, true, DXGI_FORMAT_R32G32B32A32_SINT, 16 },
+    },
+    { // GL_UNSIGNED_INT
+        { &copyVertexData<GLuint, 1, false, 1>, true, DXGI_FORMAT_R32_UINT, 4 },
+        { &copyVertexData<GLuint, 2, false, 1>, true, DXGI_FORMAT_R32G32_UINT, 8 },
+        { &copyVertexData<GLuint, 3, false, 1>, true, DXGI_FORMAT_R32G32B32_UINT, 12 },
+        { &copyVertexData<GLuint, 4, false, 1>, true, DXGI_FORMAT_R32G32B32A32_UINT, 16 },
+    },
+};
+
 const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute)
 {
     GLenum type = attribute.mArrayEnabled ? attribute.mType : attribute.mCurrentValue.Type;
-
-    unsigned int typeIndex = 0;
-    switch (type)
+    if (attribute.mPureInteger)
     {
-      case GL_BYTE:             typeIndex = 0; break;
-      case GL_UNSIGNED_BYTE:    typeIndex = 1; break;
-      case GL_SHORT:            typeIndex = 2; break;
-      case GL_UNSIGNED_SHORT:   typeIndex = 3; break;
-      case GL_FIXED:            typeIndex = 4; break;
-      case GL_HALF_FLOAT:       typeIndex = 5; break;
-      case GL_FLOAT:            typeIndex = 6; break;
-      default:                  UNREACHABLE(); break;
-    }
+        unsigned int typeIndex = 0;
+        switch (type)
+        {
+          case GL_BYTE:                        typeIndex = 0; break;
+          case GL_UNSIGNED_BYTE:               typeIndex = 1; break;
+          case GL_SHORT:                       typeIndex = 2; break;
+          case GL_UNSIGNED_SHORT:              typeIndex = 3; break;
+          case GL_INT:                         typeIndex = 4; break;
+          case GL_UNSIGNED_INT:                typeIndex = 5; break;
+          default:                             UNREACHABLE(); break;
+        }
 
-    return mPossibleTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1];
+        return mIntegerVertexTranslations[typeIndex][attribute.mSize - 1];
+    }
+    else
+    {
+        unsigned int typeIndex = 0;
+        switch (type)
+        {
+          case GL_BYTE:                        typeIndex = 0; break;
+          case GL_UNSIGNED_BYTE:               typeIndex = 1; break;
+          case GL_SHORT:                       typeIndex = 2; break;
+          case GL_UNSIGNED_SHORT:              typeIndex = 3; break;
+          case GL_INT:                         typeIndex = 4; break;
+          case GL_UNSIGNED_INT:                typeIndex = 5; break;
+          case GL_FIXED:                       typeIndex = 6; break;
+          case GL_HALF_FLOAT:                  typeIndex = 7; break;
+          case GL_FLOAT:                       typeIndex = 8; break;
+          default:                             UNREACHABLE(); break;
+        }
+
+        return mFloatVertexTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1];
+    }
 }
 
 }
diff --git a/src/libGLESv2/renderer/VertexBuffer11.h b/src/libGLESv2/renderer/VertexBuffer11.h
index d0ca035..6292cf2 100644
--- a/src/libGLESv2/renderer/VertexBuffer11.h
+++ b/src/libGLESv2/renderer/VertexBuffer11.h
@@ -59,10 +59,11 @@
         unsigned int outputElementSize;
     };
 
-    enum { NUM_GL_VERTEX_ATTRIB_TYPES = 7 };
+    static const unsigned int  NUM_GL_FLOAT_VERTEX_ATTRIB_TYPES = 9;
+    static const VertexConverter mFloatVertexTranslations[NUM_GL_FLOAT_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
 
-    // This table is used to generate mAttributeTypes.
-    static const VertexConverter mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
+    static const unsigned int NUM_GL_INTEGER_VERTEX_ATTRIB_TYPES = 6;
+    static const VertexConverter mIntegerVertexTranslations[NUM_GL_INTEGER_VERTEX_ATTRIB_TYPES][4]; // [GL types as enumerated by typeIndex()][size - 1]
 
     static const VertexConverter &getVertexConversion(const gl::VertexAttribute &attribute);
 };
diff --git a/src/libGLESv2/renderer/VertexBuffer9.cpp b/src/libGLESv2/renderer/VertexBuffer9.cpp
index 0182703..a92e9e5 100644
--- a/src/libGLESv2/renderer/VertexBuffer9.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer9.cpp
@@ -445,6 +445,9 @@
 
 const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::VertexAttribute &attribute)
 {
+    // Pure integer attributes only supported in ES3.0
+    ASSERT(!attribute.mPureInteger);
+
     GLenum type = attribute.mArrayEnabled ? attribute.mType : attribute.mCurrentValue.Type;
     return mFormatConverters[typeIndex(type)][attribute.mNormalized][attribute.mSize - 1];
 }