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/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 61cb0fe..fa14806 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -130,7 +130,7 @@
                              bool ignoreViewport) = 0;
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
-    virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard) = 0;
+    virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]) = 0;
     virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0;
     virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
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);
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
index d857c01..2e7c083 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
@@ -30,6 +30,7 @@
 #include "libGLESv2/renderer/d3d9/BufferStorage9.h"
 #include "libGLESv2/renderer/d3d9/Query9.h"
 #include "libGLESv2/renderer/d3d9/Fence9.h"
+#include "libGLESv2/angletypes.h"
 
 #include "libEGL/Display.h"
 
@@ -1722,11 +1723,11 @@
     }
 }
 
-void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard)
+void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[])
 {
     ASSERT(!rasterizerDiscard);
 
-    ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
+    ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
     ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
 
     IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL);
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d9/Renderer9.h
index c665006..78e70cc 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.h
@@ -58,17 +58,6 @@
     IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length);
     HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer);
     HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer);
-#if 0
-    void *createTexture2D();
-    void *createTextureCube();
-    void *createQuery();
-    void *createIndexBuffer();
-    void *createVertexbuffer();
-
-    // state setup
-    void applyShaders();
-    void applyConstants();
-#endif
     virtual void generateSwizzle(gl::Texture *texture);
     virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
     virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
@@ -86,7 +75,7 @@
                              bool ignoreViewport);
 
     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 bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],