Implemented support for DX11 uniform arrays.

TRAC #22239
Signed-off-by: Daniel Koch
Signed-off-by: Shannon Woods
Author: Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1629 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 76dc108..3bafe9f 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -237,12 +237,12 @@
 
     if (targetUniform->type == GL_FLOAT)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
 
@@ -258,12 +258,12 @@
     }
     else if (targetUniform->type == GL_BOOL)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
         GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element;
 
         for (int i = 0; i < count; ++i)
@@ -298,12 +298,12 @@
 
     if (targetUniform->type == GL_FLOAT_VEC2)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
 
@@ -319,12 +319,12 @@
     }
     else if (targetUniform->type == GL_BOOL_VEC2)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2;
 
@@ -360,12 +360,12 @@
 
     if (targetUniform->type == GL_FLOAT_VEC3)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
 
@@ -381,12 +381,12 @@
     }
     else if (targetUniform->type == GL_BOOL_VEC3)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
         GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3;
 
         for (int i = 0; i < count * 3; ++i)
@@ -421,24 +421,24 @@
 
     if (targetUniform->type == GL_FLOAT_VEC4)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 4,
                v, 4 * sizeof(GLfloat) * count);
     }
     else if (targetUniform->type == GL_BOOL_VEC4)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
         GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4;
 
         for (int i = 0; i < count * 4; ++i)
@@ -507,12 +507,12 @@
         return false;
     }
 
-    int arraySize = targetUniform->arraySize;
+    int elementCount = targetUniform->elementCount();
 
-    if (arraySize == 1 && count > 1)
+    if (elementCount == 1 && count > 1)
         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-    count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+    count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
     GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8;
     for (int i = 0; i < count; i++)
@@ -540,12 +540,12 @@
         return false;
     }
 
-    int arraySize = targetUniform->arraySize;
+    int elementCount = targetUniform->elementCount();
 
-    if (arraySize == 1 && count > 1)
+    if (elementCount == 1 && count > 1)
         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-    count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+    count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
     GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12;
     for (int i = 0; i < count; i++)
@@ -574,12 +574,12 @@
         return false;
     }
 
-    int arraySize = targetUniform->arraySize;
+    int elementCount = targetUniform->elementCount();
 
-    if (arraySize == 1 && count > 1)
+    if (elementCount == 1 && count > 1)
         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-    count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+    count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
     GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16);
     for (int i = 0; i < count; i++)
@@ -606,24 +606,24 @@
         targetUniform->type == GL_SAMPLER_2D ||
         targetUniform->type == GL_SAMPLER_CUBE)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint),
                v, sizeof(GLint) * count);
     }
     else if (targetUniform->type == GL_BOOL)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
         GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element;
 
         for (int i = 0; i < count; ++i)
@@ -658,24 +658,24 @@
 
     if (targetUniform->type == GL_INT_VEC2)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 2,
                v, 2 * sizeof(GLint) * count);
     }
     else if (targetUniform->type == GL_BOOL_VEC2)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
         GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2;
 
         for (int i = 0; i < count * 2; ++i)
@@ -710,24 +710,24 @@
 
     if (targetUniform->type == GL_INT_VEC3)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 3,
                v, 3 * sizeof(GLint) * count);
     }
     else if (targetUniform->type == GL_BOOL_VEC3)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
         GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3;
 
         for (int i = 0; i < count * 3; ++i)
@@ -762,24 +762,24 @@
 
     if (targetUniform->type == GL_INT_VEC4)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
 
         memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 4,
                v, 4 * sizeof(GLint) * count);
     }
     else if (targetUniform->type == GL_BOOL_VEC4)
     {
-        int arraySize = targetUniform->arraySize;
+        int elementCount = targetUniform->elementCount();
 
-        if (arraySize == 1 && count > 1)
+        if (elementCount == 1 && count > 1)
             return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
 
-        count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+        count = std::min(elementCount - (int)mUniformIndex[location].element, count);
         GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4;
 
         for (int i = 0; i < count * 4; ++i)
@@ -968,7 +968,7 @@
             if (targetUniform->type == GL_SAMPLER_2D || 
                 targetUniform->type == GL_SAMPLER_CUBE)
             {
-                int count = targetUniform->arraySize;
+                int count = targetUniform->elementCount();
                 GLint *v = (GLint*)targetUniform->data;
 
                 if (targetUniform->ps.registerCount)
@@ -2112,45 +2112,49 @@
 
 bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant)
 {
-    ASSERT(constant.arraySize <= 1);   // FIXME: UNIMPLEMENTED
-    Uniform *uniform = new Uniform(constant.type, constant.name, 1 /*constant.arraySize*/);
+    Uniform *uniform = NULL;
+    GLint location = getUniformLocation(constant.name);
+
+    if (location >= 0)   // Previously defined, types must match
+    {
+        uniform = mUniforms[mUniformIndex[location].index];
+
+        if (uniform->type != constant.type)
+        {
+            return false;
+        }
+    }
+    else
+    {
+        uniform = new Uniform(constant.type, constant.name, constant.arraySize);
+    }
 
     if (!uniform)
     {
         return false;
     }
 
-    // Check if already defined
-    GLint location = getUniformLocation(uniform->name);
-    GLenum type = uniform->type;
-
-    if (location >= 0)
-    {
-        delete uniform;
-        uniform = mUniforms[mUniformIndex[location].index];
-    }
-
     if (shader == GL_FRAGMENT_SHADER)
     {
         uniform->ps.registerIndex = constant.registerIndex;
-        uniform->ps.registerCount = 1 /*constant.arraySize*/;
+        uniform->ps.registerCount = uniform->registerCount();
     }
     else if (shader == GL_VERTEX_SHADER)
     {
         uniform->vs.registerIndex = constant.registerIndex;
-        uniform->vs.registerCount = 1 /*constant.arraySize*/;
+        uniform->vs.registerCount = uniform->registerCount();
     }
     else UNREACHABLE();
 
     if (location >= 0)
     {
-        return uniform->type == type;
+        return uniform->type == constant.type;
     }
 
     mUniforms.push_back(uniform);
     unsigned int uniformIndex = mUniforms.size() - 1;
 
-    for (unsigned int i = 0; i < uniform->arraySize; i++)
+    for (unsigned int i = 0; i < uniform->elementCount(); i++)
     {
         mUniformIndex.push_back(UniformLocation(constant.name, i, uniformIndex));
     }
@@ -2339,7 +2343,7 @@
         }
     }
 
-    *size = mUniforms[index]->arraySize;
+    *size = mUniforms[index]->elementCount();
 
     *type = mUniforms[index]->type;
 }