tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BuiltInFunctionEmulatorHLSL.cpp (7167B)


      1 //
      2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 #include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
      8 #include "angle_gl.h"
      9 #include "compiler/translator/BuiltInFunctionEmulator.h"
     10 #include "compiler/translator/VersionGLSL.h"
     11 #include "compiler/translator/tree_util/BuiltIn.h"
     12 
     13 namespace sh
     14 {
     15 
     16 // Defined in emulated_builtin_functions_hlsl_autogen.cpp.
     17 const char *FindHLSLFunction(int uniqueId);
     18 
     19 void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
     20                                                        int targetGLSLVersion)
     21 {
     22    if (targetGLSLVersion < GLSL_VERSION_130)
     23        return;
     24 
     25    emu->addEmulatedFunction(BuiltInId::isnan_Float1,
     26                             "bool isnan_emu(float x)\n"
     27                             "{\n"
     28                             "    return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n"
     29                             "}\n"
     30                             "\n");
     31 
     32    emu->addEmulatedFunction(
     33        BuiltInId::isnan_Float2,
     34        "bool2 isnan_emu(float2 x)\n"
     35        "{\n"
     36        "    bool2 isnan;\n"
     37        "    for (int i = 0; i < 2; i++)\n"
     38        "    {\n"
     39        "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
     40        "    }\n"
     41        "    return isnan;\n"
     42        "}\n");
     43 
     44    emu->addEmulatedFunction(
     45        BuiltInId::isnan_Float3,
     46        "bool3 isnan_emu(float3 x)\n"
     47        "{\n"
     48        "    bool3 isnan;\n"
     49        "    for (int i = 0; i < 3; i++)\n"
     50        "    {\n"
     51        "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
     52        "    }\n"
     53        "    return isnan;\n"
     54        "}\n");
     55 
     56    emu->addEmulatedFunction(
     57        BuiltInId::isnan_Float4,
     58        "bool4 isnan_emu(float4 x)\n"
     59        "{\n"
     60        "    bool4 isnan;\n"
     61        "    for (int i = 0; i < 4; i++)\n"
     62        "    {\n"
     63        "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
     64        "    }\n"
     65        "    return isnan;\n"
     66        "}\n");
     67 }
     68 
     69 void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
     70 {
     71    emu->addFunctionMap(FindHLSLFunction);
     72 
     73    // (a + b2^16) * (c + d2^16) = ac + (ad + bc) * 2^16 + bd * 2^32
     74    // Also note that below, a * d + ((a * c) >> 16) is guaranteed not to overflow, because:
     75    // a <= 0xffff, d <= 0xffff, ((a * c) >> 16) <= 0xffff and 0xffff * 0xffff + 0xffff = 0xffff0000
     76    emu->addEmulatedFunction(BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
     77                             "void umulExtended_emu(uint x, uint y, out uint msb, out uint lsb)\n"
     78                             "{\n"
     79                             "    lsb = x * y;\n"
     80                             "    uint a = (x & 0xffffu);\n"
     81                             "    uint b = (x >> 16);\n"
     82                             "    uint c = (y & 0xffffu);\n"
     83                             "    uint d = (y >> 16);\n"
     84                             "    uint ad = a * d + ((a * c) >> 16);\n"
     85                             "    uint bc = b * c;\n"
     86                             "    uint carry = uint(ad > (0xffffffffu - bc));\n"
     87                             "    msb = ((ad + bc) >> 16) + (carry << 16) + b * d;\n"
     88                             "}\n");
     89    emu->addEmulatedFunctionWithDependency(
     90        BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
     91        BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2,
     92        "void umulExtended_emu(uint2 x, uint2 y, out uint2 msb, out uint2 lsb)\n"
     93        "{\n"
     94        "    umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
     95        "    umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
     96        "}\n");
     97    emu->addEmulatedFunctionWithDependency(
     98        BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
     99        BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3,
    100        "void umulExtended_emu(uint3 x, uint3 y, out uint3 msb, out uint3 lsb)\n"
    101        "{\n"
    102        "    umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
    103        "    umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
    104        "    umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
    105        "}\n");
    106    emu->addEmulatedFunctionWithDependency(
    107        BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
    108        BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4,
    109        "void umulExtended_emu(uint4 x, uint4 y, out uint4 msb, out uint4 lsb)\n"
    110        "{\n"
    111        "    umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
    112        "    umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
    113        "    umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
    114        "    umulExtended_emu(x.w, y.w, msb.w, lsb.w);\n"
    115        "}\n");
    116 
    117    // The imul emulation does two's complement negation on the lsb and msb manually in case the
    118    // result needs to be negative.
    119    // TODO(oetuaho): Note that this code doesn't take one edge case into account, where x or y is
    120    // -2^31. abs(-2^31) is undefined.
    121    emu->addEmulatedFunctionWithDependency(
    122        BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
    123        BuiltInId::imulExtended_Int1_Int1_Int1_Int1,
    124        "void imulExtended_emu(int x, int y, out int msb, out int lsb)\n"
    125        "{\n"
    126        "    uint unsignedMsb;\n"
    127        "    uint unsignedLsb;\n"
    128        "    bool negative = (x < 0) != (y < 0);\n"
    129        "    umulExtended_emu(uint(abs(x)), uint(abs(y)), unsignedMsb, unsignedLsb);\n"
    130        "    lsb = asint(unsignedLsb);\n"
    131        "    msb = asint(unsignedMsb);\n"
    132        "    if (negative)\n"
    133        "    {\n"
    134        "        lsb = ~lsb;\n"
    135        "        msb = ~msb;\n"
    136        "        if (lsb == 0xffffffff)\n"
    137        "        {\n"
    138        "            lsb = 0;\n"
    139        "            msb += 1;\n"
    140        "        }\n"
    141        "        else\n"
    142        "        {\n"
    143        "            lsb += 1;\n"
    144        "        }\n"
    145        "    }\n"
    146        "}\n");
    147    emu->addEmulatedFunctionWithDependency(
    148        BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int2_Int2_Int2_Int2,
    149        "void imulExtended_emu(int2 x, int2 y, out int2 msb, out int2 lsb)\n"
    150        "{\n"
    151        "    imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
    152        "    imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
    153        "}\n");
    154    emu->addEmulatedFunctionWithDependency(
    155        BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int3_Int3_Int3_Int3,
    156        "void imulExtended_emu(int3 x, int3 y, out int3 msb, out int3 lsb)\n"
    157        "{\n"
    158        "    imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
    159        "    imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
    160        "    imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
    161        "}\n");
    162    emu->addEmulatedFunctionWithDependency(
    163        BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int4_Int4_Int4_Int4,
    164        "void imulExtended_emu(int4 x, int4 y, out int4 msb, out int4 lsb)\n"
    165        "{\n"
    166        "    imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
    167        "    imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
    168        "    imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
    169        "    imulExtended_emu(x.w, y.w, msb.w, lsb.w);\n"
    170        "}\n");
    171 }
    172 
    173 }  // namespace sh