Revert "Support precision emulation on HLSL"

Forgot to add virtual destructors.

BUG=angleproject:1437

This reverts commit a42e8b2cb9d0857f53c0490b5be3bf25b4e1f827.

Change-Id: If33fecfeca9947deedf4668c64dbadf25a5dc5eb
Reviewed-on: https://chromium-review.googlesource.com/360122
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index 0f101bd..7b22686 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -6,203 +6,99 @@
 
 #include "compiler/translator/EmulatePrecision.h"
 
-#include <memory>
-
 namespace
 {
 
-class RoundingHelperWriter
+static void writeVectorPrecisionEmulationHelpers(TInfoSinkBase &sink,
+                                                 const ShShaderOutput outputLanguage,
+                                                 const unsigned int size)
 {
-  public:
-    static RoundingHelperWriter *createHelperWriter(const ShShaderOutput outputLanguage);
+    std::stringstream vecTypeStrStr;
+    if (outputLanguage == SH_ESSL_OUTPUT)
+        vecTypeStrStr << "highp ";
+    vecTypeStrStr << "vec" << size;
+    std::string vecType = vecTypeStrStr.str();
 
-    void writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion);
-    void writeCompoundAssignmentHelper(TInfoSinkBase &sink,
-                                       const char *lType,
-                                       const char *rType,
-                                       const char *opStr,
-                                       const char *opNameStr);
+    sink <<
+    vecType << " angle_frm(in " << vecType << " v) {\n"
+    "    v = clamp(v, -65504.0, 65504.0);\n"
+    "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
+    "    bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n"
+    "    v = v * exp2(-exponent);\n"
+    "    v = sign(v) * floor(abs(v));\n"
+    "    return v * exp2(exponent) * vec" << size << "(isNonZero);\n"
+    "}\n";
 
-  protected:
-    RoundingHelperWriter(const ShShaderOutput outputLanguage) : mOutputLanguage(outputLanguage) {}
-    RoundingHelperWriter() = delete;
-
-    const ShShaderOutput mOutputLanguage;
-
-  private:
-    virtual std::string getTypeString(const char *glslType)     = 0;
-    virtual void writeFloatRoundingHelpers(TInfoSinkBase &sink) = 0;
-    virtual void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) = 0;
-    virtual void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                           const unsigned int columns,
-                                           const unsigned int rows,
-                                           const char *functionName) = 0;
-};
-
-class RoundingHelperWriterGLSL : public RoundingHelperWriter
-{
-  public:
-    RoundingHelperWriterGLSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriter(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
-    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
-    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                   const unsigned int columns,
-                                   const unsigned int rows,
-                                   const char *functionName) override;
-};
-
-class RoundingHelperWriterESSL : public RoundingHelperWriterGLSL
-{
-  public:
-    RoundingHelperWriterESSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriterGLSL(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-};
-
-class RoundingHelperWriterHLSL : public RoundingHelperWriter
-{
-  public:
-    RoundingHelperWriterHLSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriter(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
-    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
-    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                   const unsigned int columns,
-                                   const unsigned int rows,
-                                   const char *functionName) override;
-};
-
-RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
-{
-    switch (outputLanguage)
-    {
-        case SH_HLSL_4_1_OUTPUT:
-            return new RoundingHelperWriterHLSL(outputLanguage);
-        case SH_ESSL_OUTPUT:
-            return new RoundingHelperWriterESSL(outputLanguage);
-        default:
-            // Other languages not yet supported
-            ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
-                   IsGLSL130OrNewer(outputLanguage));
-            return new RoundingHelperWriterGLSL(outputLanguage);
-    }
+    sink <<
+    vecType << " angle_frl(in " << vecType << " v) {\n"
+    "    v = clamp(v, -2.0, 2.0);\n"
+    "    v = v * 256.0;\n"
+    "    v = sign(v) * floor(abs(v));\n"
+    "    return v * 0.00390625;\n"
+    "}\n";
 }
 
