Store multiple vertex executables in the program binary.

With dynamic vertex conversion the GPU, we will have different input
layouts resulting in different executables. This patch adds a way
of mapping the input layouts to vertex executables.

BUG=angle:560
Change-Id: Ie36f2f8ac2dfcb96f562af577d31f57d6d89b447
Reviewed-on: https://chromium-review.googlesource.com/185192
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp b/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
index b88a54f..5962862 100644
--- a/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
@@ -22,6 +22,21 @@
 namespace rx
 {
 
+static void GetInputLayout(const TranslatedAttribute translatedAttributes[gl::MAX_VERTEX_ATTRIBS],
+                           gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
+{
+    for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+    {
+        const TranslatedAttribute &translatedAttribute = translatedAttributes[attributeIndex];
+
+        if (translatedAttributes[attributeIndex].active)
+        {
+            inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute.attribute,
+                                                           translatedAttribute.currentValueType);
+        }
+    }
+}
+
 const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
 
 InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
@@ -135,7 +150,9 @@
     }
     else
     {
-        ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
+        gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
+        GetInputLayout(attributes, shaderInputLayout);
+        ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutableForInputLayout(shaderInputLayout));
 
         D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
         for (unsigned int j = 0; j < ilKey.elementCount; ++j)
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index a4037f6..31d31c4 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -1403,9 +1403,9 @@
     }
 }
 
-void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard)
+void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[])
 {
-    ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
+    ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
     ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
     ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
 
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d11/Renderer11.h
index 69e04ab..2f7d403 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.h
@@ -75,7 +75,7 @@
 
     virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
-    virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard);
+    virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]);
     virtual void applyUniforms(const gl::ProgramBinary &programBinary);
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
                                      GLint first, GLsizei count, GLsizei instances);