Compact the D3D shader specializations into one.

BUG=angle:731

Change-Id: I4f35a05aeea130f9011ec62cfe931ed23e2681c9
Reviewed-on: https://chromium-review.googlesource.com/214871
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 6452ef9..65b3c14 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -1615,8 +1615,8 @@
 
     mTransformFeedbackBufferMode = transformFeedbackBufferMode;
 
-    rx::VertexShaderD3D *vertexShaderD3D = rx::VertexShaderD3D::makeVertexShaderD3D(vertexShader->getImplementation());
-    rx::FragmentShaderD3D *fragmentShaderD3D = rx::FragmentShaderD3D::makeFragmentShaderD3D(fragmentShader->getImplementation());
+    rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+    rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
 
     mShaderVersion = vertexShaderD3D->getShaderVersion();
 
@@ -1718,7 +1718,7 @@
 // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
 bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
 {
-    const rx::VertexShaderD3D *vertexShaderD3D = rx::VertexShaderD3D::makeVertexShaderD3D(vertexShader->getImplementation());
+    const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
 
     unsigned int usedLocations = 0;
     const std::vector<sh::Attribute> &activeAttributes = vertexShader->getActiveAttributes();
@@ -1896,8 +1896,8 @@
 
 bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
 {
-    const rx::VertexShaderD3D *vertexShaderD3D = rx::VertexShaderD3D::makeVertexShaderD3D(vertexShader.getImplementation());
-    const rx::FragmentShaderD3D *fragmentShaderD3D = rx::FragmentShaderD3D::makeFragmentShaderD3D(fragmentShader.getImplementation());
+    const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
+    const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
 
     const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
     const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
diff --git a/src/libGLESv2/renderer/ShaderImpl.h b/src/libGLESv2/renderer/ShaderImpl.h
index 808abd9..de5d30e 100644
--- a/src/libGLESv2/renderer/ShaderImpl.h
+++ b/src/libGLESv2/renderer/ShaderImpl.h
@@ -20,6 +20,7 @@
 class ShaderImpl
 {
   public:
+    ShaderImpl() { }
     virtual ~ShaderImpl() { }
 
     virtual bool compile(const std::string &source) = 0;
@@ -39,6 +40,8 @@
     std::vector<sh::Attribute> &getActiveOutputVariables() { return mActiveOutputVariables; }
 
   protected:
+    DISALLOW_COPY_AND_ASSIGN(ShaderImpl);
+
     std::vector<gl::PackedVarying> mVaryings;
     std::vector<sh::Uniform> mUniforms;
     std::vector<sh::InterfaceBlock> mInterfaceBlocks;
diff --git a/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
index 7086f47..404525c 100644
--- a/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
@@ -207,8 +207,8 @@
 
 // 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 DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::FragmentShaderD3D *fragmentShader,
-                              rx::VertexShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
+int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
+                              rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
 {
     // TODO (geofflang):  Use context's caps
     const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
@@ -278,7 +278,7 @@
     return registers;
 }
 
-std::string DynamicHLSL::generateVaryingHLSL(rx::VertexShaderD3D *shader) const
+std::string DynamicHLSL::generateVaryingHLSL(rx::ShaderD3D *shader) const
 {
     std::string varyingSemantic = getVaryingSemantic(shader->mUsesPointSize);
     std::string varyingHLSL;
@@ -607,7 +607,7 @@
     }
 }
 
-void DynamicHLSL::storeUserLinkedVaryings(const rx::VertexShaderD3D *vertexShader,
+void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader,
                                           std::vector<LinkedVarying> *linkedVaryings) const
 {
     const std::string &varyingSemantic = getVaryingSemantic(vertexShader->mUsesPointSize);
@@ -630,7 +630,7 @@
 
 bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
                                          std::string& pixelHLSL, std::string& vertexHLSL,
-                                         rx::FragmentShaderD3D *fragmentShader, rx::VertexShaderD3D *vertexShader,
+                                         rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
                                          const std::vector<std::string>& transformFeedbackVaryings,
                                          std::vector<LinkedVarying> *linkedVaryings,
                                          std::map<int, VariableLocation> *programOutputVars,
@@ -956,7 +956,7 @@
     return true;
 }
 
-void DynamicHLSL::defineOutputVariables(rx::FragmentShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
+void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
 {
     const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables();
 
@@ -982,14 +982,14 @@
     }
 }
 
-std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, rx::FragmentShaderD3D *fragmentShader, rx::VertexShaderD3D *vertexShader) const
+std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
 {
     // for now we only handle point sprite emulation
     ASSERT(vertexShader->mUsesPointSize && mRenderer->getMajorShaderModel() >= 4);
     return generatePointSpriteHLSL(registers, fragmentShader, vertexShader);
 }
 
-std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::FragmentShaderD3D *fragmentShader, rx::VertexShaderD3D *vertexShader) const
+std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
 {
     ASSERT(registers >= 0);
     ASSERT(vertexShader->mUsesPointSize);
diff --git a/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/libGLESv2/renderer/d3d/DynamicHLSL.h
index 6ee7b11..cf61995 100644
--- a/src/libGLESv2/renderer/d3d/DynamicHLSL.h
+++ b/src/libGLESv2/renderer/d3d/DynamicHLSL.h
@@ -42,8 +42,6 @@
 {
 class Renderer;
 class ShaderD3D;
-class VertexShaderD3D;
-class FragmentShaderD3D;
 
 typedef const gl::PackedVarying *VaryingPacking[gl::IMPLEMENTATION_MAX_VARYING_VECTORS][4];
 
@@ -60,22 +58,22 @@
   public:
     explicit DynamicHLSL(rx::Renderer *const renderer);
 
-    int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, rx::FragmentShaderD3D *fragmentShader,
-                     rx::VertexShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
+    int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
+                     rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
     std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const gl::VertexFormat inputLayout[],
                                                    const sh::Attribute shaderAttributes[]) const;
     std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOuputVariable> &outputVariables,
                                                       bool usesFragDepth, const std::vector<GLenum> &outputLayout) const;
     bool generateShaderLinkHLSL(gl::InfoLog &infoLog, int registers, const VaryingPacking packing,
                                 std::string& pixelHLSL, std::string& vertexHLSL,
-                                rx::FragmentShaderD3D *fragmentShader, rx::VertexShaderD3D *vertexShader,
+                                rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
                                 const std::vector<std::string>& transformFeedbackVaryings,
                                 std::vector<gl::LinkedVarying> *linkedVaryings,
                                 std::map<int, gl::VariableLocation> *programOutputVars,
                                 std::vector<PixelShaderOuputVariable> *outPixelShaderKey,
                                 bool *outUsesFragDepth) const;
 
