|
26 | 26 | namespace Slang
|
27 | 27 | {
|
28 | 28 |
|
| 29 | +// In WGSL, expression of "1.0/0.0" is not allowed, it will report compile error, |
| 30 | +// so to construct infinity or nan, we have to assign the float literal to a variable |
| 31 | +// and then use it to bypass the compile error. |
| 32 | +static const char* kWGSLBuiltinPreludeGetInfinity = R"( |
| 33 | +fn _slang_getInfinity(positive: bool) -> f32 |
| 34 | +{ |
| 35 | + let a = select(f32(-1.0), f32(1.0), positive); |
| 36 | + let b = f32(0.0); |
| 37 | + return a / b; |
| 38 | +} |
| 39 | +)"; |
| 40 | + |
| 41 | +static const char* kWGSLBuiltinPreludeGetNan = R"( |
| 42 | +fn _slang_getNan() -> f32 |
| 43 | +{ |
| 44 | + let a = f32(0.0); |
| 45 | + let b = f32(0.0); |
| 46 | + return a / b; |
| 47 | +} |
| 48 | +)"; |
| 49 | + |
| 50 | +void WGSLSourceEmitter::ensurePrelude(const char* preludeText) |
| 51 | +{ |
| 52 | + IRStringLit* stringLit; |
| 53 | + if (!m_builtinPreludes.tryGetValue(preludeText, stringLit)) |
| 54 | + { |
| 55 | + IRBuilder builder(m_irModule); |
| 56 | + stringLit = builder.getStringValue(UnownedStringSlice(preludeText)); |
| 57 | + m_builtinPreludes[preludeText] = stringLit; |
| 58 | + } |
| 59 | + m_requiredPreludes.add(stringLit); |
| 60 | +} |
| 61 | + |
29 | 62 | void WGSLSourceEmitter::emitSwitchCaseSelectorsImpl(
|
30 | 63 | const SwitchRegion::Case* const currentCase,
|
31 | 64 | const bool isDefault)
|
@@ -878,8 +911,32 @@ void WGSLSourceEmitter::emitSimpleValueImpl(IRInst* inst)
|
878 | 911 |
|
879 | 912 | case BaseType::Float:
|
880 | 913 | {
|
881 |
| - m_writer->emit(litInst->value.floatVal); |
882 |
| - m_writer->emit("f"); |
| 914 | + IRConstant::FloatKind kind = litInst->getFloatKind(); |
| 915 | + switch (kind) |
| 916 | + { |
| 917 | + case IRConstant::FloatKind::Nan: |
| 918 | + { |
| 919 | + ensurePrelude(kWGSLBuiltinPreludeGetNan); |
| 920 | + m_writer->emit("_slang_getNan()"); |
| 921 | + break; |
| 922 | + } |
| 923 | + case IRConstant::FloatKind::PositiveInfinity: |
| 924 | + { |
| 925 | + ensurePrelude(kWGSLBuiltinPreludeGetInfinity); |
| 926 | + m_writer->emit("_slang_getInfinity(true)"); |
| 927 | + break; |
| 928 | + } |
| 929 | + case IRConstant::FloatKind::NegativeInfinity: |
| 930 | + { |
| 931 | + ensurePrelude(kWGSLBuiltinPreludeGetInfinity); |
| 932 | + m_writer->emit("_slang_getInfinity(false)"); |
| 933 | + break; |
| 934 | + } |
| 935 | + default: |
| 936 | + m_writer->emit(litInst->value.floatVal); |
| 937 | + m_writer->emit("f"); |
| 938 | + break; |
| 939 | + } |
883 | 940 | }
|
884 | 941 | break;
|
885 | 942 |
|
|
0 commit comments