-void RoundingHelperWriter::writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion)
+static void writeMatrixPrecisionEmulationHelper(TInfoSinkBase &sink,
+                                                const ShShaderOutput outputLanguage,
+                                                const unsigned int columns,
+                                                const unsigned int rows,
+                                                const char *functionName)
+{
+    std::stringstream matTypeStrStr;
+    if (outputLanguage == SH_ESSL_OUTPUT)
+        matTypeStrStr << "highp ";
+    matTypeStrStr << "mat" << columns;
+    if (rows != columns)
+    {
+        matTypeStrStr << "x" << rows;
+    }
+
+    std::string matType = matTypeStrStr.str();
+
+    sink << matType << " " << functionName << "(in " << matType << " m) {\n"
+            "    " << matType << " rounded;\n";
+
+    for (unsigned int i = 0; i < columns; ++i)
+    {
+        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
+    }
+
+    sink << "    return rounded;\n"
+            "}\n";
+}
+
+static void writeCommonPrecisionEmulationHelpers(TInfoSinkBase &sink,
+                                                 const int shaderVersion,
+                                                 const ShShaderOutput outputLanguage)
 {
     // Write the angle_frm functions that round floating point numbers to
     // half precision, and angle_frl functions that round them to minimum lowp
     // precision.
 
-    writeFloatRoundingHelpers(sink);
-    writeVectorRoundingHelpers(sink, 2);
-    writeVectorRoundingHelpers(sink, 3);
-    writeVectorRoundingHelpers(sink, 4);
-    if (shaderVersion > 100)
-    {
-        for (unsigned int columns = 2; columns <= 4; ++columns)
-        {
-            for (unsigned int rows = 2; rows <= 4; ++rows)
-            {
-                writeMatrixRoundingHelper(sink, columns, rows, "angle_frm");
-                writeMatrixRoundingHelper(sink, columns, rows, "angle_frl");
-            }
-        }
-    }
-    else
-    {
-        for (unsigned int size = 2; size <= 4; ++size)
-        {
-            writeMatrixRoundingHelper(sink, size, size, "angle_frm");
-            writeMatrixRoundingHelper(sink, size, size, "angle_frl");
-        }
-    }
-}
-
-void RoundingHelperWriter::writeCompoundAssignmentHelper(TInfoSinkBase &sink,
-                                                         const char *lType,
-                                                         const char *rType,
-                                                         const char *opStr,
-                                                         const char *opNameStr)
-{
-    std::string lTypeStr = getTypeString(lType);
-    std::string rTypeStr = getTypeString(rType);
-
-    // Note that y should be passed through angle_frm at the function call site,
-    // but x can't be passed through angle_frm there since it is an inout parameter.
-    // So only pass x and the result through angle_frm here.
-    // clang-format off
-    sink <<
-        lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
-        "    x = angle_frm(angle_frm(x) " << opStr << " y);\n"
-        "    return x;\n"
-        "}\n";
-    sink <<
-        lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
-        "    x = angle_frl(angle_frm(x) " << opStr << " y);\n"
-        "    return x;\n"
-        "}\n";
-    // clang-format on
-}
-
-std::string RoundingHelperWriterGLSL::getTypeString(const char *glslType)
-{
-    return glslType;
-}
-
-std::string RoundingHelperWriterESSL::getTypeString(const char *glslType)
-{
-    std::stringstream typeStrStr;
-    typeStrStr << "highp " << glslType;
-    return typeStrStr.str();
-}
-
-void RoundingHelperWriterGLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
-{
     // Unoptimized version of angle_frm for single floats:
     //
-    // int webgl_maxNormalExponent(in int exponentBits)
-    // {
+    // int webgl_maxNormalExponent(in int exponentBits) {
     //     int possibleExponents = int(exp2(float(exponentBits)));
     //     int exponentBias = possibleExponents / 2 - 1;
     //     int allExponentBitsOne = possibleExponents - 1;
     //     return (allExponentBitsOne - 1) - exponentBias;
     // }
     //
-    // float angle_frm(in float x)
-    // {
+    // float angle_frm(in float x) {
     //     int mantissaBits = 10;
     //     int exponentBits = 5;
     //     float possibleMantissas = exp2(float(mantissaBits));
     //     float mantissaMax = 2.0 - 1.0 / possibleMantissas;
     //     int maxNE = webgl_maxNormalExponent(exponentBits);
     //     float max = exp2(float(maxNE)) * mantissaMax;
-    //     if (x > max)
-    //     {
+    //     if (x > max) {
     //         return max;
     //     }
-    //     if (x < -max)
-    //     {
+    //     if (x < -max) {
     //         return -max;
     //     }
     //     float exponent = floor(log2(abs(x)));
-    //     if (abs(x) == 0.0 || exponent < -float(maxNE))
-    //     {
+    //     if (abs(x) == 0.0 || exponent < -float(maxNE)) {
     //         return 0.0 * sign(x)
     //     }
     //     x = x * exp2(-(exponent - float(mantissaBits)));
@@ -224,198 +120,83 @@
     //    numbers will be flushed to zero either way (2^-15 is the smallest
     //    normal positive number), this does not introduce any error.
 
-    std::string floatType = getTypeString("float");
-
-    // clang-format off
-    sink <<
-        floatType << " angle_frm(in " << floatType << " x) {\n"
-        "    x = clamp(x, -65504.0, 65504.0);\n"
-        "    " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n"
-        "    bool isNonZero = (exponent >= -25.0);\n"
-        "    x = x * exp2(-exponent);\n"
-        "    x = sign(x) * floor(abs(x));\n"
-        "    return x * exp2(exponent) * float(isNonZero);\n"
-        "}\n";
+    std::string floatType = "float";
+    if (outputLanguage == SH_ESSL_OUTPUT)
+        floatType = "highp float";
 
     sink <<
-        floatType << " angle_frl(in " << floatType << " x) {\n"
-        "    x = clamp(x, -2.0, 2.0);\n"
-        "    x = x * 256.0;\n"
-        "    x = sign(x) * floor(abs(x));\n"
-        "    return x * 0.00390625;\n"
-        "}\n";
-    // clang-format on
-}
-
-void RoundingHelperWriterGLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
-                                                          const unsigned int size)
-{
-    std::stringstream vecTypeStrStr;
-    vecTypeStrStr << "vec" << size;
-    std::string vecType = getTypeString(vecTypeStrStr.str().c_str());
-
-    // clang-format off
-    sink <<
-        vecType << " angle_frm(in " << vecType << " v) {\n"
-        "    v = clamp(v, -65504.0, 65504.0);\n"
-        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
-        "    bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n"
-        "    v = v * exp2(-exponent);\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * exp2(exponent) * vec" << size << "(isNonZero);\n"
-        "}\n";
+    floatType << " angle_frm(in " << floatType << " x) {\n"
+    "    x = clamp(x, -65504.0, 65504.0);\n"
+    "    " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n"
+    "    bool isNonZero = (exponent >= -25.0);\n"
+    "    x = x * exp2(-exponent);\n"
+    "    x = sign(x) * floor(abs(x));\n"
+    "    return x * exp2(exponent) * float(isNonZero);\n"
+    "}\n";
 
     sink <<
-        vecType << " angle_frl(in " << vecType << " v) {\n"
-        "    v = clamp(v, -2.0, 2.0);\n"
-        "    v = v * 256.0;\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * 0.00390625;\n"
-        "}\n";
-    // clang-format on
+    floatType << " angle_frl(in " << floatType << " x) {\n"
+    "    x = clamp(x, -2.0, 2.0);\n"
+    "    x = x * 256.0;\n"
+    "    x = sign(x) * floor(abs(x));\n"
+    "    return x * 0.00390625;\n"
+    "}\n";
+
+    writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 2);
+    writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 3);
+    writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 4);
+    if (shaderVersion > 100)
+    {
+        for (unsigned int columns = 2; columns <= 4; ++columns)
+        {
+            for (unsigned int rows = 2; rows <= 4; ++rows)
+            {
+                writeMatrixPrecisionEmulationHelper(sink, outputLanguage, columns, rows,
+                                                    "angle_frm");
+                writeMatrixPrecisionEmulationHelper(sink, outputLanguage, columns, rows,
+                                                    "angle_frl");
+            }
+        }
+    }
+    else
+    {
+        for (unsigned int size = 2; size <= 4; ++size)
+        {
+            writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, size, "angle_frm");
+            writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, size, "angle_frl");
+        }
+    }
 }
 