-    std::string generateGeometryShaderHLSL(int registers, rx::FragmentShaderD3D *fragmentShader, rx::VertexShaderD3D *vertexShader) const;
+    std::string generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const;
     void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
 
   private:
@@ -89,11 +87,11 @@
     SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize,
                                         bool pixelShader) const;
     std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
-    std::string generateVaryingHLSL(rx::VertexShaderD3D *shader) const;
-    void storeUserLinkedVaryings(const rx::VertexShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
+    std::string generateVaryingHLSL(rx::ShaderD3D *shader) const;
+    void storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
     void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const;
-    void defineOutputVariables(rx::FragmentShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const;
-    std::string generatePointSpriteHLSL(int registers, rx::FragmentShaderD3D *fragmentShader, rx::VertexShaderD3D *vertexShader) const;
+    void defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const;
+    std::string generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const;
 
     // Prepend an underscore
     static std::string decorateVariable(const std::string &name);
diff --git a/src/libGLESv2/renderer/d3d/ShaderD3D.cpp b/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
index f26df10..a6d5266 100644
--- a/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
@@ -27,8 +27,8 @@
     return variableList;
 }
 
-ShaderD3D::ShaderD3D(rx::Renderer *renderer)
-    : ShaderImpl(),
+ShaderD3D::ShaderD3D(GLenum type, rx::Renderer *renderer)
+    : mType(type),
       mRenderer(renderer),
       mShaderVersion(100)
 {
@@ -340,15 +340,28 @@
     return mInterfaceBlockRegisterMap.find(blockName)->second;
 }
 
+void *ShaderD3D::getCompiler()
+{
+    if (mType == GL_VERTEX_SHADER)
+    {
+        return mVertexCompiler;
+    }
+    else
+    {
+        ASSERT(mType == GL_FRAGMENT_SHADER);
+        return mFragmentCompiler;
+    }
+}
+
 ShShaderOutput ShaderD3D::getCompilerOutputType(GLenum shader)
 {
     void *compiler = NULL;
 
     switch (shader)
     {
-    case GL_VERTEX_SHADER:   compiler = mVertexCompiler;   break;
-    case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break;
-    default: UNREACHABLE();  return SH_HLSL9_OUTPUT;
+      case GL_VERTEX_SHADER:   compiler = mVertexCompiler;   break;
+      case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break;
+      default: UNREACHABLE();  return SH_HLSL9_OUTPUT;
     }
 
     size_t outputType = 0;
@@ -357,47 +370,45 @@
     return static_cast<ShShaderOutput>(outputType);
 }
 
-VertexShaderD3D::VertexShaderD3D(rx::Renderer *renderer) : ShaderD3D(renderer)
-{
-}
-
-VertexShaderD3D::~VertexShaderD3D()
-{
-}
-
-VertexShaderD3D *VertexShaderD3D::makeVertexShaderD3D(ShaderImpl *impl)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(VertexShaderD3D*, impl));
-    return static_cast<VertexShaderD3D*>(impl);
-}
-
-const VertexShaderD3D *VertexShaderD3D::makeVertexShaderD3D(const ShaderImpl *impl)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(const VertexShaderD3D*, impl));
-    return static_cast<const VertexShaderD3D*>(impl);
-}
-
-bool VertexShaderD3D::compile(const std::string &source)
+bool ShaderD3D::compile(const std::string &source)
 {
     uncompile();
 
-    compileToHLSL(mVertexCompiler, source);
-    parseAttributes();
-    parseVaryings(mVertexCompiler);
+    void *compiler = getCompiler();
+
+    compileToHLSL(compiler, source);
+
+    if (mType == GL_VERTEX_SHADER)
+    {
+        parseAttributes(compiler);
+    }
+
+    parseVaryings(compiler);
+
+    if (mType == GL_FRAGMENT_SHADER)
+    {
+        std::sort(mVaryings.begin(), mVaryings.end(), compareVarying);
+
+        const std::string &hlsl = getTranslatedSource();
+        if (!hlsl.empty())
+        {
+            mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compiler));
+        }
+    }
 
     return !getTranslatedSource().empty();
 }
 
