summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2024-09-25 10:04:22 -0700
committerGitHub <noreply@github.com>2024-09-25 10:04:22 -0700
commit03765a691531d69a30734beb0433d8d4cac45024 (patch)
tree30b0d802f1e24bae1d15fec8d498f6207919a744 /source
parent88623edb8120333d48a9ebdec73063f94a10282e (diff)
WGSL texture support for depth and multisampled (#5152)
* WGSL texture support for depth and multisampled This commit fixes a few issues with WGSL texture intrinsics. - static_assert-s are corrected. - Gather functions work properly with depth textures - Load functions work properly with depth textures and multisampled textures
Diffstat (limited to 'source')
-rw-r--r--source/slang/hlsl.meta.slang116
-rw-r--r--source/slang/slang-intrinsic-expand.cpp11
2 files changed, 71 insertions, 56 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index bbdfc3b03..c646f5cb7 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -2229,6 +2229,22 @@ vector<TElement,4> __texture_gather(
result:$$vector<TElement,4> = OpImageGather %sampledImage $location $component;
};
case wgsl:
+ if (isShadow == 1)
+ {
+ // If depth texture, `textureGather` doesn't take channel value, `$3`.
+ if (isArray == 1)
+ {
+ switch (Shape.flavor)
+ {
+ case $(SLANG_TEXTURE_2D):
+ __intrinsic_asm "textureGather($0, $1, ($2).xy, u32(($2).z))";
+ case $(SLANG_TEXTURE_CUBE):
+ __intrinsic_asm "textureGather($0, $1, ($2).xyz, u32(($2).w))";
+ }
+ }
+ __intrinsic_asm "textureGather($0, $1, $2)";
+ }
+
if (isArray == 1)
{
switch (Shape.flavor)
@@ -2293,6 +2309,22 @@ vector<TElement,4> __texture_gather_offset(
result:$$vector<TElement,4> = OpImageGather %sampledImage $location $component ConstOffset $offset;
};
case wgsl:
+ if (isShadow == 1)
+ {
+ // If depth texture, `textureGather` doesn't take channel value, `$4`.
+ if (isArray == 1)
+ {
+ switch (Shape.flavor)
+ {
+ case $(SLANG_TEXTURE_2D):
+ __intrinsic_asm "textureGather($0, $1, ($2).xy, u32(($2).z), $3)";
+ case $(SLANG_TEXTURE_CUBE):
+ __intrinsic_asm "textureGather($0, $1, ($2).xyz, u32(($2).w), $3)";
+ }
+ }
+ __intrinsic_asm "textureGather($0, $1, $2, $3)";
+ }
+
if (isArray == 1)
{
switch (Shape.flavor)
@@ -2413,6 +2445,8 @@ vector<TElement,4> __texture_gatherCmp(
result:$$vector<TElement,4> = OpImageDrefGather %sampledImage $location $compareValue;
};
case wgsl:
+ static_assert(isShadow == 1, "WGSL supports textureGatherCompare only for depth textures.");
+
if (isArray == 1)
{
switch (Shape.flavor)
@@ -2477,6 +2511,8 @@ vector<TElement,4> __texture_gatherCmp_offset(
result:$$vector<TElement,4> = OpImageDrefGather %sampledImage $location $compareValue ConstOffset $offset;
};
case wgsl:
+ static_assert(isShadow == 1, "WGSL supports textureGatherCompare only for depth textures.");
+
if (isArray == 1)
{
switch (Shape.flavor)
@@ -2841,12 +2877,13 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,0,isShadow,isCombined,form
};
}
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");
+ , "WGSL doesn't supports textureLoad for Cube texture.");
+ static_assert(isArray == 0 || Shape.flavor == $(SLANG_TEXTURE_2D)
+ , "WGSL supports textureLoad for texture_2d_array but not for array of 1D, 3D or Cube.");
+
if (isArray == 1)
{
switch (Shape.flavor)
@@ -2871,7 +2908,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_spirv_wgsl, texture_sm_4_1_samplerless)]
+ [require(cpp_glsl_hlsl_spirv, texture_sm_4_1_samplerless)]
T Load(vector<int, Shape.dimensions+isArray+1> location, constexpr vector<int, Shape.planeDimensions> offset)
{
__target_switch
@@ -2902,22 +2939,6 @@ 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";
}
}
@@ -3045,20 +3066,11 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,0,isShadow,isCombined,form
};
}
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";
- }
- }
+ static_assert(Shape.flavor == $(SLANG_TEXTURE_2D)
+ , "WGSL supports textureLoad for texture_multisampled_2d but not for multisampled of 1D, 3D or Cube.");
+ static_assert(isArray == 0
+ , "WGSL doesn't support array variants of multisampled textures for textureLoad.");
+
__intrinsic_asm "textureLoad($0, $1, $2)$z";
}
}
@@ -3283,18 +3295,21 @@ 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");
+ static_assert(Shape.flavor == $(SLANG_TEXTURE_1D)
+ || Shape.flavor == $(SLANG_TEXTURE_2D)
+ || Shape.flavor == $(SLANG_TEXTURE_3D)
+ , "WGSL doesn't supports textureLoad for Cube texture.");
+ static_assert(isArray == 0 || Shape.flavor == $(SLANG_TEXTURE_2D)
+ , "WGSL supports textureLoad for texture_storage_2d_array but not for array of 1D, 3D or Cube.");
+ static_assert(isShadow == 0 || T is float
+ , "WGSL supports only f32 depth 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";
@@ -3541,21 +3556,12 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,$(access),isShadow, 0,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))$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";
+ static_assert(Shape.flavor == $(SLANG_TEXTURE_2D)
+ , "WGSL supports textureLoad for texture_multisampled_2d but not for multisampled of 1D, 3D or Cube.");
+ static_assert(isArray == 0
+ , "WGSL doesn't support array variants of multisampled textures for textureLoad.");
+
+ __intrinsic_asm "textureLoad($0, $1, $2)$z";
}
}
diff --git a/source/slang/slang-intrinsic-expand.cpp b/source/slang/slang-intrinsic-expand.cpp
index 08f21ff1d..7cde70777 100644
--- a/source/slang/slang-intrinsic-expand.cpp
+++ b/source/slang/slang-intrinsic-expand.cpp
@@ -530,10 +530,12 @@ const char* IntrinsicExpandContext::_emitSpecial(const char* cursor)
auto textureArg = m_args[0].get();
IRType* elementType = nullptr;
+ bool isShadowTexture = false;
if (auto baseTextureType = as<IRTextureTypeBase>(textureArg->getDataType()))
{
elementType = baseTextureType->getElementType();
+ isShadowTexture = baseTextureType->isShadow();
}
else
{
@@ -548,7 +550,14 @@ const char* IntrinsicExpandContext::_emitSpecial(const char* cursor)
if (const auto basicType = as<IRBasicType>(elementType))
{
// A scalar result is expected
- m_writer->emit(".x");
+
+ // If the texture type is a scalar type, the return type from the target intrinsic
+ // probably returns a scalar type already. For GLSL, ".x" swizzling happened to
+ // work fine on a scalar value like "1.x", but it is invalid for WGSL.
+ if (!isShadowTexture)
+ {
+ m_writer->emit(".x");
+ }
}
else if (auto vectorType = as<IRVectorType>(elementType))
{