LCOV - code coverage report
Current view: top level - gfx/angle/src/compiler/translator - BuiltInFunctionEmulatorHLSL.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 78 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 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 "angle_gl.h"
       8             : #include "compiler/translator/BuiltInFunctionEmulator.h"
       9             : #include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
      10             : #include "compiler/translator/SymbolTable.h"
      11             : #include "compiler/translator/VersionGLSL.h"
      12             : 
      13             : namespace sh
      14             : {
      15             : 
      16           0 : void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
      17             :                                                         int targetGLSLVersion)
      18             : {
      19           0 :     if (targetGLSLVersion < GLSL_VERSION_130)
      20           0 :         return;
      21             : 
      22           0 :     TType *float1 = new TType(EbtFloat);
      23           0 :     TType *float2 = new TType(EbtFloat, 2);
      24           0 :     TType *float3 = new TType(EbtFloat, 3);
      25           0 :     TType *float4 = new TType(EbtFloat, 4);
      26             : 
      27             :     emu->addEmulatedFunction(EOpIsNan, float1,
      28             :         "bool webgl_isnan_emu(float x)\n"
      29             :         "{\n"
      30             :         "    return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n"
      31             :         "}\n"
      32           0 :         "\n");
      33             : 
      34             :     emu->addEmulatedFunction(EOpIsNan, float2,
      35             :         "bool2 webgl_isnan_emu(float2 x)\n"
      36             :         "{\n"
      37             :         "    bool2 isnan;\n"
      38             :         "    for (int i = 0; i < 2; i++)\n"
      39             :         "    {\n"
      40             :         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
      41             :         "    }\n"
      42             :         "    return isnan;\n"
      43           0 :         "}\n");
      44             : 
      45             :     emu->addEmulatedFunction(EOpIsNan, float3,
      46             :         "bool3 webgl_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           0 :         "}\n");
      55             : 
      56             :     emu->addEmulatedFunction(EOpIsNan, float4,
      57             :         "bool4 webgl_isnan_emu(float4 x)\n"
      58             :         "{\n"
      59             :         "    bool4 isnan;\n"
      60             :         "    for (int i = 0; i < 4; i++)\n"
      61             :         "    {\n"
      62             :         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
      63             :         "    }\n"
      64             :         "    return isnan;\n"
      65           0 :         "}\n");
      66             : }
      67             : 
      68           0 : void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
      69             : {
      70           0 :     TType *float1 = new TType(EbtFloat);
      71           0 :     TType *float2 = new TType(EbtFloat, 2);
      72           0 :     TType *float3 = new TType(EbtFloat, 3);
      73           0 :     TType *float4 = new TType(EbtFloat, 4);
      74             : 
      75             :     emu->addEmulatedFunction(EOpMod, float1, float1,
      76             :         "float webgl_mod_emu(float x, float y)\n"
      77             :         "{\n"
      78             :         "    return x - y * floor(x / y);\n"
      79             :         "}\n"
      80           0 :         "\n");
      81             :     emu->addEmulatedFunction(EOpMod, float2, float2,
      82             :         "float2 webgl_mod_emu(float2 x, float2 y)\n"
      83             :         "{\n"
      84             :         "    return x - y * floor(x / y);\n"
      85             :         "}\n"
      86           0 :         "\n");
      87             :     emu->addEmulatedFunction(EOpMod, float2, float1,
      88             :         "float2 webgl_mod_emu(float2 x, float y)\n"
      89             :         "{\n"
      90             :         "    return x - y * floor(x / y);\n"
      91             :         "}\n"
      92           0 :         "\n");
      93             :     emu->addEmulatedFunction(EOpMod, float3, float3,
      94             :         "float3 webgl_mod_emu(float3 x, float3 y)\n"
      95             :         "{\n"
      96             :         "    return x - y * floor(x / y);\n"
      97             :         "}\n"
      98           0 :         "\n");
      99             :     emu->addEmulatedFunction(EOpMod, float3, float1,
     100             :         "float3 webgl_mod_emu(float3 x, float y)\n"
     101             :         "{\n"
     102             :         "    return x - y * floor(x / y);\n"
     103             :         "}\n"
     104           0 :         "\n");
     105             :     emu->addEmulatedFunction(EOpMod, float4, float4,
     106             :         "float4 webgl_mod_emu(float4 x, float4 y)\n"
     107             :         "{\n"
     108             :         "    return x - y * floor(x / y);\n"
     109             :         "}\n"
     110           0 :         "\n");
     111             :     emu->addEmulatedFunction(EOpMod, float4, float1,
     112             :         "float4 webgl_mod_emu(float4 x, float y)\n"
     113             :         "{\n"
     114             :         "    return x - y * floor(x / y);\n"
     115             :         "}\n"
     116           0 :         "\n");
     117             : 
     118             :     emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1,
     119             :         "float webgl_faceforward_emu(float N, float I, float Nref)\n"
     120             :         "{\n"
     121             :         "    if(dot(Nref, I) >= 0)\n"
     122             :         "    {\n"
     123             :         "        return -N;\n"
     124             :         "    }\n"
     125             :         "    else\n"
     126             :         "    {\n"
     127             :         "        return N;\n"
     128             :         "    }\n"
     129             :         "}\n"
     130           0 :         "\n");
     131             :     emu->addEmulatedFunction(EOpFaceForward, float2, float2, float2,
     132             :         "float2 webgl_faceforward_emu(float2 N, float2 I, float2 Nref)\n"
     133             :         "{\n"
     134             :         "    if(dot(Nref, I) >= 0)\n"
     135             :         "    {\n"
     136             :         "        return -N;\n"
     137             :         "    }\n"
     138             :         "    else\n"
     139             :         "    {\n"
     140             :         "        return N;\n"
     141             :         "    }\n"
     142             :         "}\n"
     143           0 :         "\n");
     144             :     emu->addEmulatedFunction(EOpFaceForward, float3, float3, float3,
     145             :         "float3 webgl_faceforward_emu(float3 N, float3 I, float3 Nref)\n"
     146             :         "{\n"
     147             :         "    if(dot(Nref, I) >= 0)\n"
     148             :         "    {\n"
     149             :         "        return -N;\n"
     150             :         "    }\n"
     151             :         "    else\n"
     152             :         "    {\n"
     153             :         "        return N;\n"
     154             :         "    }\n"
     155             :         "}\n"
     156           0 :         "\n");
     157             :     emu->addEmulatedFunction(EOpFaceForward, float4, float4, float4,
     158             :         "float4 webgl_faceforward_emu(float4 N, float4 I, float4 Nref)\n"
     159             :         "{\n"
     160             :         "    if(dot(Nref, I) >= 0)\n"
     161             :         "    {\n"
     162             :         "        return -N;\n"
     163             :         "    }\n"
     164             :         "    else\n"
     165             :         "    {\n"
     166             :         "        return N;\n"
     167             :         "    }\n"
     168             :         "}\n"
     169           0 :         "\n");
     170             : 
     171             :     emu->addEmulatedFunction(EOpAtan, float1, float1,
     172             :         "float webgl_atan_emu(float y, float x)\n"
     173             :         "{\n"
     174             :         "    if(x == 0 && y == 0) x = 1;\n"   // Avoid producing a NaN
     175             :         "    return atan2(y, x);\n"
     176           0 :         "}\n");
     177             :     emu->addEmulatedFunction(EOpAtan, float2, float2,
     178             :         "float2 webgl_atan_emu(float2 y, float2 x)\n"
     179             :         "{\n"
     180             :         "    if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
     181             :         "    if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
     182             :         "    return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n"
     183           0 :         "}\n");
     184             :     emu->addEmulatedFunction(EOpAtan, float3, float3,
     185             :         "float3 webgl_atan_emu(float3 y, float3 x)\n"
     186             :         "{\n"
     187             :         "    if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
     188             :         "    if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
     189             :         "    if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
     190             :         "    return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n"
     191           0 :         "}\n");
     192             :     emu->addEmulatedFunction(EOpAtan, float4, float4,
     193             :         "float4 webgl_atan_emu(float4 y, float4 x)\n"
     194             :         "{\n"
     195             :         "    if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
     196             :         "    if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
     197             :         "    if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
     198             :         "    if(x[3] == 0 && y[3] == 0) x[3] = 1;\n"
     199             :         "    return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n"
     200           0 :         "}\n");
     201             : 
     202             :     emu->addEmulatedFunction(EOpAsinh, float1,
     203             :         "float webgl_asinh_emu(in float x) {\n"
     204             :         "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
     205           0 :         "}\n");
     206             :     emu->addEmulatedFunction(EOpAsinh, float2,
     207             :         "float2 webgl_asinh_emu(in float2 x) {\n"
     208             :         "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
     209           0 :         "}\n");
     210             :     emu->addEmulatedFunction(EOpAsinh, float3,
     211             :         "float3 webgl_asinh_emu(in float3 x) {\n"
     212             :         "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
     213           0 :         "}\n");
     214             :     emu->addEmulatedFunction(EOpAsinh, float4,
     215             :         "float4 webgl_asinh_emu(in float4 x) {\n"
     216             :         "    return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
     217           0 :         "}\n");
     218             : 
     219             :     emu->addEmulatedFunction(EOpAcosh, float1,
     220             :         "float webgl_acosh_emu(in float x) {\n"
     221             :         "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
     222           0 :         "}\n");
     223             :     emu->addEmulatedFunction(EOpAcosh, float2,
     224             :         "float2 webgl_acosh_emu(in float2 x) {\n"
     225             :         "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
     226           0 :         "}\n");
     227             :     emu->addEmulatedFunction(EOpAcosh, float3,
     228             :         "float3 webgl_acosh_emu(in float3 x) {\n"
     229             :         "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
     230           0 :         "}\n");
     231             :     emu->addEmulatedFunction(EOpAcosh, float4,
     232             :         "float4 webgl_acosh_emu(in float4 x) {\n"
     233             :         "    return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
     234           0 :         "}\n");
     235             : 
     236             :     emu->addEmulatedFunction(EOpAtanh, float1,
     237             :         "float webgl_atanh_emu(in float x) {\n"
     238             :         "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
     239           0 :         "}\n");
     240             :     emu->addEmulatedFunction(EOpAtanh, float2,
     241             :         "float2 webgl_atanh_emu(in float2 x) {\n"
     242             :         "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
     243           0 :         "}\n");
     244             :     emu->addEmulatedFunction(EOpAtanh, float3,
     245             :         "float3 webgl_atanh_emu(in float3 x) {\n"
     246             :         "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
     247           0 :         "}\n");
     248             :     emu->addEmulatedFunction(EOpAtanh, float4,
     249             :         "float4 webgl_atanh_emu(in float4 x) {\n"
     250             :         "    return 0.5 * log((1.0 + x) / (1.0 - x));\n"
     251           0 :         "}\n");
     252             : 
     253             :     emu->addEmulatedFunction(EOpRoundEven, float1,
     254             :         "float webgl_roundEven_emu(in float x) {\n"
     255             :         "    return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n"
     256           0 :         "}\n");
     257             :     emu->addEmulatedFunction(EOpRoundEven, float2,
     258             :         "float2 webgl_roundEven_emu(in float2 x) {\n"
     259             :         "    float2 v;\n"
     260             :         "    v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
     261             :         "    v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
     262             :         "    return v;\n"
     263           0 :         "}\n");
     264             :     emu->addEmulatedFunction(EOpRoundEven, float3,
     265             :         "float3 webgl_roundEven_emu(in float3 x) {\n"
     266             :         "    float3 v;\n"
     267             :         "    v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
     268             :         "    v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
     269             :         "    v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
     270             :         "    return v;\n"
     271           0 :         "}\n");
     272             :     emu->addEmulatedFunction(EOpRoundEven, float4,
     273             :         "float4 webgl_roundEven_emu(in float4 x) {\n"
     274             :         "    float4 v;\n"
     275             :         "    v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
     276             :         "    v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
     277             :         "    v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
     278             :         "    v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);\n"
     279             :         "    return v;\n"
     280           0 :         "}\n");
     281             : 
     282             :     emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
     283             :         "int webgl_toSnorm(in float x) {\n"
     284             :         "    return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
     285             :         "}\n"
     286             :         "\n"
     287             :         "uint webgl_packSnorm2x16_emu(in float2 v) {\n"
     288             :         "    int x = webgl_toSnorm(v.x);\n"
     289             :         "    int y = webgl_toSnorm(v.y);\n"
     290             :         "    return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n"
     291           0 :         "}\n");
     292             :     emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
     293             :         "uint webgl_toUnorm(in float x) {\n"
     294             :         "    return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n"
     295             :         "}\n"
     296             :         "\n"
     297             :         "uint webgl_packUnorm2x16_emu(in float2 v) {\n"
     298             :         "    uint x = webgl_toUnorm(v.x);\n"
     299             :         "    uint y = webgl_toUnorm(v.y);\n"
     300             :         "    return (y << 16) | x;\n"
     301           0 :         "}\n");
     302             :     emu->addEmulatedFunction(EOpPackHalf2x16, float2,
     303             :         "uint webgl_packHalf2x16_emu(in float2 v) {\n"
     304             :         "    uint x = f32tof16(v.x);\n"
     305             :         "    uint y = f32tof16(v.y);\n"
     306             :         "    return (y << 16) | x;\n"
     307           0 :         "}\n");
     308             : 
     309           0 :     TType *uint1 = new TType(EbtUInt);
     310             : 
     311             :     emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
     312             :         "float webgl_fromSnorm(in uint x) {\n"
     313             :         "    int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n"
     314             :         "    return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
     315             :         "}\n"
     316             :         "\n"
     317             :         "float2 webgl_unpackSnorm2x16_emu(in uint u) {\n"
     318             :         "    uint y = (u >> 16);\n"
     319             :         "    uint x = u;\n"
     320             :         "    return float2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n"
     321           0 :         "}\n");
     322             :     emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1,
     323             :         "float webgl_fromUnorm(in uint x) {\n"
     324             :         "    return float(x) / 65535.0;\n"
     325             :         "}\n"
     326             :         "\n"
     327             :         "float2 webgl_unpackUnorm2x16_emu(in uint u) {\n"
     328             :         "    uint y = (u >> 16);\n"
     329             :         "    uint x = u & 0xffffu;\n"
     330             :         "    return float2(webgl_fromUnorm(x), webgl_fromUnorm(y));\n"
     331           0 :         "}\n");
     332             :     emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1,
     333             :         "float2 webgl_unpackHalf2x16_emu(in uint u) {\n"
     334             :         "    uint y = (u >> 16);\n"
     335             :         "    uint x = u & 0xffffu;\n"
     336             :         "    return float2(f16tof32(x), f16tof32(y));\n"
     337           0 :         "}\n");
     338             : 
     339             :     // The matrix resulting from outer product needs to be transposed
     340             :     // (matrices are stored as transposed to simplify element access in HLSL).
     341             :     // So the function should return transpose(c * r) where c is a column vector
     342             :     // and r is a row vector. This can be simplified by using the following
     343             :     // formula:
     344             :     //   transpose(c * r) = transpose(r) * transpose(c)
     345             :     // transpose(r) and transpose(c) are in a sense free, since to get the
     346             :     // transpose of r, we simply can build a column matrix out of the original
     347             :     // vector instead of a row matrix.
     348             :     emu->addEmulatedFunction(EOpOuterProduct, float2, float2,
     349             :         "float2x2 webgl_outerProduct_emu(in float2 c, in float2 r) {\n"
     350             :         "    return mul(float2x1(r), float1x2(c));\n"
     351           0 :         "}\n");
     352             :     emu->addEmulatedFunction(EOpOuterProduct, float3, float3,
     353             :         "float3x3 webgl_outerProduct_emu(in float3 c, in float3 r) {\n"
     354             :         "    return mul(float3x1(r), float1x3(c));\n"
     355           0 :         "}\n");
     356             :     emu->addEmulatedFunction(EOpOuterProduct, float4, float4,
     357             :         "float4x4 webgl_outerProduct_emu(in float4 c, in float4 r) {\n"
     358             :         "    return mul(float4x1(r), float1x4(c));\n"
     359           0 :         "}\n");
     360             : 
     361             :     emu->addEmulatedFunction(EOpOuterProduct, float3, float2,
     362             :         "float2x3 webgl_outerProduct_emu(in float3 c, in float2 r) {\n"
     363             :         "    return mul(float2x1(r), float1x3(c));\n"
     364           0 :         "}\n");
     365             :     emu->addEmulatedFunction(EOpOuterProduct, float2, float3,
     366             :         "float3x2 webgl_outerProduct_emu(in float2 c, in float3 r) {\n"
     367             :         "    return mul(float3x1(r), float1x2(c));\n"
     368           0 :         "}\n");
     369             :     emu->addEmulatedFunction(EOpOuterProduct, float4, float2,
     370             :         "float2x4 webgl_outerProduct_emu(in float4 c, in float2 r) {\n"
     371             :         "    return mul(float2x1(r), float1x4(c));\n"
     372           0 :         "}\n");
     373             :     emu->addEmulatedFunction(EOpOuterProduct, float2, float4,
     374             :         "float4x2 webgl_outerProduct_emu(in float2 c, in float4 r) {\n"
     375             :         "    return mul(float4x1(r), float1x2(c));\n"
     376           0 :         "}\n");
     377             :     emu->addEmulatedFunction(EOpOuterProduct, float4, float3,
     378             :         "float3x4 webgl_outerProduct_emu(in float4 c, in float3 r) {\n"
     379             :         "    return mul(float3x1(r), float1x4(c));\n"
     380           0 :         "}\n");
     381             :     emu->addEmulatedFunction(EOpOuterProduct, float3, float4,
     382             :         "float4x3 webgl_outerProduct_emu(in float3 c, in float4 r) {\n"
     383             :         "    return mul(float4x1(r), float1x3(c));\n"
     384           0 :         "}\n");
     385             : 
     386           0 :     TType *mat2 = new TType(EbtFloat, 2, 2);
     387           0 :     TType *mat3 = new TType(EbtFloat, 3, 3);
     388           0 :     TType *mat4 = new TType(EbtFloat, 4, 4);
     389             : 
     390             :     // Remember here that the parameter matrix is actually the transpose
     391             :     // of the matrix that we're trying to invert, and the resulting matrix
     392             :     // should also be the transpose of the inverse.
     393             : 
     394             :     // When accessing the parameter matrix with m[a][b] it can be thought of so
     395             :     // that a is the column and b is the row of the matrix that we're inverting.
     396             : 
     397             :     // We calculate the inverse as the adjugate matrix divided by the
     398             :     // determinant of the matrix being inverted. However, as the result needs
     399             :     // to be transposed, we actually use of the transpose of the adjugate matrix
     400             :     // which happens to be the cofactor matrix. That's stored in "cof".
     401             : 
     402             :     // We don't need to care about divide-by-zero since results are undefined
     403             :     // for singular or poorly-conditioned matrices.
     404             : 
     405             :     emu->addEmulatedFunction(EOpInverse, mat2,
     406             :         "float2x2 webgl_inverse_emu(in float2x2 m) {\n"
     407             :         "    float2x2 cof = { m[1][1], -m[0][1], -m[1][0], m[0][0] };\n"
     408             :         "    return cof / determinant(transpose(m));\n"
     409           0 :         "}\n");
     410             : 
     411             :     // cofAB is the cofactor for column A and row B.
     412             : 
     413             :     emu->addEmulatedFunction(EOpInverse, mat3,
     414             :         "float3x3 webgl_inverse_emu(in float3x3 m) {\n"
     415             :         "    float cof00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];\n"
     416             :         "    float cof01 = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);\n"
     417             :         "    float cof02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];\n"
     418             :         "    float cof10 = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);\n"
     419             :         "    float cof11 = m[0][0] * m[2][2] - m[2][0] * m[0][2];\n"
     420             :         "    float cof12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);\n"
     421             :         "    float cof20 = m[0][1] * m[1][2] - m[1][1] * m[0][2];\n"
     422             :         "    float cof21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);\n"
     423             :         "    float cof22 = m[0][0] * m[1][1] - m[1][0] * m[0][1];\n"
     424             :         "    float3x3 cof = { cof00, cof10, cof20, cof01, cof11, cof21, cof02, cof12, cof22 };\n"
     425             :         "    return cof / determinant(transpose(m));\n"
     426           0 :         "}\n");
     427             : 
     428             :     emu->addEmulatedFunction(EOpInverse, mat4,
     429             :         "float4x4 webgl_inverse_emu(in float4x4 m) {\n"
     430             :         "    float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3]"
     431             :                        " - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * m[1][3];\n"
     432             :         "    float cof01 = -(m[1][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[1][3] + m[3][0] * m[1][2] * m[2][3]"
     433             :                        " - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * m[1][3]);\n"
     434             :         "    float cof02 = m[1][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3]"
     435             :                        " - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * m[1][3];\n"
     436             :         "    float cof03 = -(m[1][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[1][2] + m[3][0] * m[1][1] * m[2][2]"
     437             :                        " - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * m[1][2]);\n"
     438             :         "    float cof10 = -(m[0][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[0][3] + m[3][1] * m[0][2] * m[2][3]"
     439             :                        " - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * m[0][3]);\n"
     440             :         "    float cof11 = m[0][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3]"
     441             :                        " - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * m[0][3];\n"
     442             :         "    float cof12 = -(m[0][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[0][3] + m[3][0] * m[0][1] * m[2][3]"
     443             :                        " - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * m[0][3]);\n"
     444             :         "    float cof13 = m[0][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2]"
     445             :                        " - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * m[0][2];\n"
     446             :         "    float cof20 = m[0][1] * m[1][2] * m[3][3] + m[1][1] * m[3][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3]"
     447             :                        " - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * m[0][3];\n"
     448             :         "    float cof21 = -(m[0][0] * m[1][2] * m[3][3] + m[1][0] * m[3][2] * m[0][3] + m[3][0] * m[0][2] * m[1][3]"
     449             :                        " - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * m[0][3]);\n"
     450             :         "    float cof22 = m[0][0] * m[1][1] * m[3][3] + m[1][0] * m[3][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3]"
     451             :                        " - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * m[0][3];\n"
     452             :         "    float cof23 = -(m[0][0] * m[1][1] * m[3][2] + m[1][0] * m[3][1] * m[0][2] + m[3][0] * m[0][1] * m[1][2]"
     453             :                        " - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * m[0][2]);\n"
     454             :         "    float cof30 = -(m[0][1] * m[1][2] * m[2][3] + m[1][1] * m[2][2] * m[0][3] + m[2][1] * m[0][2] * m[1][3]"
     455             :                        " - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * m[0][3]);\n"
     456             :         "    float cof31 = m[0][0] * m[1][2] * m[2][3] + m[1][0] * m[2][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3]"
     457             :                        " - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * m[0][3];\n"
     458             :         "    float cof32 = -(m[0][0] * m[1][1] * m[2][3] + m[1][0] * m[2][1] * m[0][3] + m[2][0] * m[0][1] * m[1][3]"
     459             :                        " - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * m[0][3]);\n"
     460             :         "    float cof33 = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2]"
     461             :                        " - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * m[0][2];\n"
     462             :         "    float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31,"
     463             :                             " cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n"
     464             :         "    return cof / determinant(transpose(m));\n"
     465           0 :         "}\n");
     466             : 
     467           0 :     TType *bool1 = new TType(EbtBool);
     468           0 :     TType *bool2 = new TType(EbtBool, 2);
     469           0 :     TType *bool3 = new TType(EbtBool, 3);
     470           0 :     TType *bool4 = new TType(EbtBool, 4);
     471             : 
     472             :     // Emulate ESSL3 variant of mix that takes last argument as boolean vector.
     473             :     // genType mix (genType x, genType y, genBType a): Selects which vector each returned component comes from.
     474             :     // For a component of 'a' that is false, the corresponding component of 'x' is returned.For a component of 'a' that is true,
     475             :     // the corresponding component of 'y' is returned.
     476             :     emu->addEmulatedFunction(EOpMix, float1, float1, bool1,
     477             :         "float webgl_mix_emu(float x, float y, bool a)\n"
     478             :         "{\n"
     479             :         "    return a ? y : x;\n"
     480           0 :         "}\n");
     481             :     emu->addEmulatedFunction(EOpMix, float2, float2, bool2,
     482             :         "float2 webgl_mix_emu(float2 x, float2 y, bool2 a)\n"
     483             :         "{\n"
     484             :         "    return a ? y : x;\n"
     485           0 :         "}\n");
     486             :     emu->addEmulatedFunction(EOpMix, float3, float3, bool3,
     487             :         "float3 webgl_mix_emu(float3 x, float3 y, bool3 a)\n"
     488             :         "{\n"
     489             :         "    return a ? y : x;\n"
     490           0 :         "}\n");
     491             :     emu->addEmulatedFunction(EOpMix, float4, float4, bool4,
     492             :         "float4 webgl_mix_emu(float4 x, float4 y, bool4 a)\n"
     493             :         "{\n"
     494             :         "    return a ? y : x;\n"
     495           0 :         "}\n");
     496             : 
     497           0 : }
     498             : 
     499             : }  // namespace sh

Generated by: LCOV version 1.13