-void VertexShaderD3D::parseAttributes()
+void ShaderD3D::parseAttributes(void *compiler)
 {
     const std::string &hlsl = getTranslatedSource();
     if (!hlsl.empty())
     {
-        mActiveAttributes = *GetShaderVariables(ShGetAttributes(mVertexCompiler));
+        mActiveAttributes = *GetShaderVariables(ShGetAttributes(compiler));
     }
 }
 
-int VertexShaderD3D::getSemanticIndex(const std::string &attributeName) const
+int ShaderD3D::getSemanticIndex(const std::string &attributeName) const
 {
     if (!attributeName.empty())
     {
@@ -418,42 +429,4 @@
     return -1;
 }
 
-FragmentShaderD3D::FragmentShaderD3D(rx::Renderer *renderer) : ShaderD3D(renderer)
-{
-}
-
-FragmentShaderD3D::~FragmentShaderD3D()
-{
-}
-
-FragmentShaderD3D *FragmentShaderD3D::makeFragmentShaderD3D(ShaderImpl *impl)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(FragmentShaderD3D*, impl));
-    return static_cast<FragmentShaderD3D*>(impl);
-}
-
-const FragmentShaderD3D *FragmentShaderD3D::makeFragmentShaderD3D(const ShaderImpl *impl)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(const FragmentShaderD3D*, impl));
-    return static_cast<const FragmentShaderD3D*>(impl);
-}
-
-bool FragmentShaderD3D::compile(const std::string &source)
-{
-    uncompile();
-
-    compileToHLSL(mFragmentCompiler, source);
-    parseVaryings(mFragmentCompiler);
-
-    std::sort(mVaryings.begin(), mVaryings.end(), compareVarying);
-
-    const std::string &hlsl = getTranslatedSource();
-    if (!hlsl.empty())
-    {
-        mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(mFragmentCompiler));
-        return true;
-    }
-    return false;
-}
-
 }
