From bebfac8ec646c3e1e74144ec19f126d4da56ca6b Mon Sep 17 00:00:00 2001 From: Anders Leino Date: Tue, 17 Sep 2024 12:22:11 +0300 Subject: [PATCH] Add WGSL pack/unpack intrinsics This addresses issue #5080. --- source/slang/hlsl.meta.slang | 23 ++++++++++++++--------- source/slang/slang-capabilities.capdef | 4 ++++ source/slang/slang-emit-wgsl.cpp | 18 ++++++++++++++++++ source/slang/slang-emit-wgsl.h | 7 +++++++ 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 7c68a641c1..bb8c20f2ee 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -7275,12 +7275,13 @@ vector cross(vector left, vector right) // Convert encoded color [__readNone] -[require(cpp_cuda_glsl_hlsl_metal_spirv, sm_4_0_version)] +[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, sm_4_0_version)] int4 D3DCOLORtoUBYTE4(float4 color) { __target_switch { case hlsl: __intrinsic_asm "D3DCOLORtoUBYTE4"; + case wgsl: __intrinsic_asm "bitcast(pack4x8unorm($0)).zyxw"; default: let scaled = color.zyxw * 255.001999f; return int4(scaled); @@ -8030,7 +8031,7 @@ vector exp10(vector x) __glsl_version(420) __cuda_sm_version(6.0) [__readNone] -[require(cpp_cuda_glsl_hlsl_metal_spirv, shader5_sm_5_0)] +[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, shader5_sm_5_0)] float f16tof32(uint value) { __target_switch @@ -8048,12 +8049,13 @@ float f16tof32(uint value) result:$$float = OpFConvert %half }; } + case wgsl: __intrinsic_asm "unpack2x16float($0).x"; } } __generic [__readNone] -[require(cpp_cuda_glsl_hlsl_metal_spirv, shader5_sm_5_0)] +[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, shader5_sm_5_0)] vector f16tof32(vector value) { __target_switch @@ -8078,7 +8080,7 @@ vector f16tof32(vector value) __glsl_version(420) __cuda_sm_version(6.0) [__readNone] -[require(cpp_cuda_glsl_hlsl_metal_spirv, shader5_sm_5_0)] +[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, shader5_sm_5_0)] uint f32tof16(float value) { __target_switch @@ -8096,12 +8098,13 @@ uint f32tof16(float value) result:$$uint = OpUConvert %lowBits }; } + case wgsl: __intrinsic_asm "pack2x16float(vec2f($0,0.0))"; } } __generic [__readNone] -[require(cpp_cuda_glsl_hlsl_metal_spirv, shader5_sm_5_0)] +[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, shader5_sm_5_0)] vector f32tof16(vector value) { __target_switch @@ -8127,7 +8130,7 @@ vector f32tof16(vector value) __glsl_version(420) [__readNone] -[require(cpp_cuda_glsl_hlsl_metal_spirv, shader5_sm_5_0)] +[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, shader5_sm_5_0)] float f16tof32(float16_t value) { __target_switch @@ -8143,12 +8146,13 @@ float f16tof32(float16_t value) result:$$float = OpFConvert $value }; } + case wgsl: __intrinsic_asm "f32($0)"; } } __generic [__readNone] -[require(cpp_cuda_glsl_hlsl_metal_spirv, shader5_sm_5_0)] +[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, shader5_sm_5_0)] vector f16tof32(vector value) { __target_switch @@ -8167,7 +8171,7 @@ vector f16tof32(vector value) // Convert to float16_t __glsl_version(420) [__readNone] -[require(cuda_glsl_metal_spirv, shader5_sm_5_0)] +[require(cuda_glsl_metal_spirv_wgsl, shader5_sm_5_0)] float16_t f32tof16_(float value) { __target_switch @@ -8178,12 +8182,13 @@ float16_t f32tof16_(float value) case spirv: return spirv_asm { OpFConvert $$float16_t result $value }; + case wgsl: __intrinsic_asm "f16($0)"; } } __generic [__readNone] -[require(cuda_glsl_metal_spirv, shader5_sm_5_0)] +[require(cuda_glsl_metal_spirv_wgsl, shader5_sm_5_0)] vector f32tof16_(vector value) { __target_switch diff --git a/source/slang/slang-capabilities.capdef b/source/slang/slang-capabilities.capdef index 3e17b3d19d..9364600411 100644 --- a/source/slang/slang-capabilities.capdef +++ b/source/slang/slang-capabilities.capdef @@ -330,6 +330,10 @@ alias cuda_glsl_spirv = cuda | glsl | spirv; /// [Compound] alias cuda_glsl_metal_spirv = cuda | glsl | metal | spirv; +/// CUDA, GLSL, Metal, SPIRV and WGSL code-gen targets +/// [Compound] +alias cuda_glsl_metal_spirv_wgsl = cuda | glsl | metal | spirv | wgsl; + /// CUDA, and HLSL code-gen targets /// [Compound] alias cuda_hlsl = cuda | hlsl; diff --git a/source/slang/slang-emit-wgsl.cpp b/source/slang/slang-emit-wgsl.cpp index 0a4cca407a..40d8ace91a 100644 --- a/source/slang/slang-emit-wgsl.cpp +++ b/source/slang/slang-emit-wgsl.cpp @@ -1002,4 +1002,22 @@ void WGSLSourceEmitter::emitFrontMatterImpl(TargetRequest* /* targetReq */) } } +void WGSLSourceEmitter::emitIntrinsicCallExprImpl( + IRCall* inst, + UnownedStringSlice intrinsicDefinition, + IRInst* intrinsicInst, + EmitOpInfo const& inOuterPrec + ) +{ + // The f16 constructor is generated for f32tof16 + if (intrinsicDefinition.startsWith("f16")) + { + m_f16ExtensionEnabled = true; + } + + CLikeSourceEmitter::emitIntrinsicCallExprImpl( + inst, intrinsicDefinition, intrinsicInst, inOuterPrec + ); +} + } // namespace Slang diff --git a/source/slang/slang-emit-wgsl.h b/source/slang/slang-emit-wgsl.h index dacd11c3d3..d3cf19d91f 100644 --- a/source/slang/slang-emit-wgsl.h +++ b/source/slang/slang-emit-wgsl.h @@ -53,6 +53,13 @@ class WGSLSourceEmitter : public CLikeSourceEmitter IRInst* inst, const EmitOpInfo& outerPrec ) SLANG_OVERRIDE; + virtual void emitIntrinsicCallExprImpl( + IRCall* inst, + UnownedStringSlice intrinsicDefinition, + IRInst* intrinsicInst, + EmitOpInfo const& inOuterPrec + ) SLANG_OVERRIDE; + void emit(const AddressSpace addressSpace); private: