diff options
| author | Jay Kwak <82421531+jkwak-work@users.noreply.github.com> | 2024-09-20 19:55:49 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-20 19:55:49 -0700 |
| commit | c42b5e24b5b9d6b03352d809e0a49485d361154f (patch) | |
| tree | 50226429a437230ab2920d2230299c0a5a9f5bd2 /source | |
| parent | a7fc5b4fa42a7bb0b63436e4c7aad5d5bbb9efe3 (diff) | |
WGSL implement texture intrinsics except gather and sampler-less (#5123)
This commit implements all of the texture intrinsics for WGSL except "Gather" and sampler-less.
They will be implemented in a separate PR.
A few things to note:
- texture sampling functions are available only for the fragment shader stage; not for compute
- WGSL doesn't have any functions similar to CalculateLevelOfDetail or CalculateLevelOfDetailUnclamped.
- WGSL doesn't have a function overlaoding for textureSample with "clamp" or "status" arguments.
- WGSL doesn't support Load operation with offset for texture_multisampled_XX and texture_storage_XX.
- WGSL supports only four types of depth textures: 2D, 2D_array, cube and cube_array.
- WGSL doesn't support "offset" variants for cube and cube_array.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 466 | ||||
| -rw-r--r-- | source/slang/slang-capabilities.capdef | 8 | ||||
| -rw-r--r-- | source/slang/slang-emit-wgsl.cpp | 46 | ||||
| -rw-r--r-- | source/slang/slang-stdlib-textures.cpp | 41 | ||||
| -rw-r--r-- | source/slang/slang-stdlib-textures.h | 5 |
5 files changed, 491 insertions, 75 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 7b3113fce..b0c1ed450 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -610,7 +610,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> [__readNone] [ForceInline] - [require(cpp_cuda_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)] + [require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0_fragment)] T Sample(vector<float, Shape.dimensions+isArray> location) { __requireComputeDerivative(); @@ -661,12 +661,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> %sampled : __sampledType(T) = OpImageSampleImplicitLod $this $location None; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + return __getTexture().Sample(__getSampler(), location); } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0_fragment)] T Sample(vector<float, Shape.dimensions+isArray> location, constexpr vector<int, Shape.planeDimensions> offset) { __requireComputeDerivative(); @@ -689,6 +691,8 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> %sampled : __sampledType(T) = OpImageSampleImplicitLod $this $location None|ConstOffset $offset; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + return __getTexture().Sample(__getSampler(), location, offset); } } @@ -740,7 +744,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0_fragment)] T SampleBias(vector<float, Shape.dimensions+isArray> location, float bias) { __requireComputeDerivative(); @@ -763,12 +767,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + return __getTexture().SampleBias(__getSampler(), location, bias); } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0_fragment)] T SampleBias(vector<float, Shape.dimensions+isArray> location, float bias, constexpr vector<int, Shape.planeDimensions> offset) { __requireComputeDerivative(); @@ -790,12 +796,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> %sampled : __sampledType(T) = OpImageSampleImplicitLod $this $location None|Bias|ConstOffset $bias $offset; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + return __getTexture().SampleBias(__getSampler(), location, bias, offset); } } [__readNone] [ForceInline] - [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmp(vector<float, Shape.dimensions+isArray> location, float compareValue) { __requireComputeDerivative(); @@ -826,12 +834,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { result:$$float = OpImageSampleDrefImplicitLod $this $location $compareValue; }; + case wgsl: + return __getTexture().SampleCmp(__getComparisonSampler(), location, compareValue); } } [__readNone] [ForceInline] - [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmpLevelZero(vector<float, Shape.dimensions+isArray> location, float compareValue) { __target_switch @@ -858,12 +868,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { result:$$float = OpImageSampleDrefExplicitLod $this $location $compareValue Lod $zeroFloat; }; + case wgsl: + return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue); } } [__readNone] [ForceInline] - [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmp(vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset) { __requireComputeDerivative(); @@ -890,12 +902,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { result:$$float = OpImageSampleDrefImplicitLod $this $location $compareValue ConstOffset $offset; }; + case wgsl: + return __getTexture().SampleCmp(__getComparisonSampler(), location, compareValue, offset); } } [__readNone] [ForceInline] - [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmpLevelZero(vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset) { __target_switch @@ -922,12 +936,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { result:$$float = OpImageSampleDrefExplicitLod $this $location $compareValue Lod|ConstOffset $zeroFloat $offset; }; + case wgsl: + return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset); } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)] T SampleGrad(vector<float, Shape.dimensions+isArray> location, vector<float, Shape.dimensions> gradX, vector<float, Shape.dimensions> gradY) { __target_switch @@ -940,21 +956,22 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> case cpp: case metal: return __getTexture().SampleGrad(__getSampler(), location, gradX, gradY); - case glsl: - __intrinsic_asm "$ctextureGrad($0, $1, $2, $3)$z"; + __intrinsic_asm "$ctextureGrad($0, $1, $2, $3)$z"; case spirv: return spirv_asm { %sampled : __sampledType(T) = OpImageSampleExplicitLod $this $location None|Grad $gradX $gradY; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + return __getTexture().SampleGrad(__getSampler(), location, gradX, gradY); } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)] T SampleGrad(vector<float, Shape.dimensions+isArray> location, vector<float, Shape.dimensions> gradX, vector<float, Shape.dimensions> gradY, constexpr vector<int, Shape.dimensions> offset) { __target_switch @@ -968,13 +985,15 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> case metal: return __getTexture().SampleGrad(__getSampler(), location, gradX, gradY, offset); case glsl: - __intrinsic_asm "$ctextureGradOffset($0, $1, $2, $3, $4)$z"; + __intrinsic_asm "$ctextureGradOffset($0, $1, $2, $3, $4)$z"; case spirv: return spirv_asm { %sampled : __sampledType(T) = OpImageSampleExplicitLod $this $location None|Grad|ConstOffset $gradX $gradY $offset; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + return __getTexture().SampleGrad(__getSampler(), location, gradX, gradY, offset); } } @@ -1008,7 +1027,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> [__readNone] [ForceInline] - [require(cpp_cuda_glsl_hlsl_metal_spirv, texture_sm_4_0)] + [require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)] T SampleLevel(vector<float, Shape.dimensions+isArray> location, float level) { __target_switch @@ -1060,12 +1079,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> %sampled : __sampledType(T) = OpImageSampleExplicitLod $this $location None|Lod $level; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + return __getTexture().SampleLevel(__getSampler(), location, level); } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)] T SampleLevel(vector<float, Shape.dimensions+isArray> location, float level, constexpr vector<int, Shape.planeDimensions> offset) { __target_switch @@ -1078,7 +1099,6 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> case cpp: case metal: return __getTexture().SampleLevel(__getSampler(), location, level, offset); - case glsl: __intrinsic_asm "$ctextureLodOffset($0, $1, $2, $3)$z"; case spirv: @@ -1087,6 +1107,8 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> %sampled : __sampledType(T) = OpImageSampleExplicitLod $this $location None|Lod|ConstOffset $level $offset; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + return __getTexture().SampleLevel(__getSampler(), location, level, offset); } } } @@ -1147,7 +1169,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> { [__readNone] [ForceInline] - [require(cpp_cuda_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)] + [require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0_fragment)] T Sample(SamplerState s, vector<float, Shape.dimensions+isArray> location) { __requireComputeDerivative(); @@ -1226,12 +1248,29 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> %sampled : __sampledType(T) = OpImageSampleImplicitLod %sampledImage $location None; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSample($0, $1, ($2).x, i32(($2).y))$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSample($0, $1, ($2).xy, i32(($2).z))$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSample($0, $1, ($2).xyz, i32(($2).w))$z"; + } + } + __intrinsic_asm "textureSample($0, $1, $2)$z"; } } + [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0_fragment)] T Sample(SamplerState s, vector<float, Shape.dimensions+isArray> location, constexpr vector<int, Shape.planeDimensions> offset) { __requireComputeDerivative(); @@ -1267,12 +1306,28 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> case glsl: __intrinsic_asm "$ctextureOffset($p, $2, $3)$z"; case spirv: - return spirv_asm - { - %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; - %sampled : __sampledType(T) = OpImageSampleImplicitLod %sampledImage $location None|ConstOffset $offset; - __truncate $$T result __sampledType(T) %sampled; - }; + return spirv_asm + { + %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; + %sampled : __sampledType(T) = OpImageSampleImplicitLod %sampledImage $location None|ConstOffset $offset; + __truncate $$T result __sampledType(T) %sampled; + }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSample($0, $1, ($2).x, i32(($2).y), $3)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSample($0, $1, ($2).xy, i32(($2).z), $3)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSample($0, $1, ($2).xyz, i32(($2).w), $3)$z"; + } + } + __intrinsic_asm "textureSample($0, $1, $2, $3)$z"; } } @@ -1344,7 +1399,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0_fragment)] T SampleBias(SamplerState s, vector<float, Shape.dimensions+isArray> location, float bias) { __requireComputeDerivative(); @@ -1381,20 +1436,36 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> // TODO: This needs to be handled by the capability system __intrinsic_asm "<invalid intrinsic>"; case glsl: - __intrinsic_asm "$ctexture($p, $2, $3)$z"; + __intrinsic_asm "$ctexture($p, $2, $3)$z"; case spirv: - return spirv_asm - { - %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; - %sampled : __sampledType(T) = OpImageSampleImplicitLod %sampledImage $location None|Bias $bias; - __truncate $$T result __sampledType(T) %sampled; - }; + return spirv_asm + { + %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; + %sampled : __sampledType(T) = OpImageSampleImplicitLod %sampledImage $location None|Bias $bias; + __truncate $$T result __sampledType(T) %sampled; + }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleBias($0, $1, ($2).x, i32(($2).y), $3)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleBias($0, $1, ($2).xy, i32(($2).z), $3)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleBias($0, $1, ($2).xyz, i32(($2).w), $3)$z"; + } + } + __intrinsic_asm "textureSampleBias($0, $1, $2, $3)$z"; } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0_fragment)] T SampleBias(SamplerState s, vector<float, Shape.dimensions+isArray> location, float bias, constexpr vector<int, Shape.planeDimensions> offset) { __requireComputeDerivative(); @@ -1428,20 +1499,36 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> // TODO: This needs to be handled by the capability system __intrinsic_asm "<invalid intrinsic>"; case glsl: - __intrinsic_asm "$ctextureOffset($p, $2, $4, $3)$z"; + __intrinsic_asm "$ctextureOffset($p, $2, $4, $3)$z"; case spirv: - return spirv_asm - { - %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; - %sampled : __sampledType(T) = OpImageSampleImplicitLod %sampledImage $location None|Bias|ConstOffset $bias $offset; - __truncate $$T result __sampledType(T) %sampled; - }; + return spirv_asm + { + %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; + %sampled : __sampledType(T) = OpImageSampleImplicitLod %sampledImage $location None|Bias|ConstOffset $bias $offset; + __truncate $$T result __sampledType(T) %sampled; + }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleBias($0, $1, ($2).x, i32(($2).y), $3, $4)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleBias($0, $1, ($2).xy, i32(($2).z), $3, $4)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleBias($0, $1, ($2).xyz, i32(($2).w), $3, $4)$z"; + } + } + __intrinsic_asm "textureSampleBias($0, $1, $2, $3, $4)$z"; } } [__readNone] [ForceInline] - [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmp(SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue) { __requireComputeDerivative(); @@ -1492,12 +1579,28 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; result:$$float = OpImageSampleDrefImplicitLod %sampledImage $location $compareValue; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleCompare($0, $1, ($2).x, i32(($2).y), $3)"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleCompare($0, $1, ($2).xy, i32(($2).z), $3)"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleCompare($0, $1, ($2).xyz, i32(($2).w), $3)"; + } + } + __intrinsic_asm "textureSampleCompare($0, $1, $2, $3)"; } } [__readNone] [ForceInline] - [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmpLevelZero(SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue) { __target_switch @@ -1544,12 +1647,28 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; result:$$float = OpImageSampleDrefExplicitLod %sampledImage $location $compareValue Lod $zeroFloat; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleCompareLevel($0, $1, ($2).x, i32(($2).y), $3)"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleCompareLevel($0, $1, ($2).xy, i32(($2).z), $3)"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleCompareLevel($0, $1, ($2).xyz, i32(($2).w), $3)"; + } + } + __intrinsic_asm "textureSampleCompareLevel($0, $1, $2, $3)"; } } [__readNone] [ForceInline] - [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmp(SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset) { __requireComputeDerivative(); @@ -1593,12 +1712,28 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; result:$$float = OpImageSampleDrefImplicitLod %sampledImage $location $compareValue ConstOffset $offset; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleCompare($0, $1, ($2).x, i32(($2).y), $3, $4)"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleCompare($0, $1, ($2).xy, i32(($2).z), $3, $4)"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleCompare($0, $1, ($2).xyz, i32(($2).w), $3, $4)"; + } + } + __intrinsic_asm "textureSampleCompare($0, $1, $2, $3, $4)"; } } [__readNone] [ForceInline] - [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmpLevelZero(SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset) { __target_switch @@ -1644,12 +1779,28 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; result:$$float = OpImageSampleDrefExplicitLod %sampledImage $location $compareValue Lod|ConstOffset $zeroFloat $offset; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleCompareLevel($0, $1, ($2).x, i32(($2).y), $3, $4)"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleCompareLevel($0, $1, ($2).xy, i32(($2).z), $3, $4)"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleCompareLevel($0, $1, ($2).xyz, i32(($2).w), $3, $4)"; + } + } + __intrinsic_asm "textureSampleCompareLevel($0, $1, $2, $3, $4)"; } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)] T SampleGrad(SamplerState s, vector<float, Shape.dimensions+isArray> location, vector<float, Shape.dimensions> gradX, vector<float, Shape.dimensions> gradY) { __target_switch @@ -1695,12 +1846,28 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> %sampled : __sampledType(T) = OpImageSampleExplicitLod %sampledImage $location None|Grad $gradX $gradY; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleGrad($0, $1, ($2).x, i32(($2).y), $3, $4)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleGrad($0, $1, ($2).xy, i32(($2).z), $3, $4)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleGrad($0, $1, ($2).xyz, i32(($2).w), $3, $4)$z"; + } + } + __intrinsic_asm "textureSampleGrad($0, $1, $2, $3, $4)$z"; } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)] T SampleGrad(SamplerState s, vector<float, Shape.dimensions+isArray> location, vector<float, Shape.dimensions> gradX, vector<float, Shape.dimensions> gradY, constexpr vector<int, Shape.dimensions> offset) { __target_switch @@ -1743,6 +1910,22 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleGrad($0, $1, ($2).x, i32(($2).y), $3, $4, $5)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleGrad($0, $1, ($2).xy, i32(($2).z), $3, $4, $5)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleGrad($0, $1, ($2).xyz, i32(($2).w), $3, $4, $5)$z"; + } + } + __intrinsic_asm "textureSampleGrad($0, $1, $2, $3, $4, $5)$z"; } } @@ -1797,7 +1980,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> [__readNone] [ForceInline] - [require(cpp_cuda_glsl_hlsl_metal_spirv, texture_sm_4_0)] + [require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)] T SampleLevel(SamplerState s, vector<float, Shape.dimensions+isArray> location, float level) { __target_switch @@ -1870,19 +2053,35 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> } } case spirv: - return spirv_asm - { - %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; - %sampled : __sampledType(T) = OpImageSampleExplicitLod %sampledImage $location None|Lod $level; - __truncate $$T result __sampledType(T) %sampled; - }; + return spirv_asm + { + %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; + %sampled : __sampledType(T) = OpImageSampleExplicitLod %sampledImage $location None|Lod $level; + __truncate $$T result __sampledType(T) %sampled; + }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleLevel($0, $1, ($2).x, i32(($2).y), $3)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleLevel($0, $1, ($2).xy, i32(($2).z), $3)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleLevel($0, $1, ($2).xyz, i32(($2).w), $3)$z"; + } + } + __intrinsic_asm "textureSampleLevel($0, $1, $2, $3)$z"; } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)] T SampleLevel(SamplerState s, vector<float, Shape.dimensions+isArray> location, float level, constexpr vector<int, Shape.planeDimensions> offset) { __target_switch @@ -1925,6 +2124,22 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> %sampled : __sampledType(T) = OpImageSampleExplicitLod %sampledImage $location None|Lod|ConstOffset $level $offset; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureSampleLevel($0, $1, ($2).x, i32(($2).y), $3, $4)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureSampleLevel($0, $1, ($2).xy, i32(($2).z), $3, $4)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureSampleLevel($0, $1, ($2).xyz, i32(($2).w), $3, $4)$z"; + } + } + __intrinsic_asm "textureSampleLevel($0, $1, $2, $3, $4)$z"; } } } @@ -2433,7 +2648,7 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,0,isShadow,isCombined,form __glsl_extension(GL_EXT_samplerless_texture_functions) [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1_samplerless)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1_samplerless)] T Load(vector<int, Shape.dimensions+isArray+1> location) { __target_switch @@ -2525,13 +2740,38 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,0,isShadow,isCombined,form __truncate $$T result __sampledType(T) %sampled; }; } + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + static_assert(Shape.flavor == $(SLANG_TEXTURE_1D) + || Shape.flavor == $(SLANG_TEXTURE_2D) + || Shape.flavor == $(SLANG_TEXTURE_3D) + , "WGSL supports textureLoad only for 1D, 2D and 3D textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureLoad($0, ($1).xy, i32(($1).z), ($1).w)$z"; + } + } + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureLoad($0, ($1).x, ($1).y)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureLoad($0, ($1).xy, ($1).z)$z"; + case $(SLANG_TEXTURE_3D): + __intrinsic_asm "textureLoad($0, ($1).xyz, ($1).w)$z"; + } + return T(); } } __glsl_extension(GL_EXT_samplerless_texture_functions) [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_spirv, texture_sm_4_1_samplerless)] + [require(cpp_glsl_hlsl_spirv_wgsl, texture_sm_4_1_samplerless)] T Load(vector<int, Shape.dimensions+isArray+1> location, constexpr vector<int, Shape.planeDimensions> offset) { __target_switch @@ -2562,6 +2802,22 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,0,isShadow,isCombined,form __truncate $$T result __sampledType(T) %sampled; }; } + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureLoad($0, ($1).x, i32(($1).y), $2)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureLoad($0, ($1).xy, i32(($1).z), $2)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureLoad($0, ($1).xyz, i32(($1).w), $2)$z"; + } + } + __intrinsic_asm "textureLoad($0, $1, $2)$z"; } } @@ -2584,7 +2840,7 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,0,isShadow,isCombined,form __glsl_extension(GL_EXT_samplerless_texture_functions) [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1_samplerless)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1_samplerless)] get { __target_switch @@ -2614,6 +2870,8 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,0,isShadow,isCombined,form __truncate $$T result __sampledType(T) %sampled; }; } + case wgsl: + return Load(__makeVector(location, 0)); } } } @@ -2630,7 +2888,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,0,isShadow,isCombined,form __glsl_extension(GL_EXT_samplerless_texture_functions) [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1_samplerless)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1_samplerless)] T Load(vector<int, Shape.dimensions+isArray> location, int sampleIndex) { __target_switch @@ -2686,12 +2944,28 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,0,isShadow,isCombined,form __truncate $$T result __sampledType(T) %sampled; }; } + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureLoad($0, ($1).x, i32(($1).y), $2)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureLoad($0, ($1).xy, i32(($1).z), $2)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureLoad($0, ($1).xyz, i32(($1).w), $2)$z"; + } + } + __intrinsic_asm "textureLoad($0, $1, $2)$z"; } } [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_spirv, texture_sm_4_1_samplerless)] + [require(cpp_glsl_hlsl_spirv_wgsl, texture_sm_4_1_samplerless)] T Load(vector<int, Shape.dimensions + isArray + 1> locationAndSampleIndex) { return Load(__vectorReshape<Shape.dimensions + isArray>(locationAndSampleIndex), locationAndSampleIndex[Shape.dimensions + isArray]); @@ -2707,9 +2981,9 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,0,isShadow,isCombined,form { case cpp: case hlsl: - __intrinsic_asm ".Load"; + __intrinsic_asm ".Load"; case glsl: - __intrinsic_asm "$ctexelFetchOffset($0, $1, ($2), ($3))$z"; + __intrinsic_asm "$ctexelFetchOffset($0, $1, ($2), ($3))$z"; case spirv: if (isCombined != 0) { @@ -2750,7 +3024,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,0,isShadow,isCombined,form __glsl_extension(GL_EXT_samplerless_texture_functions) [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1_samplerless)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1_samplerless)] get { __target_switch @@ -2761,6 +3035,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,0,isShadow,isCombined,form case metal: case glsl: case spirv: + case wgsl: return Load(location, 0); } } @@ -2770,7 +3045,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,0,isShadow,isCombined,form __glsl_extension(GL_EXT_samplerless_texture_functions) [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1_samplerless)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1_samplerless)] get { __target_switch @@ -2781,6 +3056,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,0,isShadow,isCombined,form case metal: case glsl: case spirv: + case wgsl: return Load(location, sampleIndex); } } @@ -2800,7 +3076,7 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,form { [__readNone] [ForceInline] - [require(cpp_cuda_glsl_hlsl_metal_spirv, texture_sm_4_1)] + [require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1)] T Load(vector<int, Shape.dimensions+isArray> location) { __target_switch @@ -2906,6 +3182,22 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,form } static_assert(false, "Unsupported 'Load' of 'texture' for 'metal' target"); __intrinsic_asm "<invalid intrinsics>"; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureLoad($0, ($1).x, i32(($1).y))$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureLoad($0, ($1).xy, i32(($1).z))$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureLoad($0, ($1).xyz, i32(($1).w))$z"; + } + } + __intrinsic_asm "textureLoad($0, $1)$z"; } } @@ -2955,7 +3247,7 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,form { [__readNone] [ForceInline] - [require(cpp_cuda_glsl_hlsl_metal_spirv, texture_sm_4_1)] + [require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1)] get { __target_switch @@ -2967,20 +3259,21 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,form case spirv: case cuda: case metal: + case wgsl: return Load(location); } } [nonmutating] [ForceInline] - [require(cpp_cuda_glsl_hlsl_metal_spirv, texture_sm_4_1)] + [require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1)] set(T newValue) { __target_switch { case cpp: case hlsl: - __intrinsic_asm ".operator[]"; + __intrinsic_asm ".operator[]"; case glsl: __glslImageStore(location, newValue); case cuda: @@ -3068,6 +3361,22 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,form } break; } + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureStore($0, ($1).x, i32(($1).y), $2)$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), $2)$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureStore($0, ($1).xyz, i32(($1).w), $2)$z"; + } + } + __intrinsic_asm "textureStore($0, $1, $2)$z"; } } @@ -3087,7 +3396,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,$(access),isShadow, 0,form { [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1_compute_fragment)] + [require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1_compute_fragment)] T Load(vector<int, Shape.dimensions+isArray> location, int sampleIndex) { __target_switch @@ -3131,6 +3440,22 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,$(access),isShadow, 0,form %sampled:__sampledType(T) = OpImageRead $this $location Sample $sampleIndex; __truncate $$T result __sampledType(T) %sampled; }; + case wgsl: + static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4> + , "WGSL supports only f32 type textures"); + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_1D): + __intrinsic_asm "textureLoad($0, ($1).x, i32(($1).y))$z"; + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "textureLoad($0, ($1).xy, i32(($1).z))$z"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "textureLoad($0, ($1).xyz, i32(($1).w))$z"; + } + } + __intrinsic_asm "textureLoad($0, $1)$z"; } } @@ -3180,7 +3505,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,$(access),isShadow, 0,form { [__readNone] [ForceInline] - [require(cpp_glsl_hlsl_spirv, texture_sm_4_1_compute_fragment)] + [require(cpp_glsl_hlsl_spirv_wgsl, texture_sm_4_1_compute_fragment)] get { __target_switch @@ -3190,6 +3515,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,$(access),isShadow, 0,form __intrinsic_asm "$0.sample[$2][$1]"; case glsl: case spirv: + case wgsl: return Load(location, sampleIndex); } } @@ -3203,7 +3529,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,$(access),isShadow, 0,form { case cpp: case hlsl: - __intrinsic_asm "$0.sample[$2][$1]"; + __intrinsic_asm "$0.sample[$2][$1]"; case glsl: __glslImageStore(location, sampleIndex, newValue); case spirv: diff --git a/source/slang/slang-capabilities.capdef b/source/slang/slang-capabilities.capdef index 42a7db213..102671ffb 100644 --- a/source/slang/slang-capabilities.capdef +++ b/source/slang/slang-capabilities.capdef @@ -298,10 +298,18 @@ alias cpp_glsl = cpp | glsl; /// [Compound] alias cpp_glsl_hlsl_spirv = cpp | glsl | hlsl | spirv; +/// CPP, GLSL, HLSL, SPIRV and WGSL code-gen targets +/// [Compound] +alias cpp_glsl_hlsl_spirv_wgsl = cpp | glsl | hlsl | spirv | wgsl; + /// CPP, GLSL, HLSL, Metal, and SPIRV code-gen targets /// [Compound] alias cpp_glsl_hlsl_metal_spirv = cpp | glsl | hlsl | metal | spirv; +/// CPP, GLSL, HLSL, Metal, SPIRV and WGSL code-gen targets +/// [Compound] +alias cpp_glsl_hlsl_metal_spirv_wgsl = cpp | glsl | hlsl | metal | spirv | wgsl; + /// CPP, and HLSL code-gen targets /// [Compound] alias cpp_hlsl = cpp | hlsl; diff --git a/source/slang/slang-emit-wgsl.cpp b/source/slang/slang-emit-wgsl.cpp index 06fea46b4..833e1c8fe 100644 --- a/source/slang/slang-emit-wgsl.cpp +++ b/source/slang/slang-emit-wgsl.cpp @@ -469,6 +469,52 @@ void WGSLSourceEmitter::emitSimpleTypeImpl(IRType* type) m_writer->emit(">"); return; } + case kIROp_TextureType: + if (auto texType = as<IRTextureType>(type)) + { + switch (texType->getAccess()) + { + case SLANG_RESOURCE_ACCESS_READ_WRITE: + m_writer->emit("texture_storage"); + break; + default: + m_writer->emit("texture"); + break; + } + + if (texType->isShadow()) + { + m_writer->emit("_depth"); + } + + if (texType->isMultisample()) + { + m_writer->emit("_multisampled"); + } + + switch (texType->GetBaseShape()) + { + case SLANG_TEXTURE_1D: m_writer->emit("_1d"); break; + case SLANG_TEXTURE_2D: m_writer->emit("_2d"); break; + case SLANG_TEXTURE_3D: m_writer->emit("_3d"); break; + case SLANG_TEXTURE_CUBE: m_writer->emit("_cube"); break; + } + + if (texType->isArray()) + m_writer->emit("_array"); + + if (!texType->isShadow()) + { + m_writer->emit("<"); + auto elemType = texType->getElementType(); + if (auto vecElemType = as<IRVectorType>(elemType)) + emitSimpleType(vecElemType->getElementType()); + else + emitType(elemType); + m_writer->emit(">"); + } + } + return; case kIROp_AtomicType: { diff --git a/source/slang/slang-stdlib-textures.cpp b/source/slang/slang-stdlib-textures.cpp index dd4df7d9c..a9f14522b 100644 --- a/source/slang/slang-stdlib-textures.cpp +++ b/source/slang/slang-stdlib-textures.cpp @@ -69,7 +69,8 @@ void TextureTypeInfo::writeFuncBody( const String& spirvDefault, const String& spirvRWDefault, const String& spirvCombined, - const String& metal) + const String& metal, + const String& wgsl) { BraceScope funcScope{i, sb}; { @@ -96,7 +97,7 @@ void TextureTypeInfo::writeFuncBody( sb << i << "case metal:\n"; sb << i << "__intrinsic_asm \"" << metal << "\";\n"; } - if(spirvDefault.getLength() && spirvCombined.getLength()) + if (spirvDefault.getLength() && spirvCombined.getLength()) { sb << i << "case spirv:\n"; sb << i << "if (access == " << kStdlibResourceAccessReadWrite << ")\n"; @@ -122,6 +123,11 @@ void TextureTypeInfo::writeFuncBody( } sb << i << "}\n"; } + if (wgsl.getLength()) + { + sb << i << "case wgsl:\n"; + sb << i << "__intrinsic_asm \"" << wgsl << "\";\n"; + } } } @@ -134,13 +140,14 @@ void TextureTypeInfo::writeFuncWithSig( const String& spirvCombined, const String& cuda, const String& metal, + const String& wgsl, const ReadNoneMode readNoneMode) { if (readNoneMode == ReadNoneMode::Always) sb << i << "[__readNone]\n"; sb << i << "[ForceInline]\n"; sb << i << sig << "\n"; - writeFuncBody(funcName, glsl, cuda, spirvDefault, spirvRWDefault, spirvCombined, metal); + writeFuncBody(funcName, glsl, cuda, spirvDefault, spirvRWDefault, spirvCombined, metal, wgsl); sb << "\n"; } @@ -154,6 +161,7 @@ void TextureTypeInfo::writeFunc( const String& spirvCombined, const String& cuda, const String& metal, + const String& wgsl, const ReadNoneMode readNoneMode) { writeFuncWithSig( @@ -165,6 +173,7 @@ void TextureTypeInfo::writeFunc( spirvCombined, cuda, metal, + wgsl, readNoneMode ); } @@ -197,6 +206,9 @@ void TextureTypeInfo::writeGetDimensionFunctions() StringBuilder metal; const char* metalMipLevel = "0"; + StringBuilder wgsl; + wgsl << "{"; + if (includeMipInfo) { ++paramCount; @@ -212,6 +224,7 @@ void TextureTypeInfo::writeGetDimensionFunctions() ++paramCount; params << t << "width"; metal << "(*($" << String(paramCount) << ") = $0.get_width(" << String(metalMipLevel) << ")),"; + wgsl << "*($" << String(paramCount) << ") = textureDimensions($0" << (includeMipInfo ? ", $1" : "") << ");"; sizeDimCount = 1; break; @@ -221,10 +234,13 @@ void TextureTypeInfo::writeGetDimensionFunctions() ++paramCount; params << t << "width,"; metal << "(*($" << String(paramCount) << ") = $0.get_width(" << String(metalMipLevel) << ")),"; + wgsl << "var dim = textureDimensions($0" << (includeMipInfo ? ", $1" : "") << ");"; + wgsl << "(*$" << String(paramCount) << ") = dim.x;"; ++paramCount; params << t << "height"; metal << "(*($" << String(paramCount) << ") = $0.get_height(" << String(metalMipLevel) << ")),"; + wgsl << "(*$" << String(paramCount) << ") = dim.y;"; sizeDimCount = 2; break; @@ -233,14 +249,18 @@ void TextureTypeInfo::writeGetDimensionFunctions() ++paramCount; params << t << "width,"; metal << "(*($" << String(paramCount) << ") = $0.get_width(" << String(metalMipLevel) << ")),"; + wgsl << "var dim = textureDimensions($0" << (includeMipInfo ? ", $1" : "") << ");"; + wgsl << "(*$" << String(paramCount) << ") = dim.x;"; ++paramCount; params << t << "height,"; metal << "(*($" << String(paramCount) << ") = $0.get_height(" << String(metalMipLevel) << ")),"; + wgsl << "(*$" << String(paramCount) << ") = dim.y;"; ++paramCount; params << t << "depth"; metal << "(*($" << String(paramCount) << ") = $0.get_depth(" << String(metalMipLevel) << ")),"; + wgsl << "(*$" << String(paramCount) << ") = dim.z;"; sizeDimCount = 3; break; @@ -256,6 +276,7 @@ void TextureTypeInfo::writeGetDimensionFunctions() ++paramCount; params << ", " << t << "elements"; metal << "(*($" << String(paramCount) << ") = $0.get_array_size()),"; + wgsl << "(*$" << String(paramCount) << ") = textureNumLayers($0);"; } if (isMultisample) @@ -263,6 +284,7 @@ void TextureTypeInfo::writeGetDimensionFunctions() ++paramCount; params << ", " << t << "sampleCount"; metal << "(*($" << String(paramCount) << ") = $0.get_num_samples()),"; + wgsl << "(*$" << String(paramCount) << ") = textureNumSamples($0);"; } if (includeMipInfo) @@ -270,9 +292,11 @@ void TextureTypeInfo::writeGetDimensionFunctions() ++paramCount; params << ", " << t << "numberOfLevels"; metal << "(*($" << String(paramCount) << ") = $0.get_num_mip_levels()),"; + wgsl << "(*$" << String(paramCount) << ") = textureNumLevels($0);"; } metal.reduceLength(metal.getLength() - 1); // drop the last comma + wgsl << "}"; StringBuilder glsl; { @@ -453,7 +477,15 @@ void TextureTypeInfo::writeGetDimensionFunctions() sb << " __glsl_version(450)\n"; sb << " __glsl_extension(GL_EXT_samplerless_texture_functions)\n"; - sb << " [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1)]\n"; + + sb << " [require(cpp"; + if (glsl.getLength()) sb << "_glsl"; + sb << "_hlsl"; + if (metal.getLength()) sb << "_metal"; + if (spirvDefault.getLength() && spirvCombined.getLength()) sb << "_spirv"; + if (wgsl.getLength()) sb << "_wgsl"; + sb << ", texture_sm_4_1)]\n"; + writeFunc( "void", "GetDimensions", @@ -464,6 +496,7 @@ void TextureTypeInfo::writeGetDimensionFunctions() spirvCombined, "", metal, + wgsl, ReadNoneMode::Always); } } diff --git a/source/slang/slang-stdlib-textures.h b/source/slang/slang-stdlib-textures.h index a6166cc2d..a521a44d3 100644 --- a/source/slang/slang-stdlib-textures.h +++ b/source/slang/slang-stdlib-textures.h @@ -69,7 +69,8 @@ public: const String& spirvDefault, const String& spirvRWDefault, const String& spirvCombined, - const String& metal + const String& metal, + const String& wgsl ); void writeFuncWithSig( const char* funcName, @@ -80,6 +81,7 @@ public: const String& spirvCombined = String{}, const String& cuda = String{}, const String& metal = String{}, + const String& wgsl = String{}, const ReadNoneMode readNoneMode = ReadNoneMode::Never ); void writeFunc( @@ -92,6 +94,7 @@ public: const String& spirvCombined = String{}, const String& cuda = String{}, const String& metal = String{}, + const String& wgsl = String{}, const ReadNoneMode readNoneMode = ReadNoneMode::Never ); |
