diff options
| author | Jay Kwak <82421531+jkwak-work@users.noreply.github.com> | 2025-06-05 10:08:22 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-05 17:08:22 +0000 |
| commit | ca0bdd238f29f2fd17ae44eec913bd6c82e0c1fe (patch) | |
| tree | 880e5c5750b0b2065daed77b423b9adf538fd4f2 /source | |
| parent | 624770a1e1ba7747cd7b2f5e0def1d677e931c8c (diff) | |
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.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 20 |
1 files changed, 18 insertions, 2 deletions
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; } } |
