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