diff options
| author | Jay Kwak <82421531+jkwak-work@users.noreply.github.com> | 2024-09-25 10:04:22 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-25 10:04:22 -0700 |
| commit | 03765a691531d69a30734beb0433d8d4cac45024 (patch) | |
| tree | 30b0d802f1e24bae1d15fec8d498f6207919a744 /source | |
| parent | 88623edb8120333d48a9ebdec73063f94a10282e (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.slang | 116 | ||||
| -rw-r--r-- | source/slang/slang-intrinsic-expand.cpp | 11 |
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)) { |
