Sort the elements of the D3D11 input layouts before we store them in the cache.

This prevents a D3D11 error complaining that the input layout
uses a different ordering of the vertex elements than the vertex shader.

TRAC #22561

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

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1931 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index e2715a1..c2247a1 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -19,7 +19,10 @@
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Program.h"
 
-#include <string>
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/VertexDataManager.h"
+
+#include <algorithm>
 
 #undef near
 #undef far
@@ -2485,4 +2488,47 @@
 {
 }
 
+struct AttributeSorter
+{
+    AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
+        : originalIndices(semanticIndices)
+    {
+        for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+        {
+            indices[i] = i;
+        }
+
+        std::sort(&indices[0], &indices[MAX_VERTEX_ATTRIBS], *this);
+    }
+
+    bool operator()(int a, int b)
+    {
+        return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b];
+    }
+
+    int indices[MAX_VERTEX_ATTRIBS];
+    const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
+};
+
+void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
+{
+    AttributeSorter sorter(mSemanticIndex);
+
+    int oldIndices[MAX_VERTEX_ATTRIBS];
+    rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
+
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    {
+        oldIndices[i] = mSemanticIndex[i];
+        oldTranslatedAttributes[i] = attributes[i];
+    }
+
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    {
+        int oldIndex = sorter.indices[i];
+        sortedSemanticIndices[i] = oldIndices[oldIndex];
+        attributes[i] = oldTranslatedAttributes[oldIndex];
+    }
+}
+
 }