gfx/angle/angle-faceforward-emu.patch

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/angle/angle-faceforward-emu.patch	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,314 @@
     1.4 +From: Jeff Gilbert <jgilbert@mozilla.com>
     1.5 +Bug 771406 - Add emulation for GLSL faceforward() to ANGLE - r=bjacob
     1.6 +
     1.7 +diff --git a/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp b/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
     1.8 +--- a/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
     1.9 ++++ b/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
    1.10 +@@ -26,16 +26,22 @@ const char* kFunctionEmulationVertexSour
    1.11 +     "#error no emulation for distance(vec3, vec3)",
    1.12 +     "#error no emulation for distance(vec4, vec4)",
    1.13 + 
    1.14 +     "#define webgl_dot_emu(x, y) ((x) * (y))",
    1.15 +     "#error no emulation for dot(vec2, vec2)",
    1.16 +     "#error no emulation for dot(vec3, vec3)",
    1.17 +     "#error no emulation for dot(vec4, vec4)",
    1.18 + 
    1.19 ++    // |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
    1.20 ++    "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
    1.21 ++    "#error no emulation for faceforward(vec2, vec2, vec2)",
    1.22 ++    "#error no emulation for faceforward(vec3, vec3, vec3)",
    1.23 ++    "#error no emulation for faceforward(vec4, vec4, vec4)",
    1.24 ++
    1.25 +     "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
    1.26 +     "#error no emulation for length(vec2)",
    1.27 +     "#error no emulation for length(vec3)",
    1.28 +     "#error no emulation for length(vec4)",
    1.29 + 
    1.30 +     "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
    1.31 +     "#error no emulation for normalize(vec2)",
    1.32 +     "#error no emulation for normalize(vec3)",
    1.33 +@@ -58,16 +64,22 @@ const char* kFunctionEmulationFragmentSo
    1.34 +     "#error no emulation for distance(vec3, vec3)",
    1.35 +     "#error no emulation for distance(vec4, vec4)",
    1.36 + 
    1.37 +     "#define webgl_dot_emu(x, y) ((x) * (y))",
    1.38 +     "#error no emulation for dot(vec2, vec2)",
    1.39 +     "#error no emulation for dot(vec3, vec3)",
    1.40 +     "#error no emulation for dot(vec4, vec4)",
    1.41 + 
    1.42 ++    // |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
    1.43 ++    "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
    1.44 ++    "#error no emulation for faceforward(vec2, vec2, vec2)",
    1.45 ++    "#error no emulation for faceforward(vec3, vec3, vec3)",
    1.46 ++    "#error no emulation for faceforward(vec4, vec4, vec4)",
    1.47 ++
    1.48 +     "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
    1.49 +     "#error no emulation for length(vec2)",
    1.50 +     "#error no emulation for length(vec3)",
    1.51 +     "#error no emulation for length(vec4)",
    1.52 + 
    1.53 +     "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
    1.54 +     "#error no emulation for normalize(vec2)",
    1.55 +     "#error no emulation for normalize(vec3)",
    1.56 +@@ -89,16 +101,20 @@ const bool kFunctionEmulationVertexMask[
    1.57 +     true,  // TFunctionDistance1_1
    1.58 +     false, // TFunctionDistance2_2
    1.59 +     false, // TFunctionDistance3_3
    1.60 +     false, // TFunctionDistance4_4
    1.61 +     true,  // TFunctionDot1_1
    1.62 +     false, // TFunctionDot2_2
    1.63 +     false, // TFunctionDot3_3
    1.64 +     false, // TFunctionDot4_4
    1.65 ++    true,  // TFunctionFaceForward1_1_1
    1.66 ++    false, // TFunctionFaceForward2_2_2
    1.67 ++    false, // TFunctionFaceForward3_3_3
    1.68 ++    false, // TFunctionFaceForward4_4_4
    1.69 +     true,  // TFunctionLength1
    1.70 +     false, // TFunctionLength2
    1.71 +     false, // TFunctionLength3
    1.72 +     false, // TFunctionLength4
    1.73 +     true,  // TFunctionNormalize1
    1.74 +     false, // TFunctionNormalize2
    1.75 +     false, // TFunctionNormalize3
    1.76 +     false, // TFunctionNormalize4
    1.77 +@@ -115,16 +131,20 @@ const bool kFunctionEmulationVertexMask[
    1.78 +     false, // TFunctionDistance1_1
    1.79 +     false, // TFunctionDistance2_2
    1.80 +     false, // TFunctionDistance3_3
    1.81 +     false, // TFunctionDistance4_4
    1.82 +     false, // TFunctionDot1_1
    1.83 +     false, // TFunctionDot2_2
    1.84 +     false, // TFunctionDot3_3
    1.85 +     false, // TFunctionDot4_4
    1.86 ++    false, // TFunctionFaceForward1_1_1
    1.87 ++    false, // TFunctionFaceForward2_2_2
    1.88 ++    false, // TFunctionFaceForward3_3_3
    1.89 ++    false, // TFunctionFaceForward4_4_4
    1.90 +     false, // TFunctionLength1
    1.91 +     false, // TFunctionLength2
    1.92 +     false, // TFunctionLength3
    1.93 +     false, // TFunctionLength4
    1.94 +     false, // TFunctionNormalize1
    1.95 +     false, // TFunctionNormalize2
    1.96 +     false, // TFunctionNormalize3
    1.97 +     false, // TFunctionNormalize4
    1.98 +@@ -146,16 +166,20 @@ const bool kFunctionEmulationFragmentMas
    1.99 +     true,  // TFunctionDistance1_1
   1.100 +     false, // TFunctionDistance2_2
   1.101 +     false, // TFunctionDistance3_3
   1.102 +     false, // TFunctionDistance4_4
   1.103 +     true,  // TFunctionDot1_1
   1.104 +     false, // TFunctionDot2_2
   1.105 +     false, // TFunctionDot3_3
   1.106 +     false, // TFunctionDot4_4
   1.107 ++    true,  // TFunctionFaceForward1_1_1
   1.108 ++    false, // TFunctionFaceForward2_2_2
   1.109 ++    false, // TFunctionFaceForward3_3_3
   1.110 ++    false, // TFunctionFaceForward4_4_4
   1.111 +     true,  // TFunctionLength1
   1.112 +     false, // TFunctionLength2
   1.113 +     false, // TFunctionLength3
   1.114 +     false, // TFunctionLength4
   1.115 +     true,  // TFunctionNormalize1
   1.116 +     false, // TFunctionNormalize2
   1.117 +     false, // TFunctionNormalize3
   1.118 +     false, // TFunctionNormalize4
   1.119 +@@ -172,16 +196,20 @@ const bool kFunctionEmulationFragmentMas
   1.120 +     false, // TFunctionDistance1_1
   1.121 +     false, // TFunctionDistance2_2
   1.122 +     false, // TFunctionDistance3_3
   1.123 +     false, // TFunctionDistance4_4
   1.124 +     false, // TFunctionDot1_1
   1.125 +     false, // TFunctionDot2_2
   1.126 +     false, // TFunctionDot3_3
   1.127 +     false, // TFunctionDot4_4
   1.128 ++    false, // TFunctionFaceForward1_1_1
   1.129 ++    false, // TFunctionFaceForward2_2_2
   1.130 ++    false, // TFunctionFaceForward3_3_3
   1.131 ++    false, // TFunctionFaceForward4_4_4
   1.132 +     false, // TFunctionLength1
   1.133 +     false, // TFunctionLength2
   1.134 +     false, // TFunctionLength3
   1.135 +     false, // TFunctionLength4
   1.136 +     false, // TFunctionNormalize1
   1.137 +     false, // TFunctionNormalize2
   1.138 +     false, // TFunctionNormalize3
   1.139 +     false, // TFunctionNormalize4
   1.140 +@@ -239,25 +267,37 @@ public:
   1.141 +                 case EOpReflect:
   1.142 +                 case EOpRefract:
   1.143 +                 case EOpMul:
   1.144 +                     break;
   1.145 +                 default:
   1.146 +                     return true;
   1.147 +             };
   1.148 +             const TIntermSequence& sequence = node->getSequence();
   1.149 +-            // Right now we only handle built-in functions with two parameters.
   1.150 +-            if (sequence.size() != 2)
   1.151 ++            bool needToEmulate = false;
   1.152 ++
   1.153 ++            if (sequence.size() == 2) {
   1.154 ++                TIntermTyped* param1 = sequence[0]->getAsTyped();
   1.155 ++                TIntermTyped* param2 = sequence[1]->getAsTyped();
   1.156 ++                if (!param1 || !param2)
   1.157 ++                    return true;
   1.158 ++                needToEmulate = mEmulator.SetFunctionCalled(
   1.159 ++                    node->getOp(), param1->getType(), param2->getType());
   1.160 ++            } else if (sequence.size() == 3) {
   1.161 ++                TIntermTyped* param1 = sequence[0]->getAsTyped();
   1.162 ++                TIntermTyped* param2 = sequence[1]->getAsTyped();
   1.163 ++                TIntermTyped* param3 = sequence[2]->getAsTyped();
   1.164 ++                if (!param1 || !param2 || !param3)
   1.165 ++                    return true;
   1.166 ++                needToEmulate = mEmulator.SetFunctionCalled(
   1.167 ++                    node->getOp(), param1->getType(), param2->getType(), param3->getType());
   1.168 ++            } else {
   1.169 +                 return true;
   1.170 +-            TIntermTyped* param1 = sequence[0]->getAsTyped();
   1.171 +-            TIntermTyped* param2 = sequence[1]->getAsTyped();
   1.172 +-            if (!param1 || !param2)
   1.173 +-                return true;
   1.174 +-            bool needToEmulate = mEmulator.SetFunctionCalled(
   1.175 +-                node->getOp(), param1->getType(), param2->getType());
   1.176 ++            }
   1.177 ++
   1.178 +             if (needToEmulate)
   1.179 +                 node->setUseEmulatedFunction();
   1.180 +         }
   1.181 +         return true;
   1.182 +     }
   1.183 + 
   1.184 + private:
   1.185 +     BuiltInFunctionEmulator& mEmulator;
   1.186 +@@ -286,16 +326,23 @@ bool BuiltInFunctionEmulator::SetFunctio
   1.187 + bool BuiltInFunctionEmulator::SetFunctionCalled(
   1.188 +     TOperator op, const TType& param1, const TType& param2)
   1.189 + {
   1.190 +     TBuiltInFunction function = IdentifyFunction(op, param1, param2);
   1.191 +     return SetFunctionCalled(function);
   1.192 + }
   1.193 + 
   1.194 + bool BuiltInFunctionEmulator::SetFunctionCalled(
   1.195 ++    TOperator op, const TType& param1, const TType& param2, const TType& param3)
   1.196 ++{
   1.197 ++    TBuiltInFunction function = IdentifyFunction(op, param1, param2, param3);
   1.198 ++    return SetFunctionCalled(function);
   1.199 ++}
   1.200 ++
   1.201 ++bool BuiltInFunctionEmulator::SetFunctionCalled(
   1.202 +     BuiltInFunctionEmulator::TBuiltInFunction function) {
   1.203 +     if (function == TFunctionUnknown || mFunctionMask[function] == false)
   1.204 +         return false;
   1.205 +     for (size_t i = 0; i < mFunctions.size(); ++i) {
   1.206 +         if (mFunctions[i] == function)
   1.207 +             return true;
   1.208 +     }
   1.209 +     mFunctions.push_back(function);
   1.210 +@@ -377,16 +424,44 @@ BuiltInFunctionEmulator::IdentifyFunctio
   1.211 +     }
   1.212 +     if (function == TFunctionUnknown)
   1.213 +         return TFunctionUnknown;
   1.214 +     if (param1.isVector())
   1.215 +         function += param1.getNominalSize() - 1;
   1.216 +     return static_cast<TBuiltInFunction>(function);
   1.217 + }
   1.218 + 
   1.219 ++BuiltInFunctionEmulator::TBuiltInFunction
   1.220 ++BuiltInFunctionEmulator::IdentifyFunction(
   1.221 ++    TOperator op, const TType& param1, const TType& param2, const TType& param3)
   1.222 ++{
   1.223 ++    // Check that all params have the same type, length,
   1.224 ++    // and that they're not too large.
   1.225 ++    if (param1.isVector() != param2.isVector() ||
   1.226 ++        param2.isVector() != param3.isVector() ||
   1.227 ++        param1.getNominalSize() != param2.getNominalSize() ||
   1.228 ++        param2.getNominalSize() != param3.getNominalSize() ||
   1.229 ++        param1.getNominalSize() > 4)
   1.230 ++        return TFunctionUnknown;
   1.231 ++
   1.232 ++    unsigned int function = TFunctionUnknown;
   1.233 ++    switch (op) {
   1.234 ++        case EOpFaceForward:
   1.235 ++            function = TFunctionFaceForward1_1_1;
   1.236 ++            break;
   1.237 ++        default:
   1.238 ++            break;
   1.239 ++    }
   1.240 ++    if (function == TFunctionUnknown)
   1.241 ++        return TFunctionUnknown;
   1.242 ++    if (param1.isVector())
   1.243 ++        function += param1.getNominalSize() - 1;
   1.244 ++    return static_cast<TBuiltInFunction>(function);
   1.245 ++}
   1.246 ++
   1.247 + void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
   1.248 +     TIntermNode* root)
   1.249 + {
   1.250 +     ASSERT(root);
   1.251 + 
   1.252 +     BuiltInFunctionEmulationMarker marker(*this);
   1.253 +     root->traverse(&marker);
   1.254 + }
   1.255 +diff --git a/gfx/angle/src/compiler/BuiltInFunctionEmulator.h b/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
   1.256 +--- a/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
   1.257 ++++ b/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
   1.258 +@@ -23,16 +23,18 @@ public:
   1.259 +     // Records that a function is called by the shader and might needs to be
   1.260 +     // emulated.  If the function's group is not in mFunctionGroupFilter, this
   1.261 +     // becomes an no-op.
   1.262 +     // Returns true if the function call needs to be replaced with an emulated
   1.263 +     // one.
   1.264 +     bool SetFunctionCalled(TOperator op, const TType& param);
   1.265 +     bool SetFunctionCalled(
   1.266 +         TOperator op, const TType& param1, const TType& param2);
   1.267 ++    bool SetFunctionCalled(
   1.268 ++        TOperator op, const TType& param1, const TType& param2, const TType& param3);
   1.269 + 
   1.270 +     // Output function emulation definition.  This should be before any other
   1.271 +     // shader source.
   1.272 +     void OutputEmulatedFunctionDefinition(TInfoSinkBase& out, bool withPrecision) const;
   1.273 + 
   1.274 +     void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
   1.275 + 
   1.276 +     void Cleanup();
   1.277 +@@ -55,16 +57,21 @@ private:
   1.278 +         TFunctionDistance3_3,  // vec3 distance(vec3, vec3);
   1.279 +         TFunctionDistance4_4,  // vec4 distance(vec4, vec4);
   1.280 + 
   1.281 +         TFunctionDot1_1,  // float dot(float, float);
   1.282 +         TFunctionDot2_2,  // vec2 dot(vec2, vec2);
   1.283 +         TFunctionDot3_3,  // vec3 dot(vec3, vec3);
   1.284 +         TFunctionDot4_4,  // vec4 dot(vec4, vec4);
   1.285 + 
   1.286 ++        TFunctionFaceForward1_1_1,  // float faceforward(float, float, float);
   1.287 ++        TFunctionFaceForward2_2_2,  // vec2 faceforward(vec2, vec2, vec2);
   1.288 ++        TFunctionFaceForward3_3_3,  // vec3 faceforward(vec3, vec3, vec3);
   1.289 ++        TFunctionFaceForward4_4_4,  // vec4 faceforward(vec4, vec4, vec4);
   1.290 ++
   1.291 +         TFunctionLength1,  // float length(float);
   1.292 +         TFunctionLength2,  // float length(vec2);
   1.293 +         TFunctionLength3,  // float length(vec3);
   1.294 +         TFunctionLength4,  // float length(vec4);
   1.295 + 
   1.296 +         TFunctionNormalize1,  // float normalize(float);
   1.297 +         TFunctionNormalize2,  // vec2 normalize(vec2);
   1.298 +         TFunctionNormalize3,  // vec3 normalize(vec3);
   1.299 +@@ -76,16 +83,18 @@ private:
   1.300 +         TFunctionReflect4_4,  // vec4 reflect(vec4, vec4);
   1.301 + 
   1.302 +         TFunctionUnknown
   1.303 +     };
   1.304 + 
   1.305 +     TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
   1.306 +     TBuiltInFunction IdentifyFunction(
   1.307 +         TOperator op, const TType& param1, const TType& param2);
   1.308 ++    TBuiltInFunction IdentifyFunction(
   1.309 ++        TOperator op, const TType& param1, const TType& param2, const TType& param3);
   1.310 + 
   1.311 +     bool SetFunctionCalled(TBuiltInFunction function);
   1.312 + 
   1.313 +     std::vector<TBuiltInFunction> mFunctions;
   1.314 + 
   1.315 +     const bool* mFunctionMask;  // a boolean flag for each function.
   1.316 +     const char** mFunctionSource;
   1.317 + };

mercurial