diff options
Diffstat (limited to 'gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp')
-rwxr-xr-x | gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp | 80 |
1 files changed, 20 insertions, 60 deletions
diff --git a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp index 74397fb7f..075a55361 100755 --- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp +++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp @@ -11,68 +11,32 @@ #include "compiler/translator/SymbolTable.h" #include "compiler/translator/VersionGLSL.h" -namespace sh +void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType) { - -void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, - sh::GLenum shaderType) -{ - if (shaderType == GL_VERTEX_SHADER) - { - const TType *int1 = TCache::getType(EbtInt); - emu->addEmulatedFunction(EOpAbs, int1, "int webgl_abs_emu(int x) { return x * sign(x); }"); - } -} - -void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, - int targetGLSLVersion) -{ - // isnan() is supported since GLSL 1.3. - if (targetGLSLVersion < GLSL_VERSION_130) - return; + // we use macros here instead of function definitions to work around more GLSL + // compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are + // problematic because if the argument has side-effects they will be repeatedly + // evaluated. This is unlikely to show up in real shaders, but is something to + // consider. const TType *float1 = TCache::getType(EbtFloat); const TType *float2 = TCache::getType(EbtFloat, 2); const TType *float3 = TCache::getType(EbtFloat, 3); const TType *float4 = TCache::getType(EbtFloat, 4); - // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false. - emu->addEmulatedFunction( - EOpIsNan, float1, - "bool webgl_isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }"); - emu->addEmulatedFunction( - EOpIsNan, float2, - "bvec2 webgl_isnan_emu(vec2 x)\n" - "{\n" - " bvec2 isnan;\n" - " for (int i = 0; i < 2; i++)\n" - " {\n" - " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" - " }\n" - " return isnan;\n" - "}\n"); - emu->addEmulatedFunction( - EOpIsNan, float3, - "bvec3 webgl_isnan_emu(vec3 x)\n" - "{\n" - " bvec3 isnan;\n" - " for (int i = 0; i < 3; i++)\n" - " {\n" - " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" - " }\n" - " return isnan;\n" - "}\n"); - emu->addEmulatedFunction( - EOpIsNan, float4, - "bvec4 webgl_isnan_emu(vec4 x)\n" - "{\n" - " bvec4 isnan;\n" - " for (int i = 0; i < 4; i++)\n" - " {\n" - " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" - " }\n" - " return isnan;\n" - "}\n"); + if (shaderType == GL_FRAGMENT_SHADER) + { + emu->addEmulatedFunction(EOpCos, float1, "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }"); + emu->addEmulatedFunction(EOpCos, float2, "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }"); + emu->addEmulatedFunction(EOpCos, float3, "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }"); + emu->addEmulatedFunction(EOpCos, float4, "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }"); + } + emu->addEmulatedFunction(EOpDistance, float1, float1, "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))"); + emu->addEmulatedFunction(EOpDot, float1, float1, "#define webgl_dot_emu(x, y) ((x) * (y))"); + emu->addEmulatedFunction(EOpLength, float1, "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))"); + emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))"); + emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))"); + emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1, "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))"); } // Emulate built-in functions missing from GLSL 1.30 and higher @@ -217,9 +181,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator " float scale;\n" " if(exponent < 0)\n" " {\n" - " // The negative unary operator is buggy on OSX.\n" - " // Work around this by using abs instead.\n" - " scale = 1.0 / (1 << abs(exponent));\n" + " scale = 1.0 / (1 << -exponent);\n" " }\n" " else\n" " {\n" @@ -251,5 +213,3 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator // clang-format on } } - -} // namespace sh |