diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
new file mode 100644
index 0000000..081f7be
--- /dev/null
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -0,0 +1,2583 @@
+//
+// Copyright (c) 2002-2012 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.
+//
+
+// Program.cpp: Implements the gl::Program class. Implements GL program objects
+// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
+
+#include "libGLESv2/Program.h"
+#include "libGLESv2/ProgramBinary.h"
+
+#include "common/debug.h"
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/Shader.h"
+#include "libGLESv2/utilities.h"
+
+#include <string>
+
+#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
+#endif
+
+namespace gl
+{
+const char *fakepath = "C:\\fakepath";
+
+std::string str(int i)
+{
+    char buffer[20];
+    snprintf(buffer, sizeof(buffer), "%d", i);
+    return buffer;
+}
+
+Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize)
+    : type(type), _name(_name), name(ProgramBinary::undecorateUniform(_name)), arraySize(arraySize)
+{
+    int bytes = UniformInternalSize(type) * arraySize;
+    data = new unsigned char[bytes];
+    memset(data, 0, bytes);
+    dirty = true;
+}
+
+Uniform::~Uniform()
+{
+    delete[] data;
+}
+
+bool Uniform::isArray()
+{
+    return _name.compare(0, 3, "ar_") == 0;
+}
+
+UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index) 
+    : name(ProgramBinary::undecorateUniform(_name)), element(element), index(index)
+{
+}
+
+ProgramBinary::ProgramBinary()
+{
+    mDevice = getDevice();
+
+    mPixelExecutable = NULL;
+    mVertexExecutable = NULL;
+    mConstantTablePS = NULL;
+    mConstantTableVS = NULL;
+
+    mInfoLog = NULL;
+    mValidated = false;
+
+    for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+    {
+        mSemanticIndex[index] = -1;
+    }
+
+    for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
+    {
+        mSamplersPS[index].active = false;
+    }
+
+    for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++)
+    {
+        mSamplersVS[index].active = false;
+    }
+
+    mUsedVertexSamplerRange = 0;
+    mUsedPixelSamplerRange = 0;
+
+    mDxDepthRangeLocation = -1;
+    mDxDepthLocation = -1;
+    mDxCoordLocation = -1;
+    mDxHalfPixelSizeLocation = -1;
+    mDxFrontCCWLocation = -1;
+    mDxPointsOrLinesLocation = -1;
+}
+
+ProgramBinary::~ProgramBinary()
+{
+    if (mPixelExecutable)
+    {
+        mPixelExecutable->Release();
+    }
+
+    if (mVertexExecutable)
+    {
+        mVertexExecutable->Release();
+    }
+
+    if (mConstantTablePS)
+    {
+        mConstantTablePS->Release();
+    }
+
+    if (mConstantTableVS)
+    {
+        mConstantTableVS->Release();
+    }
+
+    while (!mUniforms.empty())
+    {
+        delete mUniforms.back();
+        mUniforms.pop_back();
+    }
+
+    delete[] mInfoLog;
+}
+
+IDirect3DPixelShader9 *ProgramBinary::getPixelShader()
+{
+    return mPixelExecutable;
+}
+
+IDirect3DVertexShader9 *ProgramBinary::getVertexShader()
+{
+    return mVertexExecutable;
+}
+
+GLuint ProgramBinary::getAttributeLocation(const char *name)
+{
+    if (name)
+    {
+        for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+        {
+            if (mLinkedAttribute[index].name == std::string(name))
+            {
+                return index;
+            }
+        }
+    }
+
+    return -1;
+}
+
+int ProgramBinary::getSemanticIndex(int attributeIndex)
+{
+    ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
+    
+    return mSemanticIndex[attributeIndex];
+}
+
+// Returns one more than the highest sampler index used.
+GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
+{
+    switch (type)
+    {
+      case SAMPLER_PIXEL:
+        return mUsedPixelSamplerRange;
+      case SAMPLER_VERTEX:
+        return mUsedVertexSamplerRange;
+      default:
+        UNREACHABLE();
+        return 0;
+    }
+}
+
+// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
+// index (0-15 for the pixel shader and 0-3 for the vertex shader).
+GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
+{
+    GLint logicalTextureUnit = -1;
+
+    switch (type)
+    {
+      case SAMPLER_PIXEL:
+        ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
+
+        if (mSamplersPS[samplerIndex].active)
+        {
+            logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
+        }
+        break;
+      case SAMPLER_VERTEX:
+        ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
+
+        if (mSamplersVS[samplerIndex].active)
+        {
+            logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
+        }
+        break;
+      default: UNREACHABLE();
+    }
+
+    if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)getContext()->getMaximumCombinedTextureImageUnits())
+    {
+        return logicalTextureUnit;
+    }
+
+    return -1;
+}
+
+// Returns the texture type for a given Direct3D 9 sampler type and
+// index (0-15 for the pixel shader and 0-3 for the vertex shader).
+TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
+{
+    switch (type)
+    {
+      case SAMPLER_PIXEL:
+        ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
+        ASSERT(mSamplersPS[samplerIndex].active);
+        return mSamplersPS[samplerIndex].textureType;
+      case SAMPLER_VERTEX:
+        ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
+        ASSERT(mSamplersVS[samplerIndex].active);
+        return mSamplersVS[samplerIndex].textureType;
+      default: UNREACHABLE();
+    }
+
+    return TEXTURE_2D;
+}
+
+GLint ProgramBinary::getUniformLocation(std::string name)
+{
+    unsigned int subscript = 0;
+
+    // Strip any trailing array operator and retrieve the subscript
+    size_t open = name.find_last_of('[');
+    size_t close = name.find_last_of(']');
+    if (open != std::string::npos && close == name.length() - 1)
+    {
+        subscript = atoi(name.substr(open + 1).c_str());
+        name.erase(open);
+    }
+
+    unsigned int numUniforms = mUniformIndex.size();
+    for (unsigned int location = 0; location < numUniforms; location++)
+    {
+        if (mUniformIndex[location].name == name &&
+            mUniformIndex[location].element == subscript)
+        {
+            return location;
+        }
+    }
+
+    return -1;
+}
+
+bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type == GL_FLOAT)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
+
+        for (int i = 0; i < count; i++)
+        {
+            target[0] = v[0];
+            target[1] = 0;
+            target[2] = 0;
+            target[3] = 0;
+            target += 4;
+            v += 1;
+        }
+    }
+    else if (targetUniform->type == GL_BOOL)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+        GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element;
+
+        for (int i = 0; i < count; ++i)
+        {
+            if (v[i] == 0.0f)
+            {
+                boolParams[i] = GL_FALSE;
+            }
+            else
+            {
+                boolParams[i] = GL_TRUE;
+            }
+        }
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type == GL_FLOAT_VEC2)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
+
+        for (int i = 0; i < count; i++)
+        {
+            target[0] = v[0];
+            target[1] = v[1];
+            target[2] = 0;
+            target[3] = 0;
+            target += 4;
+            v += 2;
+        }
+    }
+    else if (targetUniform->type == GL_BOOL_VEC2)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2;
+
+        for (int i = 0; i < count * 2; ++i)
+        {
+            if (v[i] == 0.0f)
+            {
+                boolParams[i] = GL_FALSE;
+            }
+            else
+            {
+                boolParams[i] = GL_TRUE;
+            }
+        }
+    }
+    else 
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type == GL_FLOAT_VEC3)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
+
+        for (int i = 0; i < count; i++)
+        {
+            target[0] = v[0];
+            target[1] = v[1];
+            target[2] = v[2];
+            target[3] = 0;
+            target += 4;
+            v += 3;
+        }
+    }
+    else if (targetUniform->type == GL_BOOL_VEC3)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+        GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3;
+
+        for (int i = 0; i < count * 3; ++i)
+        {
+            if (v[i] == 0.0f)
+            {
+                boolParams[i] = GL_FALSE;
+            }
+            else
+            {
+                boolParams[i] = GL_TRUE;
+            }
+        }
+    }
+    else 
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type == GL_FLOAT_VEC4)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        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;
+
+        if (arraySize == 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);
+        GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4;
+
+        for (int i = 0; i < count * 4; ++i)
+        {
+            if (v[i] == 0.0f)
+            {
+                boolParams[i] = GL_FALSE;
+            }
+            else
+            {
+                boolParams[i] = GL_TRUE;
+            }
+        }
+    }
+    else 
+    {
+        return false;
+    }
+
+    return true;
+}
+
+template<typename T, int targetWidth, int targetHeight, int srcWidth, int srcHeight>
+void transposeMatrix(T *target, const GLfloat *value)
+{
+    int copyWidth = std::min(targetWidth, srcWidth);
+    int copyHeight = std::min(targetHeight, srcHeight);
+
+    for (int x = 0; x < copyWidth; x++)
+    {
+        for (int y = 0; y < copyHeight; y++)
+        {
+            target[x * targetWidth + y] = (T)value[y * srcWidth + x];
+        }
+    }
+    // clear unfilled right side
+    for (int y = 0; y < copyHeight; y++)
+    {
+        for (int x = srcWidth; x < targetWidth; x++)
+        {
+            target[y * targetWidth + x] = (T)0;
+        }
+    }
+    // clear unfilled bottom.
+    for (int y = srcHeight; y < targetHeight; y++)
+    {
+        for (int x = 0; x < targetWidth; x++)
+        {
+            target[y * targetWidth + x] = (T)0;
+        }
+    }
+}
+
+bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type != GL_FLOAT_MAT2)
+    {
+        return false;
+    }
+
+    int arraySize = targetUniform->arraySize;
+
+    if (arraySize == 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);
+
+    GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8;
+    for (int i = 0; i < count; i++)
+    {
+        transposeMatrix<GLfloat,4,2,2,2>(target, value);
+        target += 8;
+        value += 4;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type != GL_FLOAT_MAT3)
+    {
+        return false;
+    }
+
+    int arraySize = targetUniform->arraySize;
+
+    if (arraySize == 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);
+
+    GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12;
+    for (int i = 0; i < count; i++)
+    {
+        transposeMatrix<GLfloat,4,3,3,3>(target, value);
+        target += 12;
+        value += 9;
+    }
+
+    return true;
+}
+
+
+bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type != GL_FLOAT_MAT4)
+    {
+        return false;
+    }
+
+    int arraySize = targetUniform->arraySize;
+
+    if (arraySize == 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);
+
+    GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16);
+    for (int i = 0; i < count; i++)
+    {
+        transposeMatrix<GLfloat,4,4,4,4>(target, value);
+        target += 16;
+        value += 16;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type == GL_INT ||
+        targetUniform->type == GL_SAMPLER_2D ||
+        targetUniform->type == GL_SAMPLER_CUBE)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint),
+               v, sizeof(GLint) * count);
+    }
+    else if (targetUniform->type == GL_BOOL)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+        GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element;
+
+        for (int i = 0; i < count; ++i)
+        {
+            if (v[i] == 0)
+            {
+                boolParams[i] = GL_FALSE;
+            }
+            else
+            {
+                boolParams[i] = GL_TRUE;
+            }
+        }
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type == GL_INT_VEC2)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        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;
+
+        if (arraySize == 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);
+        GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2;
+
+        for (int i = 0; i < count * 2; ++i)
+        {
+            if (v[i] == 0)
+            {
+                boolParams[i] = GL_FALSE;
+            }
+            else
+            {
+                boolParams[i] = GL_TRUE;
+            }
+        }
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type == GL_INT_VEC3)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        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;
+
+        if (arraySize == 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);
+        GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3;
+
+        for (int i = 0; i < count * 3; ++i)
+        {
+            if (v[i] == 0)
+            {
+                boolParams[i] = GL_FALSE;
+            }
+            else
+            {
+                boolParams[i] = GL_TRUE;
+            }
+        }
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+    targetUniform->dirty = true;
+
+    if (targetUniform->type == GL_INT_VEC4)
+    {
+        int arraySize = targetUniform->arraySize;
+
+        if (arraySize == 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);
+
+        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;
+
+        if (arraySize == 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);
+        GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4;
+
+        for (int i = 0; i < count * 4; ++i)
+        {
+            if (v[i] == 0)
+            {
+                boolParams[i] = GL_FALSE;
+            }
+            else
+            {
+                boolParams[i] = GL_TRUE;
+            }
+        }
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+
+    // sized queries -- ensure the provided buffer is large enough
+    if (bufSize)
+    {
+        int requiredBytes = UniformExternalSize(targetUniform->type);
+        if (*bufSize < requiredBytes)
+        {
+            return false;
+        }
+    }
+
+    switch (targetUniform->type)
+    {
+      case GL_FLOAT_MAT2:
+        transposeMatrix<GLfloat,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8);
+        break;
+      case GL_FLOAT_MAT3:
+        transposeMatrix<GLfloat,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12);
+        break;
+      case GL_FLOAT_MAT4:
+        transposeMatrix<GLfloat,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16);
+        break;
+      default:
+        {
+            unsigned int count = UniformExternalComponentCount(targetUniform->type);
+            unsigned int internalCount = UniformInternalComponentCount(targetUniform->type);
+
+            switch (UniformComponentType(targetUniform->type))
+            {
+              case GL_BOOL:
+                {
+                    GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * internalCount;
+
+                    for (unsigned int i = 0; i < count; ++i)
+                    {
+                        params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
+                    }
+                }
+                break;
+              case GL_FLOAT:
+                memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLfloat),
+                       count * sizeof(GLfloat));
+                break;
+              case GL_INT:
+                {
+                    GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * internalCount;
+
+                    for (unsigned int i = 0; i < count; ++i)
+                    {
+                        params[i] = (float)intParams[i];
+                    }
+                }
+                break;
+              default: UNREACHABLE();
+            }
+        }
+    }
+
+    return true;
+}
+
+bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
+{
+    if (location < 0 || location >= (int)mUniformIndex.size())
+    {
+        return false;
+    }
+
+    Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
+
+    // sized queries -- ensure the provided buffer is large enough
+    if (bufSize)
+    {
+        int requiredBytes = UniformExternalSize(targetUniform->type);
+        if (*bufSize < requiredBytes)
+        {
+            return false;
+        }
+    }
+
+    switch (targetUniform->type)
+    {
+      case GL_FLOAT_MAT2:
+        {
+            transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8);
+        }
+        break;
+      case GL_FLOAT_MAT3:
+        {
+            transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12);
+        }
+        break;
+      case GL_FLOAT_MAT4:
+        {
+            transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16);
+        }
+        break;
+      default:
+        {
+            unsigned int count = UniformExternalComponentCount(targetUniform->type);
+            unsigned int internalCount = UniformInternalComponentCount(targetUniform->type);
+
+            switch (UniformComponentType(targetUniform->type))
+            {
+              case GL_BOOL:
+                {
+                    GLboolean *boolParams = targetUniform->data + mUniformIndex[location].element * internalCount;
+
+                    for (unsigned int i = 0; i < count; ++i)
+                    {
+                        params[i] = (GLint)boolParams[i];
+                    }
+                }
+                break;
+              case GL_FLOAT:
+                {
+                    GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * internalCount;
+
+                    for (unsigned int i = 0; i < count; ++i)
+                    {
+                        params[i] = (GLint)floatParams[i];
+                    }
+                }
+                break;
+              case GL_INT:
+                memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLint),
+                       count * sizeof(GLint));
+                break;
+              default: UNREACHABLE();
+            }
+        }
+    }
+
+    return true;
+}
+
+void ProgramBinary::dirtyAllUniforms()
+{
+    unsigned int numUniforms = mUniforms.size();
+    for (unsigned int index = 0; index < numUniforms; index++)
+    {
+        mUniforms[index]->dirty = true;
+    }
+}
+
+// Applies all the uniforms set for this program object to the Direct3D 9 device
+void ProgramBinary::applyUniforms()
+{
+    for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) {
+        Uniform *targetUniform = *ub;
+
+        if (targetUniform->dirty)
+        {
+            int arraySize = targetUniform->arraySize;
+            GLfloat *f = (GLfloat*)targetUniform->data;
+            GLint *i = (GLint*)targetUniform->data;
+            GLboolean *b = (GLboolean*)targetUniform->data;
+
+            switch (targetUniform->type)
+            {
+              case GL_BOOL:       applyUniformnbv(targetUniform, arraySize, 1, b);    break;
+              case GL_BOOL_VEC2:  applyUniformnbv(targetUniform, arraySize, 2, b);    break;
+              case GL_BOOL_VEC3:  applyUniformnbv(targetUniform, arraySize, 3, b);    break;
+              case GL_BOOL_VEC4:  applyUniformnbv(targetUniform, arraySize, 4, b);    break;
+              case GL_FLOAT:
+              case GL_FLOAT_VEC2:
+              case GL_FLOAT_VEC3:
+              case GL_FLOAT_VEC4:
+              case GL_FLOAT_MAT2:
+              case GL_FLOAT_MAT3:
+              case GL_FLOAT_MAT4: applyUniformnfv(targetUniform, f);                  break;
+              case GL_SAMPLER_2D:
+              case GL_SAMPLER_CUBE:
+              case GL_INT:        applyUniform1iv(targetUniform, arraySize, i);       break;
+              case GL_INT_VEC2:   applyUniform2iv(targetUniform, arraySize, i);       break;
+              case GL_INT_VEC3:   applyUniform3iv(targetUniform, arraySize, i);       break;
+              case GL_INT_VEC4:   applyUniform4iv(targetUniform, arraySize, i);       break;
+              default:
+                UNREACHABLE();
+            }
+
+            targetUniform->dirty = false;
+        }
+    }
+}
+
+// Compiles the HLSL code of the attached shaders into executable binaries
+ID3D10Blob *ProgramBinary::compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable)
+{
+    if (!hlsl)
+    {
+        return NULL;
+    }
+
+    DWORD result;
+    UINT flags = 0;
+    std::string sourceText;
+    if (perfActive())
+    {
+        flags |= D3DCOMPILE_DEBUG;
+#ifdef NDEBUG
+        flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
+#else
+        flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
+#endif
+
+        std::string sourcePath = getTempPath();
+        sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
+        writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
+    }
+    else
+    {
+        flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
+        sourceText = hlsl;
+    }
+
+    ID3D10Blob *binary = NULL;
+    ID3D10Blob *errorMessage = NULL;
+    result = D3DCompile(hlsl, strlen(hlsl), fakepath, NULL, NULL, "main", profile, flags, 0, &binary, &errorMessage);
+
+    if (errorMessage)
+    {
+        const char *message = (const char*)errorMessage->GetBufferPointer();
+
+        appendToInfoLogSanitized(message);
+        TRACE("\n%s", hlsl);
+        TRACE("\n%s", message);
+
+        errorMessage->Release();
+        errorMessage = NULL;
+    }
+
+    if (FAILED(result))
+    {
+        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+        {
+            error(GL_OUT_OF_MEMORY);
+        }
+
+        return NULL;
+    }
+
+    result = D3DXGetShaderConstantTable(static_cast<const DWORD*>(binary->GetBufferPointer()), constantTable);
+
+    if (FAILED(result))
+    {
+        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+        {
+            error(GL_OUT_OF_MEMORY);
+        }
+
+        binary->Release();
+
+        return NULL;
+    }
+
+    return binary;
+}
+
+// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
+// Returns the number of used varying registers, or -1 if unsuccesful
+int ProgramBinary::packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader)
+{
+    Context *context = getContext();
+    const int maxVaryingVectors = context->getMaximumVaryingVectors();
+
+    for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
+    {
+        int n = VariableRowCount(varying->type) * varying->size;
+        int m = VariableColumnCount(varying->type);
+        bool success = false;
+
+        if (m == 2 || m == 3 || m == 4)
+        {
+            for (int r = 0; r <= maxVaryingVectors - n && !success; r++)
+            {
+                bool available = true;
+
+                for (int y = 0; y < n && available; y++)
+                {
+                    for (int x = 0; x < m && available; x++)
+                    {
+                        if (packing[r + y][x])
+                        {
+                            available = false;
+                        }
+                    }
+                }
+
+                if (available)
+                {
+                    varying->reg = r;
+                    varying->col = 0;
+
+                    for (int y = 0; y < n; y++)
+                    {
+                        for (int x = 0; x < m; x++)
+                        {
+                            packing[r + y][x] = &*varying;
+                        }
+                    }
+
+                    success = true;
+                }
+            }
+
+            if (!success && m == 2)
+            {
+                for (int r = maxVaryingVectors - n; r >= 0 && !success; r--)
+                {
+                    bool available = true;
+
+                    for (int y = 0; y < n && available; y++)
+                    {
+                        for (int x = 2; x < 4 && available; x++)
+                        {
+                            if (packing[r + y][x])
+                            {
+                                available = false;
+                            }
+                        }
+                    }
+
+                    if (available)
+                    {
+                        varying->reg = r;
+                        varying->col = 2;
+
+                        for (int y = 0; y < n; y++)
+                        {
+                            for (int x = 2; x < 4; x++)
+                            {
+                                packing[r + y][x] = &*varying;
+                            }
+                        }
+
+                        success = true;
+                    }
+                }
+            }
+        }
+        else if (m == 1)
+        {
+            int space[4] = {0};
+
+            for (int y = 0; y < maxVaryingVectors; y++)
+            {
+                for (int x = 0; x < 4; x++)
+                {
+                    space[x] += packing[y][x] ? 0 : 1;
+                }
+            }
+
+            int column = 0;
+
+            for (int x = 0; x < 4; x++)
+            {
+                if (space[x] >= n && space[x] < space[column])
+                {
+                    column = x;
+                }
+            }
+
+            if (space[column] >= n)
+            {
+                for (int r = 0; r < maxVaryingVectors; r++)
+                {
+                    if (!packing[r][column])
+                    {
+                        varying->reg = r;
+
+                        for (int y = r; y < r + n; y++)
+                        {
+                            packing[y][column] = &*varying;
+                        }
+
+                        break;
+                    }
+                }
+
+                varying->col = column;
+
+                success = true;
+            }
+        }
+        else UNREACHABLE();
+
+        if (!success)
+        {
+            appendToInfoLog("Could not pack varying %s", varying->name.c_str());
+
+            return -1;
+        }
+    }
+
+    // Return the number of used registers
+    int registers = 0;
+
+    for (int r = 0; r < maxVaryingVectors; r++)
+    {
+        if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
+        {
+            registers++;
+        }
+    }
+
+    return registers;
+}
+
+bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader)
+{
+    if (pixelHLSL.empty() || vertexHLSL.empty())
+    {
+        return false;
+    }
+
+    // Reset the varying register assignments
+    for (VaryingList::iterator fragVar = fragmentShader->mVaryings.begin(); fragVar != fragmentShader->mVaryings.end(); fragVar++)
+    {
+        fragVar->reg = -1;
+        fragVar->col = -1;
+    }
+
+    for (VaryingList::iterator vtxVar = vertexShader->mVaryings.begin(); vtxVar != vertexShader->mVaryings.end(); vtxVar++)
+    {
+        vtxVar->reg = -1;
+        vtxVar->col = -1;
+    }
+
+    // Map the varyings to the register file
+    const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL};
+    int registers = packVaryings(packing, fragmentShader);
+
+    if (registers < 0)
+    {
+        return false;
+    }
+
+    // Write the HLSL input/output declarations
+    Context *context = getContext();
+    const bool sm3 = context->supportsShaderModel3();
+    const int maxVaryingVectors = context->getMaximumVaryingVectors();
+
+    if (registers == maxVaryingVectors && fragmentShader->mUsesFragCoord)
+    {
+        appendToInfoLog("No varying registers left to support gl_FragCoord");
+
+        return false;
+    }
+
+    for (VaryingList::iterator input = fragmentShader->mVaryings.begin(); input != fragmentShader->mVaryings.end(); input++)
+    {
+        bool matched = false;
+
+        for (VaryingList::iterator output = vertexShader->mVaryings.begin(); output != vertexShader->mVaryings.end(); output++)
+        {
+            if (output->name == input->name)
+            {
+                if (output->type != input->type || output->size != input->size)
+                {
+                    appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
+
+                    return false;
+                }
+
+                output->reg = input->reg;
+                output->col = input->col;
+
+                matched = true;
+                break;
+            }
+        }
+
+        if (!matched)
+        {
+            appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());
+
+            return false;
+        }
+    }
+
+    std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD");
+
+    vertexHLSL += "struct VS_INPUT\n"
+                   "{\n";
+
+    int semanticIndex = 0;
+    for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+    {
+        switch (attribute->type)
+        {
+          case GL_FLOAT:      vertexHLSL += "    float ";    break;
+          case GL_FLOAT_VEC2: vertexHLSL += "    float2 ";   break;
+          case GL_FLOAT_VEC3: vertexHLSL += "    float3 ";   break;
+          case GL_FLOAT_VEC4: vertexHLSL += "    float4 ";   break;
+          case GL_FLOAT_MAT2: vertexHLSL += "    float2x2 "; break;
+          case GL_FLOAT_MAT3: vertexHLSL += "    float3x3 "; break;
+          case GL_FLOAT_MAT4: vertexHLSL += "    float4x4 "; break;
+          default:  UNREACHABLE();
+        }
+
+        vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
+
+        semanticIndex += VariableRowCount(attribute->type);
+    }
+
+    vertexHLSL += "};\n"
+                   "\n"
+                   "struct VS_OUTPUT\n"
+                   "{\n"
+                   "    float4 gl_Position : POSITION;\n";
+
+    for (int r = 0; r < registers; r++)
+    {
+        int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
+
+        vertexHLSL += "    float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
+    }
+
+    if (fragmentShader->mUsesFragCoord)
+    {
+        vertexHLSL += "    float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+    }
+
+    if (vertexShader->mUsesPointSize && sm3)
+    {
+        vertexHLSL += "    float gl_PointSize : PSIZE;\n";
+    }
+
+    vertexHLSL += "};\n"
+                   "\n"
+                   "VS_OUTPUT main(VS_INPUT input)\n"
+                   "{\n";
+
+    for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+    {
+        vertexHLSL += "    " + decorateAttribute(attribute->name) + " = ";
+
+        if (VariableRowCount(attribute->type) > 1)   // Matrix
+        {
+            vertexHLSL += "transpose";
+        }
+
+        vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
+    }
+
+    vertexHLSL += "\n"
+                   "    gl_main();\n"
+                   "\n"
+                   "    VS_OUTPUT output;\n"
+                   "    output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n"
+                   "    output.gl_Position.y = gl_Position.y - dx_HalfPixelSize.y * gl_Position.w;\n"
+                   "    output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+                   "    output.gl_Position.w = gl_Position.w;\n";
+
+    if (vertexShader->mUsesPointSize && sm3)
+    {
+        vertexHLSL += "    output.gl_PointSize = clamp(gl_PointSize, 1.0, " + str((int)ALIASED_POINT_SIZE_RANGE_MAX_SM3) + ");\n";
+    }
+
+    if (fragmentShader->mUsesFragCoord)
+    {
+        vertexHLSL += "    output.gl_FragCoord = gl_Position;\n";
+    }
+
+    for (VaryingList::iterator varying = vertexShader->mVaryings.begin(); varying != vertexShader->mVaryings.end(); varying++)
+    {
+        if (varying->reg >= 0)
+        {
+            for (int i = 0; i < varying->size; i++)
+            {
+                int rows = VariableRowCount(varying->type);
+
+                for (int j = 0; j < rows; j++)
+                {
+                    int r = varying->reg + i * rows + j;
+                    vertexHLSL += "    output.v" + str(r);
+
+                    bool sharedRegister = false;   // Register used by multiple varyings
+                    
+                    for (int x = 0; x < 4; x++)
+                    {
+                        if (packing[r][x] && packing[r][x] != packing[r][0])
+                        {
+                            sharedRegister = true;
+                            break;
+                        }
+                    }
+
+                    if(sharedRegister)
+                    {
+                        vertexHLSL += ".";
+
+                        for (int x = 0; x < 4; x++)
+                        {
+                            if (packing[r][x] == &*varying)
+                            {
+                                switch(x)
+                                {
+                                  case 0: vertexHLSL += "x"; break;
+                                  case 1: vertexHLSL += "y"; break;
+                                  case 2: vertexHLSL += "z"; break;
+                                  case 3: vertexHLSL += "w"; break;
+                                }
+                            }
+                        }
+                    }
+
+                    vertexHLSL += " = " + varying->name;
+                    
+                    if (varying->array)
+                    {
+                        vertexHLSL += "[" + str(i) + "]";
+                    }
+
+                    if (rows > 1)
+                    {
+                        vertexHLSL += "[" + str(j) + "]";
+                    }
+                    
+                    vertexHLSL += ";\n";
+                }
+            }
+        }
+    }
+
+    vertexHLSL += "\n"
+                   "    return output;\n"
+                   "}\n";
+
+    pixelHLSL += "struct PS_INPUT\n"
+                  "{\n";
+    
+    for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
+    {
+        if (varying->reg >= 0)
+        {
+            for (int i = 0; i < varying->size; i++)
+            {
+                int rows = VariableRowCount(varying->type);
+                for (int j = 0; j < rows; j++)
+                {
+                    std::string n = str(varying->reg + i * rows + j);
+                    pixelHLSL += "    float4 v" + n + " : " + varyingSemantic + n + ";\n";
+                }
+            }
+        }
+        else UNREACHABLE();
+    }
+
+    if (fragmentShader->mUsesFragCoord)
+    {
+        pixelHLSL += "    float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+        if (sm3) {
+            pixelHLSL += "    float2 dx_VPos : VPOS;\n";
+        }
+    }
+
+    if (fragmentShader->mUsesPointCoord && sm3)
+    {
+        pixelHLSL += "    float2 gl_PointCoord : TEXCOORD0;\n";
+    }
+
+    if (fragmentShader->mUsesFrontFacing)
+    {
+        pixelHLSL += "    float vFace : VFACE;\n";
+    }
+
+    pixelHLSL += "};\n"
+                  "\n"
+                  "struct PS_OUTPUT\n"
+                  "{\n"
+                  "    float4 gl_Color[1] : COLOR;\n"
+                  "};\n"
+                  "\n"
+                  "PS_OUTPUT main(PS_INPUT input)\n"
+                  "{\n";
+
+    if (fragmentShader->mUsesFragCoord)
+    {
+        pixelHLSL += "    float rhw = 1.0 / input.gl_FragCoord.w;\n";
+        
+        if (sm3)
+        {
+            // dx_Coord.y contains the render target height. See Context::applyRenderTarget()
+            pixelHLSL += "    gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
+                          "    gl_FragCoord.y = dx_Coord.y - input.dx_VPos.y - 0.5;\n";
+        }
+        else
+        {
+            // dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget()
+            pixelHLSL += "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n"
+                          "    gl_FragCoord.y = -(input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n";
+        }
+        
+        pixelHLSL += "    gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
+                      "    gl_FragCoord.w = rhw;\n";
+    }
+
+    if (fragmentShader->mUsesPointCoord && sm3)
+    {
+        pixelHLSL += "    gl_PointCoord = input.gl_PointCoord;\n";
+    }
+
+    if (fragmentShader->mUsesFrontFacing)
+    {
+        pixelHLSL += "    gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
+    }
+
+    for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
+    {
+        if (varying->reg >= 0)
+        {
+            for (int i = 0; i < varying->size; i++)
+            {
+                int rows = VariableRowCount(varying->type);
+                for (int j = 0; j < rows; j++)
+                {
+                    std::string n = str(varying->reg + i * rows + j);
+                    pixelHLSL += "    " + varying->name;
+
+                    if (varying->array)
+                    {
+                        pixelHLSL += "[" + str(i) + "]";
+                    }
+
+                    if (rows > 1)
+                    {
+                        pixelHLSL += "[" + str(j) + "]";
+                    }
+
+                    pixelHLSL += " = input.v" + n + ";\n";
+                }
+            }
+        }
+        else UNREACHABLE();
+    }
+
+    pixelHLSL += "\n"
+                  "    gl_main();\n"
+                  "\n"
+                  "    PS_OUTPUT output;\n"                 
+                  "    output.gl_Color[0] = gl_Color[0];\n"
+                  "\n"
+                  "    return output;\n"
+                  "}\n";
+
+    return true;
+}
+
+bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
+{
+    if (!fragmentShader || !fragmentShader->isCompiled())
+    {
+        return false;
+    }
+
+    if (!vertexShader || !vertexShader->isCompiled())
+    {
+        return false;
+    }
+
+    std::string pixelHLSL = fragmentShader->getHLSL();
+    std::string vertexHLSL = vertexShader->getHLSL();
+
+    if (!linkVaryings(pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
+    {
+        return false;
+    }
+
+    Context *context = getContext();
+    const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0";
+    const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0";
+
+    ID3D10Blob *vertexBinary = compileToBinary(vertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
+    ID3D10Blob *pixelBinary = compileToBinary(pixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
+
+    if (vertexBinary && pixelBinary)
+    {
+        HRESULT vertexResult = mDevice->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable);
+        HRESULT pixelResult = mDevice->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable);
+
+        if (vertexResult == D3DERR_OUTOFVIDEOMEMORY || vertexResult == E_OUTOFMEMORY || pixelResult == D3DERR_OUTOFVIDEOMEMORY || pixelResult == E_OUTOFMEMORY)
+        {
+            return error(GL_OUT_OF_MEMORY, false);
+        }
+
+        ASSERT(SUCCEEDED(vertexResult) && SUCCEEDED(pixelResult));
+
+        vertexBinary->Release();
+        pixelBinary->Release();
+        vertexBinary = NULL;
+        pixelBinary = NULL;
+
+        if (mVertexExecutable && mPixelExecutable)
+        {
+            if (!linkAttributes(attributeBindings, fragmentShader, vertexShader))
+            {
+                return false;
+            }
+
+            if (!linkUniforms(GL_FRAGMENT_SHADER, mConstantTablePS))
+            {
+                return false;
+            }
+
+            if (!linkUniforms(GL_VERTEX_SHADER, mConstantTableVS))
+            {
+                return false;
+            }
+
+            // these uniforms are searched as already-decorated because gl_ and dx_
+            // are reserved prefixes, and do not receive additional decoration
+            mDxDepthRangeLocation = getUniformLocation("dx_DepthRange");
+            mDxDepthLocation = getUniformLocation("dx_Depth");
+            mDxCoordLocation = getUniformLocation("dx_Coord");
+            mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize");
+            mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW");
+            mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines");
+
+            context->markDxUniformsDirty();
+
+            return true;
+        }
+    }
+
+    return false;
+}
+
+// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
+bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
+{
+    unsigned int usedLocations = 0;
+
+    // Link attributes that have a binding location
+    for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+    {
+        int location = attributeBindings.getAttributeBinding(attribute->name);
+
+        if (location != -1)   // Set by glBindAttribLocation
+        {
+            if (!mLinkedAttribute[location].name.empty())
+            {
+                // Multiple active attributes bound to the same location; not an error
+            }
+
+            mLinkedAttribute[location] = *attribute;
+
+            int rows = VariableRowCount(attribute->type);
+
+            if (rows + location > MAX_VERTEX_ATTRIBS)
+            {
+                appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
+
+                return false;
+            }
+
+            for (int i = 0; i < rows; i++)
+            {
+                usedLocations |= 1 << (location + i);
+            }
+        }
+    }
+
+    // Link attributes that don't have a binding location
+    for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+    {
+        int location = attributeBindings.getAttributeBinding(attribute->name);
+
+        if (location == -1)   // Not set by glBindAttribLocation
+        {
+            int rows = VariableRowCount(attribute->type);
+            int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
+
+            if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
+            {
+                appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
+
+                return false;   // Fail to link
+            }
+
+            mLinkedAttribute[availableIndex] = *attribute;
+        }
+    }
+
+    for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
+    {
+        int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
+        int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1);
+
+        for (int r = 0; r < rows; r++)
+        {
+            mSemanticIndex[attributeIndex++] = index++;
+        }
+    }
+
+    return true;
+}
+
+bool ProgramBinary::linkUniforms(GLenum shader, ID3DXConstantTable *constantTable)
+{
+    D3DXCONSTANTTABLE_DESC constantTableDescription;
+
+    constantTable->GetDesc(&constantTableDescription);
+
+    for (unsigned int constantIndex = 0; constantIndex < constantTableDescription.Constants; constantIndex++)
+    {
+        D3DXHANDLE constantHandle = constantTable->GetConstant(0, constantIndex);
+
+        D3DXCONSTANT_DESC constantDescription;
+        UINT descriptionCount = 1;
+        HRESULT result = constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount);
+        ASSERT(SUCCEEDED(result));
+
+        if (!defineUniform(shader, constantHandle, constantDescription))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// 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(GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name)
+{
+    if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
+    {
+        for (unsigned int i = 0; i < constantDescription.RegisterCount; i++)
+        {
+            D3DXHANDLE psConstant = mConstantTablePS->GetConstantByName(NULL, constantDescription.Name);
+            D3DXHANDLE vsConstant = mConstantTableVS->GetConstantByName(NULL, constantDescription.Name);
+
+            if (psConstant)
+            {
+                unsigned int samplerIndex = mConstantTablePS->GetSamplerIndex(psConstant) + i;
+
+                if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+                {
+                    mSamplersPS[samplerIndex].active = true;
+                    mSamplersPS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
+                    mSamplersPS[samplerIndex].logicalTextureUnit = 0;
+                    mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange);
+                }
+                else
+                {
+                    appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
+                    return false;
+                }
+            }
+            
+            if (vsConstant)
+            {
+                unsigned int samplerIndex = mConstantTableVS->GetSamplerIndex(vsConstant) + i;
+
+                if (samplerIndex < getContext()->getMaximumVertexTextureImageUnits())
+                {
+                    mSamplersVS[samplerIndex].active = true;
+                    mSamplersVS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
+                    mSamplersVS[samplerIndex].logicalTextureUnit = 0;
+                    mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange);
+                }
+                else
+                {
+                    appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", getContext()->getMaximumVertexTextureImageUnits());
+                    return false;
+                }
+            }
+        }
+    }
+
+    switch(constantDescription.Class)
+    {
+      case D3DXPC_STRUCT:
+        {
+            for (unsigned int arrayIndex = 0; arrayIndex < constantDescription.Elements; arrayIndex++)
+            {
+                for (unsigned int field = 0; field < constantDescription.StructMembers; field++)
+                {
+                    D3DXHANDLE fieldHandle = mConstantTablePS->GetConstant(constantHandle, field);
+
+                    D3DXCONSTANT_DESC fieldDescription;
+                    UINT descriptionCount = 1;
+
+                    HRESULT result = mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount);
+                    ASSERT(SUCCEEDED(result));
+
+                    std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : "";
+
+                    if (!defineUniform(shader, fieldHandle, fieldDescription, name + constantDescription.Name + structIndex + "."))
+                    {
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        }
+      case D3DXPC_SCALAR:
+      case D3DXPC_VECTOR:
+      case D3DXPC_MATRIX_COLUMNS:
+      case D3DXPC_OBJECT:
+        return defineUniform(shader, constantDescription, name + constantDescription.Name);
+      default:
+        UNREACHABLE();
+        return false;
+    }
+}
+
+bool ProgramBinary::defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDescription, const std::string &_name)
+{
+    Uniform *uniform = createUniform(constantDescription, _name);
+
+    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.set(constantDescription);
+    if (shader == GL_VERTEX_SHADER)   uniform->vs.set(constantDescription);
+
+    if (location >= 0)
+    {
+        return uniform->type == type;
+    }
+
+    mUniforms.push_back(uniform);
+    unsigned int uniformIndex = mUniforms.size() - 1;
+
+    for (unsigned int i = 0; i < uniform->arraySize; ++i)
+    {
+        mUniformIndex.push_back(UniformLocation(_name, i, uniformIndex));
+    }
+
+    return true;
+}
+
+Uniform *ProgramBinary::createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name)
+{
+    if (constantDescription.Rows == 1)   // Vectors and scalars
+    {
+        switch (constantDescription.Type)
+        {
+          case D3DXPT_SAMPLER2D:
+            switch (constantDescription.Columns)
+            {
+              case 1: return new Uniform(GL_SAMPLER_2D, _name, constantDescription.Elements);
+              default: UNREACHABLE();
+            }
+            break;
+          case D3DXPT_SAMPLERCUBE:
+            switch (constantDescription.Columns)
+            {
+              case 1: return new Uniform(GL_SAMPLER_CUBE, _name, constantDescription.Elements);
+              default: UNREACHABLE();
+            }
+            break;
+          case D3DXPT_BOOL:
+            switch (constantDescription.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);
+              default: UNREACHABLE();
+            }
+            break;
+          case D3DXPT_INT:
+            switch (constantDescription.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);
+              default: UNREACHABLE();
+            }
+            break;
+          case D3DXPT_FLOAT:
+            switch (constantDescription.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);
+              default: UNREACHABLE();
+            }
+            break;
+          default:
+            UNREACHABLE();
+        }
+    }
+    else if (constantDescription.Rows == constantDescription.Columns)  // Square matrices
+    {
+        switch (constantDescription.Type)
+        {
+          case D3DXPT_FLOAT:
+            switch (constantDescription.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);
+              default: UNREACHABLE();
+            }
+            break;
+          default: UNREACHABLE();
+        }
+    }
+    else UNREACHABLE();
+
+    return 0;
+}
+
+// This method needs to match OutputHLSL::decorate
+std::string ProgramBinary::decorateAttribute(const std::string &name)
+{
+    if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0)
+    {
+        return "_" + name;
+    }
+    
+    return name;
+}
+
+std::string ProgramBinary::undecorateUniform(const std::string &_name)
+{
+    std::string name = _name;
+    
+    // Remove any structure field decoration
+    size_t pos = 0;
+    while ((pos = name.find("._", pos)) != std::string::npos)
+    {
+        name.replace(pos, 2, ".");
+    }
+
+    // Remove the leading decoration
+    if (name[0] == '_')
+    {
+        return name.substr(1);
+    }
+    else if (name.compare(0, 3, "ar_") == 0)
+    {
+        return name.substr(3);
+    }
+    
+    return name;
+}
+
+void ProgramBinary::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v)
+{
+    float vector[D3D9_MAX_FLOAT_CONSTANTS * 4];
+    BOOL boolVector[D3D9_MAX_BOOL_CONSTANTS];
+
+    if (targetUniform->ps.float4Index >= 0 || targetUniform->vs.float4Index >= 0)
+    {
+        ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
+        for (int i = 0; i < count; i++)
+        {
+            for (int j = 0; j < 4; j++)
+            {
+                if (j < width)
+                {
+                    vector[i * 4 + j] = (v[i * width + j] == GL_FALSE) ? 0.0f : 1.0f;
+                }
+                else
+                {
+                    vector[i * 4 + j] = 0.0f;
+                }
+            }
+        }
+    }
+
+    if (targetUniform->ps.boolIndex >= 0 || targetUniform->vs.boolIndex >= 0)
+    {
+        int psCount = targetUniform->ps.boolIndex >= 0 ? targetUniform->ps.registerCount : 0;
+        int vsCount = targetUniform->vs.boolIndex >= 0 ? targetUniform->vs.registerCount : 0;
+        int copyCount = std::min(count * width, std::max(psCount, vsCount));
+        ASSERT(copyCount <= D3D9_MAX_BOOL_CONSTANTS);
+        for (int i = 0; i < copyCount; i++)
+        {
+            boolVector[i] = v[i] != GL_FALSE;
+        }
+    }
+
+    if (targetUniform->ps.float4Index >= 0)
+    {
+        mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, vector, targetUniform->ps.registerCount);
+    }
+        
+    if (targetUniform->ps.boolIndex >= 0)
+    {
+        mDevice->SetPixelShaderConstantB(targetUniform->ps.boolIndex, boolVector, targetUniform->ps.registerCount);
+    }
+    
+    if (targetUniform->vs.float4Index >= 0)
+    {
+        mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, vector, targetUniform->vs.registerCount);
+    }
+        
+    if (targetUniform->vs.boolIndex >= 0)
+    {
+        mDevice->SetVertexShaderConstantB(targetUniform->vs.boolIndex, boolVector, targetUniform->vs.registerCount);
+    }
+}
+
+bool ProgramBinary::applyUniformnfv(Uniform *targetUniform, const GLfloat *v)
+{
+    if (targetUniform->ps.registerCount)
+    {
+        mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, v, targetUniform->ps.registerCount);
+    }
+
+    if (targetUniform->vs.registerCount)
+    {
+        mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, v, targetUniform->vs.registerCount);
+    }
+
+    return true;
+}
+
+bool ProgramBinary::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v)
+{
+    ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
+    D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
+
+    for (int i = 0; i < count; i++)
+    {
+        vector[i] = D3DXVECTOR4((float)v[i], 0, 0, 0);
+    }
+
+    if (targetUniform->ps.registerCount)
+    {
+        if (targetUniform->ps.samplerIndex >= 0)
+        {
+            unsigned int firstIndex = targetUniform->ps.samplerIndex;
+
+            for (int i = 0; i < count; i++)
+            {
+                unsigned int samplerIndex = firstIndex + i;
+
+                if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+                {
+                    ASSERT(mSamplersPS[samplerIndex].active);
+                    mSamplersPS[samplerIndex].logicalTextureUnit = v[i];
+                }
+            }
+        }
+        else
+        {
+            ASSERT(targetUniform->ps.float4Index >= 0);
+            mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, (const float*)vector, targetUniform->ps.registerCount);
+        }
+    }
+
+    if (targetUniform->vs.registerCount)
+    {
+        if (targetUniform->vs.samplerIndex >= 0)
+        {
+            unsigned int firstIndex = targetUniform->vs.samplerIndex;
+
+            for (int i = 0; i < count; i++)
+            {
+                unsigned int samplerIndex = firstIndex + i;
+
+                if (samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF)
+                {
+                    ASSERT(mSamplersVS[samplerIndex].active);
+                    mSamplersVS[samplerIndex].logicalTextureUnit = v[i];
+                }
+            }
+        }
+        else
+        {
+            ASSERT(targetUniform->vs.float4Index >= 0);
+            mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, (const float *)vector, targetUniform->vs.registerCount);
+        }
+    }
+
+    return true;
+}
+
+bool ProgramBinary::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v)
+{
+    ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
+    D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
+
+    for (int i = 0; i < count; i++)
+    {
+        vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], 0, 0);
+
+        v += 2;
+    }
+
+    applyUniformniv(targetUniform, count, vector);
+
+    return true;
+}
+
+bool ProgramBinary::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v)
+{
+    ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
+    D3DXVECTOR4 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);
+
+        v += 3;
+    }
+
+    applyUniformniv(targetUniform, count, vector);
+
+    return true;
+}
+
+bool ProgramBinary::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v)
+{
+    ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
+    D3DXVECTOR4 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]);
+
+        v += 4;
+    }
+
+    applyUniformniv(targetUniform, count, vector);
+
+    return true;
+}
+
+void ProgramBinary::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector)
+{
+    if (targetUniform->ps.registerCount)
+    {
+        ASSERT(targetUniform->ps.float4Index >= 0);
+        mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, (const float *)vector, targetUniform->ps.registerCount);
+    }
+
+    if (targetUniform->vs.registerCount)
+    {
+        ASSERT(targetUniform->vs.float4Index >= 0);
+        mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, (const float *)vector, targetUniform->vs.registerCount);
+    }
+}
+
+// append a santized message to the program info log.
+// The D3D compiler includes a fake file path in some of the warning or error 
+// messages, so lets remove all occurrences of this fake file path from the log.
+void ProgramBinary::appendToInfoLogSanitized(const char *message)
+{
+    std::string msg(message);
+
+    size_t found;
+    do
+    {
+        found = msg.find(fakepath);
+        if (found != std::string::npos)
+        {
+            msg.erase(found, strlen(fakepath));
+        }
+    }
+    while (found != std::string::npos);
+
+    appendToInfoLog("%s\n", msg.c_str());
+}
+
+void ProgramBinary::appendToInfoLog(const char *format, ...)
+{
+    if (!format)
+    {
+        return;
+    }
+
+    char info[1024];
+
+    va_list vararg;
+    va_start(vararg, format);
+    vsnprintf(info, sizeof(info), format, vararg);
+    va_end(vararg);
+
+    size_t infoLength = strlen(info);
+
+    if (!mInfoLog)
+    {
+        mInfoLog = new char[infoLength + 1];
+        strcpy(mInfoLog, info);
+    }
+    else
+    {
+        size_t logLength = strlen(mInfoLog);
+        char *newLog = new char[logLength + infoLength + 1];
+        strcpy(newLog, mInfoLog);
+        strcpy(newLog + logLength, info);
+
+        delete[] mInfoLog;
+        mInfoLog = newLog;
+    }
+}
+
+void ProgramBinary::resetInfoLog()
+{
+    if (mInfoLog)
+    {
+        delete [] mInfoLog;
+        mInfoLog = NULL;
+    }
+}
+
+bool ProgramBinary::isValidated() const 
+{
+    return mValidated;
+}
+
+int ProgramBinary::getInfoLogLength() const
+{
+    if (!mInfoLog)
+    {
+        return 0;
+    }
+    else
+    {
+       return strlen(mInfoLog) + 1;
+    }
+}
+
+void ProgramBinary::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
+{
+    int index = 0;
+
+    if (bufSize > 0)
+    {
+        if (mInfoLog)
+        {
+            index = std::min(bufSize - 1, (int)strlen(mInfoLog));
+            memcpy(infoLog, mInfoLog, index);
+        }
+
+        infoLog[index] = '\0';
+    }
+
+    if (length)
+    {
+        *length = index;
+    }
+}
+
+void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+    // Skip over inactive attributes
+    unsigned int activeAttribute = 0;
+    unsigned int attribute;
+    for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+    {
+        if (mLinkedAttribute[attribute].name.empty())
+        {
+            continue;
+        }
+
+        if (activeAttribute == index)
+        {
+            break;
+        }
+
+        activeAttribute++;
+    }
+
+    if (bufsize > 0)
+    {
+        const char *string = mLinkedAttribute[attribute].name.c_str();
+
+        strncpy(name, string, bufsize);
+        name[bufsize - 1] = '\0';
+
+        if (length)
+        {
+            *length = strlen(name);
+        }
+    }
+
+    *size = 1;   // Always a single 'type' instance
+
+    *type = mLinkedAttribute[attribute].type;
+}
+
+GLint ProgramBinary::getActiveAttributeCount()
+{
+    int count = 0;
+
+    for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+    {
+        if (!mLinkedAttribute[attributeIndex].name.empty())
+        {
+            count++;
+        }
+    }
+
+    return count;
+}
+
+GLint ProgramBinary::getActiveAttributeMaxLength()
+{
+    int maxLength = 0;
+
+    for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+    {
+        if (!mLinkedAttribute[attributeIndex].name.empty())
+        {
+            maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
+        }
+    }
+
+    return maxLength;
+}
+
+void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+    // Skip over internal uniforms
+    unsigned int activeUniform = 0;
+    unsigned int uniform;
+    for (uniform = 0; uniform < mUniforms.size(); uniform++)
+    {
+        if (mUniforms[uniform]->name.compare(0, 3, "dx_") == 0)
+        {
+            continue;
+        }
+
+        if (activeUniform == index)
+        {
+            break;
+        }
+
+        activeUniform++;
+    }
+
+    ASSERT(uniform < mUniforms.size());   // index must be smaller than getActiveUniformCount()
+
+    if (bufsize > 0)
+    {
+        std::string string = mUniforms[uniform]->name;
+
+        if (mUniforms[uniform]->isArray())
+        {
+            string += "[0]";
+        }
+
+        strncpy(name, string.c_str(), bufsize);
+        name[bufsize - 1] = '\0';
+
+        if (length)
+        {
+            *length = strlen(name);
+        }
+    }
+
+    *size = mUniforms[uniform]->arraySize;
+
+    *type = mUniforms[uniform]->type;
+}
+
+GLint ProgramBinary::getActiveUniformCount()
+{
+    int count = 0;
+
+    unsigned int numUniforms = mUniforms.size();
+    for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
+    {
+        if (mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0)
+        {
+            count++;
+        }
+    }
+
+    return count;
+}
+
+GLint ProgramBinary::getActiveUniformMaxLength()
+{
+    int maxLength = 0;
+
+    unsigned int numUniforms = mUniforms.size();
+    for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
+    {
+        if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0)
+        {
+            int length = (int)(mUniforms[uniformIndex]->name.length() + 1);
+            if (mUniforms[uniformIndex]->isArray())
+            {
+                length += 3;  // Counting in "[0]".
+            }
+            maxLength = std::max(length, maxLength);
+        }
+    }
+
+    return maxLength;
+}
+
+void ProgramBinary::validate()
+{
+    resetInfoLog();
+
+    applyUniforms();
+    if (!validateSamplers(true))
+    {
+        mValidated = false;
+    }
+    else
+    {
+        mValidated = true;
+    }
+}
+
+bool ProgramBinary::validateSamplers(bool logErrors)
+{
+    // if any two active samplers in a program are of different types, but refer to the same
+    // texture image unit, and this is the current program, then ValidateProgram will fail, and
+    // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
+
+    const unsigned int maxCombinedTextureImageUnits = getContext()->getMaximumCombinedTextureImageUnits();
+    TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF];
+
+    for (unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; ++i)
+    {
+        textureUnitType[i] = TEXTURE_UNKNOWN;
+    }
+
+    for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
+    {
+        if (mSamplersPS[i].active)
+        {
+            unsigned int unit = mSamplersPS[i].logicalTextureUnit;
+            
+            if (unit >= maxCombinedTextureImageUnits)
+            {
+                if (logErrors)
+                {
+                    appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+                }
+
+                return false;
+            }
+
+            if (textureUnitType[unit] != TEXTURE_UNKNOWN)
+            {
+                if (mSamplersPS[i].textureType != textureUnitType[unit])
+                {
+                    if (logErrors)
+                    {
+                        appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+                    }
+
+                    return false;
+                }
+            }
+            else
+            {
+                textureUnitType[unit] = mSamplersPS[i].textureType;
+            }
+        }
+    }
+
+    for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
+    {
+        if (mSamplersVS[i].active)
+        {
+            unsigned int unit = mSamplersVS[i].logicalTextureUnit;
+            
+            if (unit >= maxCombinedTextureImageUnits)
+            {
+                if (logErrors)
+                {
+                    appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+                }
+
+                return false;
+            }
+
+            if (textureUnitType[unit] != TEXTURE_UNKNOWN)
+            {
+                if (mSamplersVS[i].textureType != textureUnitType[unit])
+                {
+                    if (logErrors)
+                    {
+                        appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+                    }
+
+                    return false;
+                }
+            }
+            else
+            {
+                textureUnitType[unit] = mSamplersVS[i].textureType;
+            }
+        }
+    }
+
+    return true;
+}
+
+GLint ProgramBinary::getDxDepthRangeLocation() const
+{
+    return mDxDepthRangeLocation;
+}
+
+GLint ProgramBinary::getDxDepthLocation() const
+{
+    return mDxDepthLocation;
+}
+
+GLint ProgramBinary::getDxCoordLocation() const
+{
+    return mDxCoordLocation;
+}
+
+GLint ProgramBinary::getDxHalfPixelSizeLocation() const
+{
+    return mDxHalfPixelSizeLocation;
+}
+
+GLint ProgramBinary::getDxFrontCCWLocation() const
+{
+    return mDxFrontCCWLocation;
+}
+
+GLint ProgramBinary::getDxPointsOrLinesLocation() const
+{
+    return mDxPointsOrLinesLocation;
+}
+
+}