-void RoundingHelperWriterGLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                                         const unsigned int columns,
-                                                         const unsigned int rows,
-                                                         const char *functionName)
+static void writeCompoundAssignmentPrecisionEmulation(
+    TInfoSinkBase& sink, ShShaderOutput outputLanguage,
+    const char *lType, const char *rType, const char *opStr, const char *opNameStr)
 {
-    std::stringstream matTypeStrStr;
-    matTypeStrStr << "mat" << columns;
-    if (rows != columns)
+    std::string lTypeStr = lType;
+    std::string rTypeStr = rType;
+    if (outputLanguage == SH_ESSL_OUTPUT)
     {
-        matTypeStrStr << "x" << rows;
-    }
-    std::string matType = getTypeString(matTypeStrStr.str().c_str());
-
-    sink << matType << " " << functionName << "(in " << matType << " m) {\n"
-         << "    " << matType << " rounded;\n";
-
-    for (unsigned int i = 0; i < columns; ++i)
-    {
-        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
+        std::stringstream lTypeStrStr;
+        lTypeStrStr << "highp " << lType;
+        lTypeStr = lTypeStrStr.str();
+        std::stringstream rTypeStrStr;
+        rTypeStrStr << "highp " << rType;
+        rTypeStr = rTypeStrStr.str();
     }
 
-    sink << "    return rounded;\n"
-            "}\n";
-}
-
-static const char *GetHLSLTypeStr(const char *floatTypeStr)
-{
-    if (strcmp(floatTypeStr, "float") == 0)
-    {
-        return "float";
-    }
-    if (strcmp(floatTypeStr, "vec2") == 0)
-    {
-        return "float2";
-    }
-    if (strcmp(floatTypeStr, "vec3") == 0)
-    {
-        return "float3";
-    }
-    if (strcmp(floatTypeStr, "vec4") == 0)
-    {
-        return "float4";
-    }
-    if (strcmp(floatTypeStr, "mat2") == 0)
-    {
-        return "float2x2";
-    }
-    if (strcmp(floatTypeStr, "mat3") == 0)
-    {
-        return "float3x3";
-    }
-    if (strcmp(floatTypeStr, "mat4") == 0)
-    {
-        return "float4x4";
-    }
-    if (strcmp(floatTypeStr, "mat2x3") == 0)
-    {
-        return "float2x3";
-    }
-    if (strcmp(floatTypeStr, "mat2x4") == 0)
-    {
-        return "float2x4";
-    }
-    if (strcmp(floatTypeStr, "mat3x2") == 0)
-    {
-        return "float3x2";
-    }
-    if (strcmp(floatTypeStr, "mat3x4") == 0)
-    {
-        return "float3x4";
-    }
-    if (strcmp(floatTypeStr, "mat4x2") == 0)
-    {
-        return "float4x2";
-    }
-    if (strcmp(floatTypeStr, "mat4x3") == 0)
-    {
-        return "float4x3";
-    }
-    UNREACHABLE();
-    return nullptr;
-}
-
-std::string RoundingHelperWriterHLSL::getTypeString(const char *glslType)
-{
-    return GetHLSLTypeStr(glslType);
-}
-
-void RoundingHelperWriterHLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
-{
-    // In HLSL scalars are the same as 1-vectors.
-    writeVectorRoundingHelpers(sink, 1);
-}
-
-void RoundingHelperWriterHLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
-                                                          const unsigned int size)
-{
-    std::stringstream vecTypeStrStr;
-    vecTypeStrStr << "float" << size;
-    std::string vecType = vecTypeStrStr.str();
-
-    // clang-format off
+    // Note that y should be passed through angle_frm at the function call site,
+    // but x can't be passed through angle_frm there since it is an inout parameter.
+    // So only pass x and the result through angle_frm here.
     sink <<
-        vecType << " angle_frm(" << vecType << " v) {\n"
-        "    v = clamp(v, -65504.0, 65504.0);\n"
-        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
-        "    bool" << size << " isNonZero = exponent < -25.0;\n"
-        "    v = v * exp2(-exponent);\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * exp2(exponent) * (float" << size << ")(isNonZero);\n"
-        "}\n";
-
+    lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
+    "    x = angle_frm(angle_frm(x) " << opStr << " y);\n"
+    "    return x;\n"
+    "}\n";
     sink <<
-        vecType << " angle_frl(" << vecType << " v) {\n"
-        "    v = clamp(v, -2.0, 2.0);\n"
-        "    v = v * 256.0;\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * 0.00390625;\n"
-        "}\n";
-    // clang-format on
-}
-
-void RoundingHelperWriterHLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                                         const unsigned int columns,
-                                                         const unsigned int rows,
-                                                         const char *functionName)
-{
-    std::stringstream matTypeStrStr;
-    matTypeStrStr << "float" << columns << "x" << rows;
-    std::string matType = matTypeStrStr.str();
-
-    sink << matType << " " << functionName << "(" << matType << " m) {\n"
-         << "    " << matType << " rounded;\n";
-
-    for (unsigned int i = 0; i < columns; ++i)
-    {
-        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
-    }
-
-    sink << "    return rounded;\n"
-            "}\n";
+    lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
+    "    x = angle_frl(angle_frm(x) " << opStr << " y);\n"
+    "    return x;\n"
+    "}\n";
 }
 
 bool canRoundFloat(const TType &type)
