Implement D3DConstantTable.

Remove ProgramBinary dependencies on D3DX.
Review URL: https://codereview.appspot.com/6485061

git-svn-id: https://angleproject.googlecode.com/svn/trunk@1271 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 61a272f..fc7ea4e 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -108,15 +108,8 @@
         mVertexExecutable->Release();
     }
 
-    if (mConstantTablePS)
-    {
-        mConstantTablePS->Release();
-    }
-
-    if (mConstantTableVS)
-    {
-        mConstantTableVS->Release();
-    }
+    delete mConstantTablePS;
+    delete mConstantTableVS;
 
     while (!mUniforms.empty())
     {
@@ -1036,7 +1029,7 @@
 }
 
 // Compiles the HLSL code of the attached shaders into executable binaries
-ID3D10Blob *ProgramBinary::compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, ID3DXConstantTable **constantTable)
+ID3D10Blob *ProgramBinary::compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, D3DConstantTable **constantTable)
 {
     if (!hlsl)
     {
@@ -1090,21 +1083,17 @@
 
         return NULL;
     }
-
-    result = D3DXGetShaderConstantTable(static_cast<const DWORD*>(binary->GetBufferPointer()), constantTable);
-
-    if (FAILED(result))
+    
+    D3DConstantTable *table = new D3DConstantTable(binary->GetBufferPointer(), binary->GetBufferSize());
+    if (table->error())
     {
-        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-        {
-            error(GL_OUT_OF_MEMORY);
-        }
-
+        delete table;
         binary->Release();
-
         return NULL;
     }
 
+    *constantTable = table;
+    
     return binary;
 }
 
