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

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2002-2011 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/BuiltInFunctionEmulatorGLSL.h"
      10             : #include "compiler/translator/Cache.h"
      11             : #include "compiler/translator/SymbolTable.h"
      12             : #include "compiler/translator/VersionGLSL.h"
      13             : 
      14             : namespace sh
      15             : {
      16             : 
      17           0 : void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
      18             :                                                       sh::GLenum shaderType)
      19             : {
      20           0 :     if (shaderType == GL_VERTEX_SHADER)
      21             :     {
      22           0 :         const TType *int1 = TCache::getType(EbtInt);
      23           0 :         emu->addEmulatedFunction(EOpAbs, int1, "int webgl_abs_emu(int x) { return x * sign(x); }");
      24             :     }
      25           0 : }
      26             : 
      27           0 : void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
      28             :                                                         int targetGLSLVersion)
      29             : {
      30             :     // isnan() is supported since GLSL 1.3.
      31           0 :     if (targetGLSLVersion < GLSL_VERSION_130)
      32           0 :         return;
      33             : 
      34           0 :     const TType *float1 = TCache::getType(EbtFloat);
      35           0 :     const TType *float2 = TCache::getType(EbtFloat, 2);
      36           0 :     const TType *float3 = TCache::getType(EbtFloat, 3);
      37           0 :     const TType *float4 = TCache::getType(EbtFloat, 4);
      38             : 
      39             :     // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
      40             :     emu->addEmulatedFunction(
      41             :         EOpIsNan, float1,
      42           0 :         "bool webgl_isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
      43             :     emu->addEmulatedFunction(
      44             :         EOpIsNan, float2,
      45             :         "bvec2 webgl_isnan_emu(vec2 x)\n"
      46             :         "{\n"
      47             :         "    bvec2 isnan;\n"
      48             :         "    for (int i = 0; i < 2; i++)\n"
      49             :         "    {\n"
      50             :         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
      51             :         "    }\n"
      52             :         "    return isnan;\n"
      53           0 :         "}\n");
      54             :     emu->addEmulatedFunction(
      55             :         EOpIsNan, float3,
      56             :         "bvec3 webgl_isnan_emu(vec3 x)\n"
      57             :         "{\n"
      58             :         "    bvec3 isnan;\n"
      59             :         "    for (int i = 0; i < 3; i++)\n"
      60             :         "    {\n"
      61             :         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
      62             :         "    }\n"
      63             :         "    return isnan;\n"
      64           0 :         "}\n");
      65             :     emu->addEmulatedFunction(
      66             :         EOpIsNan, float4,
      67             :         "bvec4 webgl_isnan_emu(vec4 x)\n"
      68             :         "{\n"
      69             :         "    bvec4 isnan;\n"
      70             :         "    for (int i = 0; i < 4; i++)\n"
      71             :         "    {\n"
      72             :         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
      73             :         "    }\n"
      74             :         "    return isnan;\n"
      75           0 :         "}\n");
      76           0 :     emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1, "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))");
      77             : 
      78             : }
      79             : 
      80             : // Emulate built-in functions missing from GLSL 1.30 and higher
      81           0 : void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType,
      82             :                                                         int targetGLSLVersion)
      83             : {
      84             :     // Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10)
      85           0 :     if (targetGLSLVersion < GLSL_VERSION_410)
      86             :     {
      87           0 :         const TType *float2 = TCache::getType(EbtFloat, 2);
      88           0 :         const TType *uint1  = TCache::getType(EbtUInt);
      89             : 
      90             :         // clang-format off
      91             :         emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
      92             :             "uint webgl_packUnorm2x16_emu(vec2 v)\n"
      93             :             "{\n"
      94             :             "    int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n"
      95             :             "    int y = int(round(clamp(v.y, 0.0, 1.0) * 65535.0));\n"
      96             :             "    return uint((y << 16) | (x & 0xFFFF));\n"
      97           0 :             "}\n");
      98             : 
      99             :         emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1,
     100             :             "vec2 webgl_unpackUnorm2x16_emu(uint u)\n"
     101             :             "{\n"
     102             :             "    float x = float(u & 0xFFFFu) / 65535.0;\n"
     103             :             "    float y = float(u >> 16) / 65535.0;\n"
     104             :             "    return vec2(x, y);\n"
     105           0 :             "}\n");
     106             :         // clang-format on
     107             :     }
     108             : 
     109             :     // Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20)
     110             :     // by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30).
     111           0 :     if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420)
     112             :     {
     113           0 :         const TType *float2 = TCache::getType(EbtFloat, 2);
     114           0 :         const TType *uint1 = TCache::getType(EbtUInt);
     115             : 
     116             :         // clang-format off
     117             :         emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
     118             :             "uint webgl_packSnorm2x16_emu(vec2 v)\n"
     119             :             "{\n"
     120             :             "    #if defined(GL_ARB_shading_language_packing)\n"
     121             :             "        return packSnorm2x16(v);\n"
     122             :             "    #else\n"
     123             :             "        int x = int(round(clamp(v.x, -1.0, 1.0) * 32767.0));\n"
     124             :             "        int y = int(round(clamp(v.y, -1.0, 1.0) * 32767.0));\n"
     125             :             "        return uint((y << 16) | (x & 0xFFFF));\n"
     126             :             "    #endif\n"
     127           0 :             "}\n");
     128             :         emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
     129             :             "#if !defined(GL_ARB_shading_language_packing)\n"
     130             :             "    float webgl_fromSnorm(uint x)\n"
     131             :             "    {\n"
     132             :             "        int xi = (int(x) & 0x7FFF) - (int(x) & 0x8000);\n"
     133             :             "        return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
     134             :             "    }\n"
     135             :             "#endif\n"
     136             :             "\n"
     137             :             "vec2 webgl_unpackSnorm2x16_emu(uint u)\n"
     138             :             "{\n"
     139             :             "    #if defined(GL_ARB_shading_language_packing)\n"
     140             :             "        return unpackSnorm2x16(u);\n"
     141             :             "    #else\n"
     142             :             "        uint y = (u >> 16);\n"
     143             :             "        uint x = u;\n"
     144             :             "        return vec2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n"
     145             :             "    #endif\n"
     146           0 :             "}\n");
     147             :         // Functions uint webgl_f32tof16(float val) and float webgl_f16tof32(uint val) are
     148             :         // based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL".
     149             :         emu->addEmulatedFunction(EOpPackHalf2x16, float2,
     150             :             "#if !defined(GL_ARB_shading_language_packing)\n"
     151             :             "    uint webgl_f32tof16(float val)\n"
     152             :             "    {\n"
     153             :             "        uint f32 = floatBitsToUint(val);\n"
     154             :             "        uint f16 = 0u;\n"
     155             :             "        uint sign = (f32 >> 16) & 0x8000u;\n"
     156             :             "        int exponent = int((f32 >> 23) & 0xFFu) - 127;\n"
     157             :             "        uint mantissa = f32 & 0x007FFFFFu;\n"
     158             :             "        if (exponent == 128)\n"
     159             :             "        {\n"
     160             :             "            // Infinity or NaN\n"
     161             :             "            // NaN bits that are masked out by 0x3FF get discarded.\n"
     162             :             "            // This can turn some NaNs to infinity, but this is allowed by the spec.\n"
     163             :             "            f16 = sign | (0x1Fu << 10);\n"
     164             :             "            f16 |= (mantissa & 0x3FFu);\n"
     165             :             "        }\n"
     166             :             "        else if (exponent > 15)\n"
     167             :             "        {\n"
     168             :             "            // Overflow - flush to Infinity\n"
     169             :             "            f16 = sign | (0x1Fu << 10);\n"
     170             :             "        }\n"
     171             :             "        else if (exponent > -15)\n"
     172             :             "        {\n"
     173             :             "            // Representable value\n"
     174             :             "            exponent += 15;\n"
     175             :             "            mantissa >>= 13;\n"
     176             :             "            f16 = sign | uint(exponent << 10) | mantissa;\n"
     177             :             "        }\n"
     178             :             "        else\n"
     179             :             "        {\n"
     180             :             "            f16 = sign;\n"
     181             :             "        }\n"
     182             :             "        return f16;\n"
     183             :             "    }\n"
     184             :             "#endif\n"
     185             :             "\n"
     186             :             "uint webgl_packHalf2x16_emu(vec2 v)\n"
     187             :             "{\n"
     188             :             "    #if defined(GL_ARB_shading_language_packing)\n"
     189             :             "        return packHalf2x16(v);\n"
     190             :             "    #else\n"
     191             :             "        uint x = webgl_f32tof16(v.x);\n"
     192             :             "        uint y = webgl_f32tof16(v.y);\n"
     193             :             "        return (y << 16) | x;\n"
     194             :             "    #endif\n"
     195           0 :             "}\n");
     196             :         emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1,
     197             :             "#if !defined(GL_ARB_shading_language_packing)\n"
     198             :             "    float webgl_f16tof32(uint val)\n"
     199             :             "    {\n"
     200             :             "        uint sign = (val & 0x8000u) << 16;\n"
     201             :             "        int exponent = int((val & 0x7C00u) >> 10);\n"
     202             :             "        uint mantissa = val & 0x03FFu;\n"
     203             :             "        float f32 = 0.0;\n"
     204             :             "        if(exponent == 0)\n"
     205             :             "        {\n"
     206             :             "            if (mantissa != 0u)\n"
     207             :             "            {\n"
     208             :             "                const float scale = 1.0 / (1 << 24);\n"
     209             :             "                f32 = scale * mantissa;\n"
     210             :             "            }\n"
     211             :             "        }\n"
     212             :             "        else if (exponent == 31)\n"
     213             :             "        {\n"
     214             :             "            return uintBitsToFloat(sign | 0x7F800000u | mantissa);\n"
     215             :             "        }\n"
     216             :             "        else\n"
     217             :             "        {\n"
     218             :             "            exponent -= 15;\n"
     219             :             "            float scale;\n"
     220             :             "            if(exponent < 0)\n"
     221             :             "            {\n"
     222             :             "                // The negative unary operator is buggy on OSX.\n"
     223             :             "                // Work around this by using abs instead.\n"
     224             :             "                scale = 1.0 / (1 << abs(exponent));\n"
     225             :             "            }\n"
     226             :             "            else\n"
     227             :             "            {\n"
     228             :             "                scale = 1 << exponent;\n"
     229             :             "            }\n"
     230             :             "            float decimal = 1.0 + float(mantissa) / float(1 << 10);\n"
     231             :             "            f32 = scale * decimal;\n"
     232             :             "        }\n"
     233             :             "\n"
     234             :             "        if (sign != 0u)\n"
     235             :             "        {\n"
     236             :             "            f32 = -f32;\n"
     237             :             "        }\n"
     238             :             "\n"
     239             :             "        return f32;\n"
     240             :             "    }\n"
     241             :             "#endif\n"
     242             :             "\n"
     243             :             "vec2 webgl_unpackHalf2x16_emu(uint u)\n"
     244             :             "{\n"
     245             :             "    #if defined(GL_ARB_shading_language_packing)\n"
     246             :             "        return unpackHalf2x16(u);\n"
     247             :             "    #else\n"
     248             :             "        uint y = (u >> 16);\n"
     249             :             "        uint x = u & 0xFFFFu;\n"
     250             :             "        return vec2(webgl_f16tof32(x), webgl_f16tof32(y));\n"
     251             :             "    #endif\n"
     252           0 :             "}\n");
     253             :         // clang-format on
     254             :     }
     255           0 : }
     256             : 
     257             : }  // namespace sh

Generated by: LCOV version 1.13