@@ -693,19 +474,20 @@
                                              const int shaderVersion,
                                              const ShShaderOutput outputLanguage)
 {
-    std::unique_ptr<RoundingHelperWriter> roundingHelperWriter(
-        RoundingHelperWriter::createHelperWriter(outputLanguage));
-
-    roundingHelperWriter->writeCommonRoundingHelpers(sink, shaderVersion);
+    // Other languages not yet supported
+    ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
+           IsGLSL130OrNewer(outputLanguage) ||
+           outputLanguage == SH_ESSL_OUTPUT);
+    writeCommonPrecisionEmulationHelpers(sink, shaderVersion, outputLanguage);
 
     EmulationSet::const_iterator it;
     for (it = mEmulateCompoundAdd.begin(); it != mEmulateCompoundAdd.end(); it++)
-        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "+", "add");
+        writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "+", "add");
     for (it = mEmulateCompoundSub.begin(); it != mEmulateCompoundSub.end(); it++)
-        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "-", "sub");
+        writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "-", "sub");
     for (it = mEmulateCompoundDiv.begin(); it != mEmulateCompoundDiv.end(); it++)
-        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "/", "div");
+        writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "/", "div");
     for (it = mEmulateCompoundMul.begin(); it != mEmulateCompoundMul.end(); it++)
-        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul");
+        writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "*", "mul");
 }