@@ -2030,22 +2019,13 @@
     return true;
 }
 
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, GLenum shader, ID3DXConstantTable *constantTable)
+bool ProgramBinary::linkUniforms(InfoLog &infoLog, GLenum shader, D3DConstantTable *constantTable)
 {
-    D3DXCONSTANTTABLE_DESC constantTableDescription;
-
-    constantTable->GetDesc(&constantTableDescription);
-
-    for (unsigned int constantIndex = 0; constantIndex < constantTableDescription.Constants; constantIndex++)
+    for (unsigned int constantIndex = 0; constantIndex < constantTable->constants(); constantIndex++)
     {
-        D3DXHANDLE constantHandle = constantTable->GetConstant(0, constantIndex);
+        const D3DConstant *constant = constantTable->getConstant(constantIndex);
 
-        D3DXCONSTANT_DESC constantDescription;
-        UINT descriptionCount = 1;
-        HRESULT result = constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount);
-        ASSERT(SUCCEEDED(result));
-
-        if (!defineUniform(infoLog, shader, constantHandle, constantDescription))
+        if (!defineUniform(infoLog, shader, constant))
         {
             return false;
         }
@@ -2056,23 +2036,23 @@
 
 // Adds the description of a constant found in the binary shader to the list of uniforms
 // Returns true if succesful (uniform not already defined)
-bool ProgramBinary::defineUniform(InfoLog &infoLog, GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name)
+bool ProgramBinary::defineUniform(InfoLog &infoLog, GLenum shader, const D3DConstant *constant, std::string name)
 {
-    if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
+    if (constant->registerSet == D3DConstant::RS_SAMPLER)
     {
-        for (unsigned int i = 0; i < constantDescription.RegisterCount; i++)
+        for (unsigned int i = 0; i < constant->registerCount; i++)
         {
-            D3DXHANDLE psConstant = mConstantTablePS->GetConstantByName(NULL, constantDescription.Name);
-            D3DXHANDLE vsConstant = mConstantTableVS->GetConstantByName(NULL, constantDescription.Name);
+            const D3DConstant *psConstant = mConstantTablePS->getConstantByName(constant->name.c_str());
+            const D3DConstant *vsConstant = mConstantTableVS->getConstantByName(constant->name.c_str());
 
             if (psConstant)
             {
-                unsigned int samplerIndex = mConstantTablePS->GetSamplerIndex(psConstant) + i;
+                unsigned int samplerIndex = psConstant->registerIndex + i;
 
                 if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
                 {
                     mSamplersPS[samplerIndex].active = true;
-                    mSamplersPS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
+                    mSamplersPS[samplerIndex].textureType = (constant->type == D3DConstant::PT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
                     mSamplersPS[samplerIndex].logicalTextureUnit = 0;
                     mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange);
                 }
@@ -2085,12 +2065,12 @@
             
             if (vsConstant)
             {
-                unsigned int samplerIndex = mConstantTableVS->GetSamplerIndex(vsConstant) + i;
+                unsigned int samplerIndex = vsConstant->registerIndex + i;
 
                 if (samplerIndex < getContext()->getMaximumVertexTextureImageUnits())
                 {
                     mSamplersVS[samplerIndex].active = true;
-                    mSamplersVS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
+                    mSamplersVS[samplerIndex].textureType = (constant->type == D3DConstant::PT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
                     mSamplersVS[samplerIndex].logicalTextureUnit = 0;
                     mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange);
                 }
@@ -2103,27 +2083,19 @@
         }
     }
 
-    switch(constantDescription.Class)
+    switch(constant->typeClass)
     {
-      case D3DXPC_STRUCT:
+      case D3DConstant::CLASS_STRUCT:
         {
-            for (unsigned int arrayIndex = 0; arrayIndex < constantDescription.Elements; arrayIndex++)
+            for (unsigned int arrayIndex = 0; arrayIndex < constant->elements; arrayIndex++)
             {
-                D3DXHANDLE elementHandle = mConstantTablePS->GetConstantElement(constantHandle, arrayIndex);
-
-                for (unsigned int field = 0; field < constantDescription.StructMembers; field++)
+                for (unsigned int field = 0; field < constant->structMembers[arrayIndex].size(); field++)
                 {
-                    D3DXHANDLE fieldHandle = mConstantTablePS->GetConstant(elementHandle, field);
+                    const D3DConstant *fieldConstant = constant->structMembers[arrayIndex][field];
 
-                    D3DXCONSTANT_DESC fieldDescription;
-                    UINT descriptionCount = 1;
+                    std::string structIndex = (fieldConstant->elements > 1) ? ("[" + str(arrayIndex) + "]") : "";
 
-                    HRESULT result = mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount);
-                    ASSERT(SUCCEEDED(result));
-
-                    std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : "";
-
-                    if (!defineUniform(infoLog, shader, fieldHandle, fieldDescription, name + constantDescription.Name + structIndex + "."))
+                    if (!defineUniform(infoLog, shader, fieldConstant, name + constant->name + structIndex + "."))
                     {
                         return false;
                     }
@@ -2132,20 +2104,20 @@
 
             return true;
         }
-      case D3DXPC_SCALAR:
-      case D3DXPC_VECTOR:
-      case D3DXPC_MATRIX_COLUMNS:
-      case D3DXPC_OBJECT:
-        return defineUniform(shader, constantDescription, name + constantDescription.Name);
+      case D3DConstant::CLASS_SCALAR:
+      case D3DConstant::CLASS_VECTOR:
+      case D3DConstant::CLASS_MATRIX_COLUMNS:
+      case D3DConstant::CLASS_OBJECT:
+        return defineUniform(shader, constant, name + constant->name);
       default:
         UNREACHABLE();
         return false;
     }
 }
 
-bool ProgramBinary::defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDescription, const std::string &_name)
+bool ProgramBinary::defineUniform(GLenum shader, const D3DConstant *constant, const std::string &_name)
 {
-    Uniform *uniform = createUniform(constantDescription, _name);
+    Uniform *uniform = createUniform(constant, _name);
 
     if(!uniform)
     {
@@ -2162,8 +2134,8 @@
         uniform = mUniforms[mUniformIndex[location].index];
     }
 
-    if (shader == GL_FRAGMENT_SHADER) uniform->ps.set(constantDescription);
-    if (shader == GL_VERTEX_SHADER)   uniform->vs.set(constantDescription);
+    if (shader == GL_FRAGMENT_SHADER) uniform->ps.set(constant);
+    if (shader == GL_VERTEX_SHADER)   uniform->vs.set(constant);
 
     if (location >= 0)
     {
@@ -2181,53 +2153,53 @@
     return true;
 }
 
-Uniform *ProgramBinary::createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name)
+Uniform *ProgramBinary::createUniform(const D3DConstant *constant, const std::string &_name)
 {
-    if (constantDescription.Rows == 1)   // Vectors and scalars
+    if (constant->rows == 1)   // Vectors and scalars
     {
-        switch (constantDescription.Type)
+        switch (constant->type)
         {
-          case D3DXPT_SAMPLER2D:
-            switch (constantDescription.Columns)
+          case D3DConstant::PT_SAMPLER2D:
+            switch (constant->columns)
             {
-              case 1: return new Uniform(GL_SAMPLER_2D, _name, constantDescription.Elements);
+              case 1: return new Uniform(GL_SAMPLER_2D, _name, constant->elements);
               default: UNREACHABLE();
             }
             break;
-          case D3DXPT_SAMPLERCUBE:
-            switch (constantDescription.Columns)
+          case D3DConstant::PT_SAMPLERCUBE:
+            switch (constant->columns)
             {
-              case 1: return new Uniform(GL_SAMPLER_CUBE, _name, constantDescription.Elements);
+              case 1: return new Uniform(GL_SAMPLER_CUBE, _name, constant->elements);
               default: UNREACHABLE();
             }
             break;
-          case D3DXPT_BOOL:
-            switch (constantDescription.Columns)
+          case D3DConstant::PT_BOOL:
+            switch (constant->columns)
             {
-              case 1: return new Uniform(GL_BOOL, _name, constantDescription.Elements);
-              case 2: return new Uniform(GL_BOOL_VEC2, _name, constantDescription.Elements);
-              case 3: return new Uniform(GL_BOOL_VEC3, _name, constantDescription.Elements);
-              case 4: return new Uniform(GL_BOOL_VEC4, _name, constantDescription.Elements);
+              case 1: return new Uniform(GL_BOOL, _name, constant->elements);
+              case 2: return new Uniform(GL_BOOL_VEC2, _name, constant->elements);
+              case 3: return new Uniform(GL_BOOL_VEC3, _name, constant->elements);
+              case 4: return new Uniform(GL_BOOL_VEC4, _name, constant->elements);
               default: UNREACHABLE();
             }
             break;
-          case D3DXPT_INT:
-            switch (constantDescription.Columns)
+          case D3DConstant::PT_INT:
+            switch (constant->columns)
             {
-              case 1: return new Uniform(GL_INT, _name, constantDescription.Elements);
-              case 2: return new Uniform(GL_INT_VEC2, _name, constantDescription.Elements);
-              case 3: return new Uniform(GL_INT_VEC3, _name, constantDescription.Elements);
-              case 4: return new Uniform(GL_INT_VEC4, _name, constantDescription.Elements);
+              case 1: return new Uniform(GL_INT, _name, constant->elements);
+              case 2: return new Uniform(GL_INT_VEC2, _name, constant->elements);
+              case 3: return new Uniform(GL_INT_VEC3, _name, constant->elements);
+              case 4: return new Uniform(GL_INT_VEC4, _name, constant->elements);
               default: UNREACHABLE();
             }
             break;
-          case D3DXPT_FLOAT:
-            switch (constantDescription.Columns)
+          case D3DConstant::PT_FLOAT:
+            switch (constant->columns)
             {
-              case 1: return new Uniform(GL_FLOAT, _name, constantDescription.Elements);
-              case 2: return new Uniform(GL_FLOAT_VEC2, _name, constantDescription.Elements);
-              case 3: return new Uniform(GL_FLOAT_VEC3, _name, constantDescription.Elements);
-              case 4: return new Uniform(GL_FLOAT_VEC4, _name, constantDescription.Elements);
+              case 1: return new Uniform(GL_FLOAT, _name, constant->elements);
+              case 2: return new Uniform(GL_FLOAT_VEC2, _name, constant->elements);
+              case 3: return new Uniform(GL_FLOAT_VEC3, _name, constant->elements);
+              case 4: return new Uniform(GL_FLOAT_VEC4, _name, constant->elements);
               default: UNREACHABLE();
             }
             break;
@@ -2235,16 +2207,16 @@
             UNREACHABLE();
         }
     }
-    else if (constantDescription.Rows == constantDescription.Columns)  // Square matrices
+    else if (constant->rows == constant->columns)  // Square matrices
     {
-        switch (constantDescription.Type)
+        switch (constant->type)
         {
-          case D3DXPT_FLOAT:
-            switch (constantDescription.Rows)
+          case D3DConstant::PT_FLOAT:
+            switch (constant->rows)
             {
-              case 2: return new Uniform(GL_FLOAT_MAT2, _name, constantDescription.Elements);
-              case 3: return new Uniform(GL_FLOAT_MAT3, _name, constantDescription.Elements);
-              case 4: return new Uniform(GL_FLOAT_MAT4, _name, constantDescription.Elements);
+              case 2: return new Uniform(GL_FLOAT_MAT2, _name, constant->elements);
+              case 3: return new Uniform(GL_FLOAT_MAT3, _name, constant->elements);
+              case 4: return new Uniform(GL_FLOAT_MAT4, _name, constant->elements);
               default: UNREACHABLE();
             }
             break;
@@ -2366,11 +2338,11 @@
 bool ProgramBinary::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v)
 {
     ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
-    D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
+    Vector4 vector[D3D9_MAX_FLOAT_CONSTANTS];
 
     for (int i = 0; i < count; i++)
     {
-        vector[i] = D3DXVECTOR4((float)v[i], 0, 0, 0);
+        vector[i] = Vector4((float)v[i], 0, 0, 0);
     }
 
     if (targetUniform->ps.registerCount)
@@ -2427,11 +2399,11 @@
 bool ProgramBinary::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v)
 {
     ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
-    D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
+    Vector4 vector[D3D9_MAX_FLOAT_CONSTANTS];
 
     for (int i = 0; i < count; i++)
     {
-        vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], 0, 0);
+        vector[i] = Vector4((float)v[0], (float)v[1], 0, 0);
 
         v += 2;
     }
@@ -2444,11 +2416,11 @@
 bool ProgramBinary::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v)
 {
     ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
-    D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
+    Vector4 vector[D3D9_MAX_FLOAT_CONSTANTS];
 
     for (int i = 0; i < count; i++)
     {
-        vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], (float)v[2], 0);
+        vector[i] = Vector4((float)v[0], (float)v[1], (float)v[2], 0);
 
         v += 3;
     }
@@ -2461,11 +2433,11 @@
 bool ProgramBinary::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v)
 {
     ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
-    D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
+    Vector4 vector[D3D9_MAX_FLOAT_CONSTANTS];
 
     for (int i = 0; i < count; i++)
     {
-        vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], (float)v[2], (float)v[3]);
+        vector[i] = Vector4((float)v[0], (float)v[1], (float)v[2], (float)v[3]);
 
         v += 4;
     }
@@ -2475,7 +2447,7 @@
     return true;
 }
 
-void ProgramBinary::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector)
+void ProgramBinary::applyUniformniv(Uniform *targetUniform, GLsizei count, const Vector4 *vector)
 {
     if (targetUniform->ps.registerCount)
     {