From ca0bdd238f29f2fd17ae44eec913bd6c82e0c1fe Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Thu, 5 Jun 2025 10:08:22 -0700 Subject: Implement isnan and isinf for WGSL with bitwise operations (#7344) WGSL doesn't support isnan and isinf, because it assumes that it always uses fast-math and fast-math doesnt' handle NaN as defined in IEEE standard. The initial implementation used a clever workaround but it stopped working from some point. This PR implemented isnan and isinf with a bitwise operation, which can be expensive. But that seems to be an only option at the moment. --- source/slang/hlsl.meta.slang | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 6a3ae63ec..e00108e96 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -10628,7 +10628,15 @@ bool isinf(T x) case spirv: return spirv_asm { result:$$bool = OpIsInf $x}; case wgsl: - __intrinsic_asm "($0 > 0x1.fffffep+127f) || ($0 < -0x1.fffffep+127f)"; + static_assert(T is float, "isnan is implemented only for float type"); + if (let f = x as float) + { + let bits = asuint(f); + let exp = (bits >> 23) & 0xffu; + let frac = bits & 0x7fffffu; + return exp == 0xffu && frac == 0u; + } + return false; } } @@ -10684,7 +10692,15 @@ bool isnan(T x) case spirv: return spirv_asm { result:$$bool = OpIsNan $x}; case wgsl: - __intrinsic_asm "$0 != $0"; + static_assert(T is float, "isnan is implemented only for float type"); + if (let f = x as float) + { + let bits = asuint(f); + let exp = (bits >> 23) & 0xffu; + let frac = bits & 0x7fffffu; + return exp == 0xffu && frac != 0u; + } + return false; } } -- cgit v1.2.3