diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2024-12-17 19:06:30 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-17 17:06:30 -0800 |
| commit | 6f57e47a9e1675b011f023277b47cfc768d30da8 (patch) | |
| tree | ed9d531c1e1e4f55650314956c485d5107130a21 /source | |
| parent | 49e912a9d0d6ca5f762ec11cd8cb918f182eb76e (diff) | |
Implement bitcast for 64-bit date type (#5895)
Close #5470
* implement bitcast for 64-bit date type
* Move 'ensurePrelude' to base class to remove duplication
* Assert on 'double' type for Metal target, as Metal doesn't have 'double' support
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 11 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 26 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.cpp | 37 | ||||
| -rw-r--r-- | source/slang/slang-emit-metal.cpp | 16 | ||||
| -rw-r--r-- | source/slang/slang-emit-metal.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-emit-wgsl.cpp | 12 | ||||
| -rw-r--r-- | source/slang/slang-emit-wgsl.h | 4 |
8 files changed, 73 insertions, 42 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index f38adc67e..b70069d42 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -5137,4 +5137,15 @@ void CLikeSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink) executeEmitActions(actions); } +void CLikeSourceEmitter::ensurePrelude(const char* preludeText) +{ + IRStringLit* stringLit; + if (!m_builtinPreludes.tryGetValue(preludeText, stringLit)) + { + IRBuilder builder(m_irModule); + stringLit = builder.getStringValue(UnownedStringSlice(preludeText)); + m_builtinPreludes[preludeText] = stringLit; + } + m_requiredPreludes.add(stringLit); +} } // namespace Slang diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h index 7f6f32923..dd8e27674 100644 --- a/source/slang/slang-emit-c-like.h +++ b/source/slang/slang-emit-c-like.h @@ -678,6 +678,9 @@ protected: String _emitLiteralOneWithType(int bitWidth); + + virtual void ensurePrelude(const char* preludeText); + CodeGenContext* m_codeGenContext = nullptr; IRModule* m_irModule = nullptr; @@ -723,6 +726,8 @@ protected: { String requireComputeDerivatives; } m_requiredAfter; + + Dictionary<const char*, IRStringLit*> m_builtinPreludes; }; } // namespace Slang diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 2c2447c53..d6f3795e3 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -2030,6 +2030,32 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu emitType(inst->getDataType()); } break; + case BaseType::Int64: + if (fromType == BaseType::Double) + { + m_writer->emit("int64_t(doubleBitsToInt64("); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); + m_writer->emit("))"); + return true; + } + else + { + emitType(inst->getDataType()); + } + break; + case BaseType::UInt64: + if (fromType == BaseType::Double) + { + m_writer->emit("uint64_t(doubleBitsToUint64("); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); + m_writer->emit("))"); + return true; + } + else + { + emitType(inst->getDataType()); + } + break; case BaseType::Half: switch (fromType) { diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index 824680b72..c43f075b2 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -11,6 +11,23 @@ namespace Slang { +static const char* kHLSLBuiltInPrelude64BitCast = R"( +uint64_t _slang_asuint64(double x) +{ + uint32_t low; + uint32_t high; + asuint(x, low, high); + return ((uint64_t)high << 32) | low; +} + +double _slang_asdouble(uint64_t x) +{ + uint32_t low = x & 0xFFFFFFFF; + uint32_t high = x >> 32; + return asdouble(low, high); +} +)"; + void HLSLSourceEmitter::_emitHLSLDecorationSingleString( const char* name, IRFunc* entryPoint, @@ -822,17 +839,12 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu // // There is no current function (it seems) // for bit-casting an `int16_t` to a `half`. - // - // TODO: There is an `asdouble` function - // for converting two 32-bit integer values into - // one `double`. We could use that for - // bit casts of 64-bit values with a bit of - // extra work, but doing so might be best - // handled in an IR pass that legalizes - // bit-casts. - // m_writer->emit("asfloat"); break; + case BaseType::Double: + ensurePrelude(kHLSLBuiltInPrelude64BitCast); + m_writer->emit("_slang_asdouble"); + break; } m_writer->emit("("); int closeCount = 1; @@ -844,6 +856,8 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu diagnoseUnhandledInst(inst); break; + case BaseType::Int64: + case BaseType::UInt64: case BaseType::UInt: case BaseType::Int: case BaseType::Bool: @@ -860,6 +874,11 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu m_writer->emit("asuint16("); closeCount++; break; + case BaseType::Double: + ensurePrelude(kHLSLBuiltInPrelude64BitCast); + m_writer->emit("_slang_asuint64("); + closeCount++; + break; } emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp index 45a9e60ad..282d8f95c 100644 --- a/source/slang/slang-emit-metal.cpp +++ b/source/slang/slang-emit-metal.cpp @@ -263,18 +263,6 @@ void MetalSourceEmitter::emitEntryPointAttributesImpl( } } -void MetalSourceEmitter::ensurePrelude(const char* preludeText) -{ - IRStringLit* stringLit; - if (!m_builtinPreludes.tryGetValue(preludeText, stringLit)) - { - IRBuilder builder(m_irModule); - stringLit = builder.getStringValue(UnownedStringSlice(preludeText)); - m_builtinPreludes[preludeText] = stringLit; - } - m_requiredPreludes.add(stringLit); -} - void MetalSourceEmitter::emitMemoryOrderOperand(IRInst* inst) { auto memoryOrder = (IRMemoryOrder)getIntVal(inst); @@ -1065,7 +1053,6 @@ void MetalSourceEmitter::emitSimpleTypeImpl(IRType* type) case kIROp_UInt8Type: case kIROp_UIntType: case kIROp_FloatType: - case kIROp_DoubleType: case kIROp_HalfType: { m_writer->emit(getDefaultBuiltinTypeName(type->getOp())); @@ -1093,6 +1080,9 @@ void MetalSourceEmitter::emitSimpleTypeImpl(IRType* type) m_writer->emit(getName(type)); return; + case kIROp_DoubleType: + SLANG_UNEXPECTED("'double' type emitted"); + return; case kIROp_VectorType: { auto vecType = (IRVectorType*)type; diff --git a/source/slang/slang-emit-metal.h b/source/slang/slang-emit-metal.h index 17562b1c4..b67a5b801 100644 --- a/source/slang/slang-emit-metal.h +++ b/source/slang/slang-emit-metal.h @@ -22,13 +22,9 @@ public: virtual RefObject* getExtensionTracker() SLANG_OVERRIDE { return m_extensionTracker; } - Dictionary<const char*, IRStringLit*> m_builtinPreludes; - protected: RefPtr<MetalExtensionTracker> m_extensionTracker; - void ensurePrelude(const char* preludeText); - void emitMemoryOrderOperand(IRInst* inst); virtual void emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) SLANG_OVERRIDE; diff --git a/source/slang/slang-emit-wgsl.cpp b/source/slang/slang-emit-wgsl.cpp index 0e45fd4cf..da5e38327 100644 --- a/source/slang/slang-emit-wgsl.cpp +++ b/source/slang/slang-emit-wgsl.cpp @@ -49,18 +49,6 @@ fn _slang_getNan() -> f32 } )"; -void WGSLSourceEmitter::ensurePrelude(const char* preludeText) -{ - IRStringLit* stringLit; - if (!m_builtinPreludes.tryGetValue(preludeText, stringLit)) - { - IRBuilder builder(m_irModule); - stringLit = builder.getStringValue(UnownedStringSlice(preludeText)); - m_builtinPreludes[preludeText] = stringLit; - } - m_requiredPreludes.add(stringLit); -} - void WGSLSourceEmitter::emitSwitchCaseSelectorsImpl( const SwitchRegion::Case* const currentCase, const bool isDefault) diff --git a/source/slang/slang-emit-wgsl.h b/source/slang/slang-emit-wgsl.h index 28311aa27..390ee876d 100644 --- a/source/slang/slang-emit-wgsl.h +++ b/source/slang/slang-emit-wgsl.h @@ -57,10 +57,6 @@ public: void emit(const AddressSpace addressSpace); virtual bool shouldFoldInstIntoUseSites(IRInst* inst) SLANG_OVERRIDE; - Dictionary<const char*, IRStringLit*> m_builtinPreludes; - -protected: - void ensurePrelude(const char* preludeText); private: bool maybeEmitSystemSemantic(IRInst* inst); |