diff --git a/src/libGLESv2/renderer/d3d/ShaderD3D.h b/src/libGLESv2/renderer/d3d/ShaderD3D.h
index d537f5b..9f7dc0b 100644
--- a/src/libGLESv2/renderer/d3d/ShaderD3D.h
+++ b/src/libGLESv2/renderer/d3d/ShaderD3D.h
@@ -23,7 +23,7 @@
     friend class DynamicHLSL;
 
   public:
-    ShaderD3D(rx::Renderer *renderer);
+    ShaderD3D(GLenum type, rx::Renderer *renderer);
     virtual ~ShaderD3D();
 
     static ShaderD3D *makeShaderD3D(ShaderImpl *impl);
@@ -38,6 +38,7 @@
     void resetVaryingsRegisterAssignment();
     unsigned int getUniformRegister(const std::string &uniformName) const;
     unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
+    int getSemanticIndex(const std::string &attributeName) const;
 
     rx::D3DWorkaroundType getD3DWorkarounds() const;
     int getShaderVersion() const { return mShaderVersion; }
@@ -47,15 +48,24 @@
     static void releaseCompiler();
     static ShShaderOutput getCompilerOutputType(GLenum shader);
 
-  protected:
+    virtual bool compile(const std::string &source);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(ShaderD3D);
+
     void compileToHLSL(void *compiler, const std::string &source);
     void parseVaryings(void *compiler);
 
+    void initializeCompiler();
+    void parseAttributes(void *compiler);
+    void *getCompiler();
+
     static bool compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y);
 
     static void *mFragmentCompiler;
     static void *mVertexCompiler;
 
+    GLenum mType;
     rx::Renderer *mRenderer;
 
     int mShaderVersion;
@@ -72,55 +82,12 @@
     bool mUsesDiscardRewriting;
     bool mUsesNestedBreak;
 
-  private:
-    DISALLOW_COPY_AND_ASSIGN(ShaderD3D);
-
-    void initializeCompiler();
-
     std::string mHlsl;
     std::string mInfoLog;
     std::map<std::string, unsigned int> mUniformRegisterMap;
     std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
 };
 
-class VertexShaderD3D : public ShaderD3D
-{
-    friend class DynamicHLSL;
-
-  public:
-    VertexShaderD3D(rx::Renderer *renderer);
-    virtual ~VertexShaderD3D();
-
-    static VertexShaderD3D *makeVertexShaderD3D(ShaderImpl *impl);
-    static const VertexShaderD3D *makeVertexShaderD3D(const ShaderImpl *impl);
-
-    virtual bool compile(const std::string &source);
-
-    int getSemanticIndex(const std::string &attributeName) const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(VertexShaderD3D);
-
-    void parseAttributes();
-};
-
-class FragmentShaderD3D : public ShaderD3D
-{
-    friend class DynamicHLSL;
-
-  public:
-    FragmentShaderD3D(rx::Renderer *renderer);
-    virtual ~FragmentShaderD3D();
-
-    static FragmentShaderD3D *makeFragmentShaderD3D(ShaderImpl *impl);
-    static const FragmentShaderD3D *makeFragmentShaderD3D(const ShaderImpl *impl);
-
-    virtual bool compile(const std::string &source);
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(FragmentShaderD3D);
-};
-
 }
 
 #endif // LIBGLESV2_RENDERER_SHADERD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index 3a276e1..33c39de 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -2207,16 +2207,7 @@
 
 ShaderImpl *Renderer11::createShader(GLenum type)
 {
-    switch (type)
-    {
-      case GL_VERTEX_SHADER:
-        return new VertexShaderD3D(this);
-      case GL_FRAGMENT_SHADER:
-        return new FragmentShaderD3D(this);
-      default:
-        UNREACHABLE();
-        return NULL;
-    }
+    return new ShaderD3D(type, this);
 }
 
 void Renderer11::releaseShaderCompiler()
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index e26dcc7..7b0e14b 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -2760,16 +2760,7 @@
 
 ShaderImpl *Renderer9::createShader(GLenum type)
 {
-    switch (type)
-    {
-      case GL_VERTEX_SHADER:
-        return new VertexShaderD3D(this);
-      case GL_FRAGMENT_SHADER:
-        return new FragmentShaderD3D(this);
-      default:
-        UNREACHABLE();
-        return NULL;
-    }
+    return new ShaderD3D(type, this);
 }
 
 void Renderer9::releaseShaderCompiler()