summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2024-09-20 19:55:49 -0700
committerGitHub <noreply@github.com>2024-09-20 19:55:49 -0700
commitc42b5e24b5b9d6b03352d809e0a49485d361154f (patch)
tree50226429a437230ab2920d2230299c0a5a9f5bd2
parenta7fc5b4fa42a7bb0b63436e4c7aad5d5bbb9efe3 (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.
-rw-r--r--source/slang/hlsl.meta.slang466
-rw-r--r--source/slang/slang-capabilities.capdef8
-rw-r--r--source/slang/slang-emit-wgsl.cpp46
-rw-r--r--source/slang/slang-stdlib-textures.cpp41
-rw-r--r--source/slang/slang-stdlib-textures.h5
-rw-r--r--tests/wgsl/texture.slang446
6 files changed, 937 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
);
diff --git a/tests/wgsl/texture.slang b/tests/wgsl/texture.slang
new file mode 100644
index 000000000..999555a55
--- /dev/null
+++ b/tests/wgsl/texture.slang
@@ -0,0 +1,446 @@
+// WGSL supports "textureSample()" only in fragment shader
+//TEST:SIMPLE(filecheck=WGSL): -stage fragment -entry fragMain -target wgsl
+
+//TEST_INPUT: ubuffer(data=[0], stride=4):out,name outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+//TEST_INPUT: Texture1D(size=4, content = zero):name t1D_f32v3
+Texture1D<float3> t1D_f32v3;
+//TEST_INPUT: Texture2D(size=4, content = zero):name t2D_f32v3
+Texture2D<float3> t2D_f32v3;
+//TEST_INPUT: Texture3D(size=4, content = zero):name t3D_f32v3
+Texture3D<float3> t3D_f32v3;
+//TEST_INPUT: TextureCube(size=4, content = zero):name tCube_f32v3
+TextureCube<float3> tCube_f32v3;
+//TEST_INPUT: Texture1D(size=4, content = zero, arrayLength=2):name t1DArray_f32v3
+Texture1DArray<float3> t1DArray_f32v3;
+//TEST_INPUT: Texture2D(size=4, content = zero, arrayLength=2):name t2DArray_f32v3
+Texture2DArray<float3> t2DArray_f32v3;
+//TEST_INPUT: TextureCube(size=4, content = zero, arrayLength=2):name tCubeArray_f32v3
+TextureCubeArray<float3> tCubeArray_f32v3;
+
+//TEST_INPUT: Texture1D(size=4, content = zero):name t1D_f32v4
+Texture1D<float4> t1D_f32v4;
+//TEST_INPUT: Texture2D(size=4, content = zero):name t2D_f32v4
+Texture2D<float4> t2D_f32v4;
+//TEST_INPUT: Texture3D(size=4, content = zero):name t3D_f32v4
+Texture3D<float4> t3D_f32v4;
+//TEST_INPUT: TextureCube(size=4, content = zero):name tCube_f32v4
+TextureCube<float4> tCube_f32v4;
+
+//TEST_INPUT: Texture1D(size=4, content = zero, arrayLength=2):name t1DArray_f32v4
+Texture1DArray<float4> t1DArray_f32v4;
+//TEST_INPUT: Texture2D(size=4, content = zero, arrayLength=2):name t2DArray_f32v4
+Texture2DArray<float4> t2DArray_f32v4;
+//TEST_INPUT: TextureCube(size=4, content = zero, arrayLength=2):name tCubeArray_f32v4
+TextureCubeArray<float4> tCubeArray_f32v4;
+
+__generic<T : __BuiltinType, let sampleCount:int=0, let format:int=0>
+typealias depth2d = __TextureImpl<
+ T,
+ __Shape2D,
+ 0, // isArray
+ 0, // isMS
+ sampleCount,
+ 0, // access
+ 1, // isShadow
+ 0, // isCombined
+ format
+>;
+
+__generic<T : __BuiltinType, let sampleCount:int=0, let format:int=0>
+typealias depth2d_array = __TextureImpl<
+ T,
+ __Shape2D,
+ 1, // isArray
+ 0, // isMS
+ sampleCount,
+ 0, // access
+ 1, // isShadow
+ 0, // isCombined
+ format
+>;
+
+__generic<T : __BuiltinType, let sampleCount:int=0, let format:int=0>
+typealias depthcube = __TextureImpl<
+ T,
+ __ShapeCube,
+ 0, // isArray
+ 0, // isMS
+ sampleCount,
+ 0, // access
+ 1, // isShadow
+ 0, // isCombined
+ format
+>;
+
+__generic<T : __BuiltinType, let sampleCount:int=0, let format:int=0>
+typealias depthcube_array = __TextureImpl<
+ T,
+ __ShapeCube,
+ 1, // isArray
+ 0, // isMS
+ sampleCount,
+ 0, // access
+ 1, // isShadow
+ 0, // isCombined
+ format
+>;
+
+//TEST_INPUT: Texture2D(size=4, content = zero):name d2D
+depth2d<float> d2D;
+//TEST_INPUT: TextureCube(size=4, content = zero):name dCube
+depthcube<float> dCube;
+//TEST_INPUT: Texture2D(size=4, content = zero, arrayLength=2):name d2DArray
+depth2d_array<float> d2DArray;
+//TEST_INPUT: TextureCube(size=4, content = zero, arrayLength=2):name dCubeArray
+depthcube_array<float> dCubeArray;
+
+//TEST_INPUT: Sampler:name samplerState
+SamplerState samplerState;
+//TEST_INPUT: Sampler:name shadowSampler
+SamplerComparisonState shadowSampler;
+
+
+__generic<T:__BuiltinArithmeticType, let N:int>
+bool TEST_texture(
+ Texture1D<vector<T,N>> t1D,
+ Texture2D<vector<T,N>> t2D,
+ Texture3D<vector<T,N>> t3D,
+ TextureCube<vector<T,N>> tCube,
+ Texture1DArray<vector<T,N>> t1DArray,
+ Texture2DArray<vector<T,N>> t2DArray,
+ TextureCubeArray<vector<T,N>> tCubeArray
+)
+{
+ // WGSL-LABEL: TEST_texture
+ typealias Tvn = vector<T,N>;
+ typealias Tv4 = vector<T,4>;
+
+ float u = 0;
+ float u2 = 0.5;
+ constexpr const float ddx = 0.0f;
+ constexpr const float ddy = 0.0f;
+
+ uint width = 0, height = 0, depth = 0;
+ uint elements = 0;
+
+ bool voidResult = true;
+
+ // ======================
+ // void GetDimensions()
+ // ======================
+
+ // WGSL: textureDimensions({{\(*}}t1D
+ t1D.GetDimensions(width);
+ voidResult = voidResult && (uint(4) == width);
+
+ // WGSL: textureDimensions({{\(*}}t2D
+ t2D.GetDimensions(width, height);
+ voidResult = voidResult && (uint(4) == width);
+ voidResult = voidResult && (uint(4) == height);
+
+ // WGSL: textureDimensions({{\(*}}t3D
+ t3D.GetDimensions(width, height, depth);
+ voidResult = voidResult && (uint(4) == width);
+ voidResult = voidResult && (uint(4) == height);
+ voidResult = voidResult && (uint(4) == depth);
+
+ // WGSL: textureDimensions({{\(*}}tCube
+ tCube.GetDimensions(width, height);
+ voidResult = voidResult && (uint(4) == width);
+ voidResult = voidResult && (uint(4) == height);
+
+ // WGSL: textureDimensions({{\(*}}t1DArray
+ t1DArray.GetDimensions(width, elements);
+ voidResult = voidResult && (uint(4) == width);
+ voidResult = voidResult && (uint(2) == elements);
+
+ // WGSL: textureDimensions({{\(*}}t2DArray
+ t2DArray.GetDimensions(width, height, elements);
+ voidResult = voidResult && (uint(4) == width);
+ voidResult = voidResult && (uint(4) == height);
+ voidResult = voidResult && (uint(2) == elements);
+
+ // WGSL: textureDimensions({{\(*}}tCubeArray
+ tCubeArray.GetDimensions(width, height, elements);
+ voidResult = voidResult && (uint(4) == width);
+ voidResult = voidResult && (uint(4) == height);
+ voidResult = voidResult && (uint(2) == elements);
+
+ bool result = voidResult
+ // ===============================
+ // float CalculateLevelOfDetail()
+ // ===============================
+ // WGSL doesn't have a way to calculate mip-map level for the given coordinate
+
+ // ========================================
+ // float CalculateLevelOfDetailUnclamped()
+ // ========================================
+ // WGSL doesn't have a way to calculate mip-map level for the given coordinate
+
+ // ===========
+ // T Sample()
+ // https://www.w3.org/TR/WGSL/#texturesample
+ // ===========
+
+ // WGSL: textureSample({{\(*}}t1D
+ && all(Tvn(T(0)) == t1D.Sample(samplerState, u))
+
+ // WGSL: textureSample({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.Sample(samplerState, float2(u, u)))
+
+ // WGSL: textureSample({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.Sample(samplerState, float3(u, u, u)))
+
+ // WGSL: textureSample({{\(*}}tCube
+ && all(Tvn(T(0)) == tCube.Sample(samplerState, normalize(float3(u, 1 - u, u))))
+
+ // WGSL doesn't support textureSample for 1d_array and 3d_array; only 2d and cube
+
+ // WGSL: textureSample({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.Sample(samplerState, float3(u, u, 0)))
+
+ // WGSL: textureSample({{\(*}}tCubeArray
+ && all(Tvn(T(0)) == tCubeArray.Sample(samplerState, float4(normalize(float3(u, 1 - u, u)), 0)))
+
+ // Offset variant
+
+ // WGSL: textureSample({{\(*}}t1D
+ && all(Tvn(T(0)) == t1D.Sample(samplerState, u, 1))
+
+ // WGSL: textureSample({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.Sample(samplerState, float2(u, u), int2(1, 1)))
+
+ // WGSL: textureSample({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.Sample(samplerState, float3(u, u, u), int3(1, 1, 1)))
+
+ // WGSL doesn't support offset variant for cube and cube_array
+
+ // WGSL: textureSample({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.Sample(samplerState, float3(u, u, 0), int2(1, 1)))
+
+ // Clamp variant
+ // WGSL doesn't support clamp variants for `textureSample()`
+
+ // ===============
+ // T SampleBias()
+ // https://www.w3.org/TR/WGSL/#texturesamplebias
+ // ===============
+
+ // WGSL doesn't support Bias for 1D texture
+
+ // WGSL: textureSampleBias({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.SampleBias(samplerState, float2(u, u), float(-1)))
+
+ // WGSL: textureSampleBias({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.SampleBias(samplerState, float3(u, u, u), float(-1)))
+
+ // WGSL: textureSampleBias({{\(*}}tCube
+ && all(Tvn(T(0)) == tCube.SampleBias(samplerState, normalize(float3(u, 1 - u, u)), float(-1)))
+
+ // WGSL: textureSampleBias({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.SampleBias(samplerState, float3(u, u, 0), float(-1)))
+
+ // WGSL: textureSampleBias({{\(*}}tCubeArray
+ && all(Tvn(T(0)) == tCubeArray.SampleBias(samplerState, float4(normalize(float3(u, 1 - u, u)), 0), float(-1)))
+
+ // Offset variant
+
+ // WGSL: textureSampleBias({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.SampleBias(samplerState, float2(u, u), float(-1), int2(1, 1)))
+
+ // WGSL: textureSampleBias({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.SampleBias(samplerState, float3(u, u, u), float(-1), int3(1, 1, 1)))
+
+ // WGSL: textureSampleBias({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.SampleBias(samplerState, float3(u, u, 0), float(-1), int2(1, 1)))
+
+ // ===================================
+ // T SampleLevel()
+ // https://www.w3.org/TR/WGSL/#texturesamplelevel
+ // ===================================
+
+ // WGSL doesn't support textureSampleLevel for 1D texture
+
+ // WGSL: textureSampleLevel({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.SampleLevel(samplerState, float2(u, u), 0))
+
+ // WGSL: textureSampleLevel({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.SampleLevel(samplerState, float3(u, u, u), 0))
+
+ // WGSL: textureSampleLevel({{\(*}}tCube
+ && all(Tvn(T(0)) == tCube.SampleLevel(samplerState, normalize(float3(u, 1 - u, u)), 0))
+
+ // WGSL: textureSampleLevel({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.SampleLevel(samplerState, float3(u, u, 0), 0))
+
+ // WGSL: textureSampleLevel({{\(*}}tCubeArray
+ && all(Tvn(T(0)) == tCubeArray.SampleLevel(samplerState, float4(normalize(float3(u, 1 - u, u)), 0), 0))
+
+ // Offset variant
+
+ // WGSL: textureSampleLevel({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.SampleLevel(samplerState, float2(u, u), 0, int2(1, 1)))
+
+ // WGSL: textureSampleLevel({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.SampleLevel(samplerState, float3(u, u, u), 0, int3(1, 1, 1)))
+
+ // WGSL: textureSampleLevel({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.SampleLevel(samplerState, float3(u, u, 0), 0, int2(1, 1)))
+
+ // ==================
+ // float SampleCmp()
+ // https://www.w3.org/TR/WGSL/#texturesamplecompare
+ // ==================
+
+ // WGSL: textureSampleCompare({{\(*}}d2D
+ && float(0) == d2D.SampleCmp(shadowSampler, float2(u, u), 0)
+
+ // WGSL: textureSampleCompare({{\(*}}d2DArray
+ && float(0) == d2DArray.SampleCmp(shadowSampler, float3(u, u, 0), 0)
+
+ // WGSL: textureSampleCompare({{\(*}}dCube
+ && float(0) == dCube.SampleCmp(shadowSampler, normalize(float3(u, 1 - u, u)), 0)
+
+ // WGSL: textureSampleCompare({{\(*}}dCubeArray
+ && float(0) == dCubeArray.SampleCmp(shadowSampler, float4(normalize(float3(u, 1 - u, u)), 0), 0)
+
+ // Offset variant
+
+ // WGSL doesn't support the offset variant for cube and cube_array
+
+ // WGSL: textureSampleCompare({{\(*}}d2D
+ && float(0) == d2D.SampleCmp(shadowSampler, float2(u2, u), 0, int2(0, 0))
+
+ // WGSL: textureSampleCompare({{\(*}}d2DArray
+ && float(0) == d2DArray.SampleCmp(shadowSampler, float3(u2, u, u), 0, int2(0, 0))
+
+ // ===================================
+ // float SampleCmpLevelZero()
+ // https://www.w3.org/TR/WGSL/#texturesamplecomparelevel
+ // ===================================
+
+ // WGSL: textureSampleCompareLevel({{\(*}}d2D
+ && float(0) == d2D.SampleCmpLevelZero(shadowSampler, float2(u, u), 0)
+
+ // WGSL: textureSampleCompareLevel({{\(*}}d2DArray
+ && float(0) == d2DArray.SampleCmpLevelZero(shadowSampler, float3(u, u, 0), 0)
+
+ // WGSL: textureSampleCompareLevel({{\(*}}dCube
+ && float(0) == dCube.SampleCmpLevelZero(shadowSampler, normalize(float3(u, 1 - u, u)), 0)
+
+ // WGSL: textureSampleCompareLevel({{\(*}}dCubeArray
+ && float(0) == dCubeArray.SampleCmpLevelZero(shadowSampler, float4(normalize(float3(u, 1-u, u)), 0), 0)
+
+ // Offset variant
+
+ // WGSL: textureSampleCompareLevel({{\(*}}d2D
+ && float(0) == d2D.SampleCmpLevelZero(shadowSampler, float2(u2, u), 0, int2(0, 0))
+
+ // WGSL: textureSampleCompareLevel({{\(*}}d2DArray
+ && float(0) == d2DArray.SampleCmpLevelZero(shadowSampler, float3(u2, u, u), 0, int2(0, 0))
+
+ // ==================================
+ // vector<T,4> Gather()
+ // https://www.w3.org/TR/WGSL/#texturegather
+ // ==================================
+
+#if 0
+ && all(Tv4(T(0)) == t2D.Gather(samplerState, float2(u, u)))
+
+ && all(Tv4(T(0)) == tCube.Gather(samplerState, normalize(float3(u, 1 - u, u))))
+
+ && all(Tv4(T(0)) == t2DArray.Gather(samplerState, float3(u, u, 0)))
+
+ && all(Tv4(T(0)) == tCubeArray.Gather(samplerState, float4(normalize(float3(u, 1 - u, u)), 0)))
+
+ // Offset variant
+
+ && all(Tv4(T(0)) == t2D.Gather(samplerState, float2(u2, u), int2(0, 0)))
+
+ && all(Tv4(T(0)) == t2DArray.Gather(samplerState, float3(u2, u, 0), int2(0, 0)))
+#endif
+
+ // =====================================
+ // T SampleGrad()
+ // https://www.w3.org/TR/WGSL/#texturesamplegrad
+ // =====================================
+
+ // WGSL doesn't support textureSampleGrad for 1D textures
+
+ // WGSL: textureSampleGrad({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.SampleGrad(samplerState, float2(u, u), float2(ddx, ddx), float2(ddy, ddy)))
+
+ // WGSL: textureSampleGrad({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.SampleGrad(samplerState, float3(u, u, u), float3(ddx, ddx, ddx), float3(ddy, ddy, ddy)))
+
+ // WGSL: textureSampleGrad({{\(*}}tCube
+ && all(Tvn(T(0)) == tCube.SampleGrad(samplerState, normalize(float3(u, 1 - u, u)), float3(ddx, ddx, ddx), float3(ddy, ddy, ddy)))
+
+ // WGSL: textureSampleGrad({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.SampleGrad(samplerState, float3(u, u, 0.0f), float2(ddx, ddx), float2(ddy, ddy)))
+
+ // WGSL: textureSampleGrad({{\(*}}tCubeArray
+ && all(Tvn(T(0)) == tCubeArray.SampleGrad(samplerState, float4(normalize(float3(u, 1 - u, u)), 0), float3(ddx, ddx, ddx), float3(ddy, ddy, ddy)))
+
+ // Offset variant
+
+ // WGSL: textureSampleGrad({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.SampleGrad(samplerState, float2(u2, u), float2(ddx, ddx), float2(ddy, ddy), int2(0, 0)))
+
+ // WGSL: textureSampleGrad({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.SampleGrad(samplerState, float3(u2, u, u), float3(ddx, ddx, ddx), float3(ddy, ddy, ddy), int3(0, 0, 0)))
+
+ // WGSL: textureSampleGrad({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.SampleGrad(samplerState, float3(u2, u, 0.0f), float2(ddx, ddx), float2(ddy, ddy), int2(0, 0)))
+
+ // ===================
+ // T Load()
+ // https://www.w3.org/TR/WGSL/#textureload
+ // ===================
+
+ // WGSL: textureLoad({{\(*}}t1D
+ && all(Tvn(T(0)) == t1D.Load(int2(0, 0)))
+
+ // WGSL: textureLoad({{\(*}}t2D
+ && all(Tvn(T(0)) == t2D.Load(int3(0, 0, 0)))
+
+ // WGSL: textureLoad({{\(*}}t3D
+ && all(Tvn(T(0)) == t3D.Load(int4(0, 0, 0, 0)))
+
+ // WGSL supports array only for 2D
+
+ // WGSL: textureLoad({{\(*}}t2DArray
+ && all(Tvn(T(0)) == t2DArray.Load(int4(0, 0, 0, 0)))
+
+ // Offset variant
+ // WGSL doesn't support offset variants for Load
+ ;
+
+ return result;
+}
+
+void fragMain()
+{
+ bool result = true
+ && TEST_texture<float, 3>(
+ t1D_f32v3,
+ t2D_f32v3,
+ t3D_f32v3,
+ tCube_f32v3,
+ t1DArray_f32v3,
+ t2DArray_f32v3,
+ tCubeArray_f32v3)
+ && TEST_texture<float, 4>(
+ t1D_f32v4,
+ t2D_f32v4,
+ t3D_f32v4,
+ tCube_f32v4,
+ t1DArray_f32v4,
+ t2DArray_f32v4,
+ tCubeArray_f32v4)
+ ;
+
+ outputBuffer[0] = int(result);
+}