Stop generating duplicate vertex binaries.

We would generate multiple vertex binaries that result in the same
HLSL code, eg for vec2 and vec3 vertex attributes. Eliminate
duplicates by using the converted attribute type for testing
for matching binaries.

BUG=angle:599

Change-Id: I061588164577ff9fa69ebb7d8a3f2bf6bb6fe013
Reviewed-on: https://chromium-review.googlesource.com/197830
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 302315e..c3924fa 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -85,12 +85,14 @@
 
 ProgramBinary::VertexExecutable::VertexExecutable(rx::Renderer *const renderer,
                                                   const VertexFormat inputLayout[],
+                                                  const GLenum signature[],
                                                   rx::ShaderExecutable *shaderExecutable)
     : mShaderExecutable(shaderExecutable)
 {
     for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
     {
         mInputs[attributeIndex] = inputLayout[attributeIndex];
+        mSignature[attributeIndex] = signature[attributeIndex];
     }
 }
 
@@ -99,11 +101,11 @@
     delete mShaderExecutable;
 }
 
-bool ProgramBinary::VertexExecutable::matchesInputLayout(const VertexFormat attributes[]) const
+bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const
 {
-    for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+    for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
     {
-        if (mInputs[attributeIndex] != attributes[attributeIndex])
+        if (mSignature[attributeIndex] != signature[attributeIndex])
         {
             return false;
         }
@@ -206,11 +208,14 @@
     return mPixelExecutable;
 }
 
-rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
+rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
 {
+    GLenum signature[MAX_VERTEX_ATTRIBS];
+    mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
+
     for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
     {
-        if (mVertexExecutables[executableIndex]->matchesInputLayout(inputLayout))
+        if (mVertexExecutables[executableIndex]->matchesSignature(signature))
         {
             return mVertexExecutables[executableIndex]->shaderExecutable();
         }
@@ -240,7 +245,7 @@
     }
     else
     {
-        mVertexExecutables.push_back(new VertexExecutable(mRenderer, inputLayout, vertexExecutable));
+        mVertexExecutables.push_back(new VertexExecutable(mRenderer, inputLayout, signature, vertexExecutable));
     }
 
     return vertexExecutable;
@@ -1234,11 +1239,11 @@
 
     for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
     {
-        VertexFormat vertexInputs[gl::MAX_VERTEX_ATTRIBS];
+        VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
 
-        for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
+        for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++)
         {
-            VertexFormat *vertexInput = &vertexInputs[inputIndex];
+            VertexFormat *vertexInput = &inputLayout[inputIndex];
             stream.read(&vertexInput->mType);
             stream.read(&vertexInput->mNormalized);
             stream.read(&vertexInput->mComponents);
@@ -1260,7 +1265,12 @@
             return false;
         }
 
-        mVertexExecutables.push_back(new VertexExecutable(mRenderer, vertexInputs, shaderExecutable));
+        // generated converted input layout
+        GLenum signature[MAX_VERTEX_ATTRIBS];
+        mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
+
+        // add new binary
+        mVertexExecutables.push_back(new VertexExecutable(mRenderer, inputLayout, signature, shaderExecutable));
 
         stream.skip(vertexShaderSize);
     }