From 2b76466c4bc8a47bd4ac69994bafdbb2924272c2 Mon Sep 17 00:00:00 2001 From: Darren Wihandi <65404740+fairywreath@users.noreply.github.com> Date: Thu, 9 Jan 2025 23:49:59 -0500 Subject: Add CalculateLevelOfDetail* overloads for comparison samplers (#6018) * add CalculateLevelOfDetail* intrinsics for comparison samplers * fix dx12 test * fix metallib test * fix merge conflict --------- Co-authored-by: Yong He --- source/slang/hlsl.meta.slang | 50 ++++++++++++++++++++++ .../glsl-calculatelevelofdetail.slang | 13 ++++-- .../texture-calculate-level-of-detail.slang | 27 ++++++++++++ tests/metal/texture-sampler-less.slang | 36 ++++++++++++++++ tests/metal/texture.slang | 48 +++++++++++++++++++++ 5 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 tests/hlsl-intrinsic/texture/texture-calculate-level-of-detail.slang diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 07bf2ffbd..5fb82d875 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -814,6 +814,7 @@ extension _Texture case spirv: return (spirv_asm { + OpCapability ImageQuery; result:$$float2 = OpImageQueryLod $this $location }).x; } @@ -839,6 +840,7 @@ extension _Texture case spirv: return (spirv_asm { + OpCapability ImageQuery; result:$$float2 = OpImageQueryLod $this $location }).y; } @@ -1517,6 +1519,7 @@ extension _Texture __intrinsic_asm "textureQueryLod($p, $2).x"; case spirv: return (spirv_asm { + OpCapability ImageQuery; %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; result:$$float2 = OpImageQueryLod %sampledImage $location; }).x; @@ -1539,6 +1542,53 @@ extension _Texture __intrinsic_asm "textureQueryLod($p, $2).y"; case spirv: return (spirv_asm { + OpCapability ImageQuery; + %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; + result:$$float2 = OpImageQueryLod %sampledImage $location; + }).y; + } + } + + [__readNone] + [ForceInline] + [require(glsl_hlsl_metal_spirv, texture_querylod)] + float CalculateLevelOfDetail(SamplerComparisonState s, TextureCoord location) + { + __requireComputeDerivative(); + __target_switch + { + case hlsl: + __intrinsic_asm ".CalculateLevelOfDetail"; + case metal: + __intrinsic_asm ".calculate_clamped_lod"; + case glsl: + __intrinsic_asm "textureQueryLod($p, $2).x"; + case spirv: + return (spirv_asm { + OpCapability ImageQuery; + %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; + result:$$float2 = OpImageQueryLod %sampledImage $location; + }).x; + } + } + + [__readNone] + [ForceInline] + [require(glsl_hlsl_metal_spirv, texture_querylod)] + float CalculateLevelOfDetailUnclamped(SamplerComparisonState s, TextureCoord location) + { + __requireComputeDerivative(); + __target_switch + { + case hlsl: + __intrinsic_asm ".CalculateLevelOfDetailUnclamped"; + case metal: + __intrinsic_asm ".calculate_unclamped_lod"; + case glsl: + __intrinsic_asm "textureQueryLod($p, $2).y"; + case spirv: + return (spirv_asm { + OpCapability ImageQuery; %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; result:$$float2 = OpImageQueryLod %sampledImage $location; }).y; diff --git a/tests/cross-compile/glsl-calculatelevelofdetail.slang b/tests/cross-compile/glsl-calculatelevelofdetail.slang index eb8c44a8b..bef0110ac 100644 --- a/tests/cross-compile/glsl-calculatelevelofdetail.slang +++ b/tests/cross-compile/glsl-calculatelevelofdetail.slang @@ -1,11 +1,18 @@ //TEST:CROSS_COMPILE(filecheck=CHECK): -profile ps_5_0 -entry main -target glsl -// CHECK: textureQueryLod(sampler2D(t_0,s_0), ({{.*}})).x -// CHECK: textureQueryLod(sampler2D(t_0,s_0), ({{.*}})).y +// CHECK: textureQueryLod(sampler2D( +// CHECK: textureQueryLod(sampler2D( +// CHECK: textureQueryLod(sampler2DShadow( +// CHECK: textureQueryLod(sampler2DShadow( Texture2D t; SamplerState s; +SamplerComparisonState sc; + float main() { - return t.CalculateLevelOfDetail(s, float2(0,0)) + t.CalculateLevelOfDetailUnclamped(s, float2(0,0)); + float result = 0.0; + result += t.CalculateLevelOfDetail(s, float2(0,0)) + t.CalculateLevelOfDetailUnclamped(s, float2(0,0)); + result += t.CalculateLevelOfDetail(sc, float2(0,0)) + t.CalculateLevelOfDetailUnclamped(sc, float2(0,0)); + return result; } diff --git a/tests/hlsl-intrinsic/texture/texture-calculate-level-of-detail.slang b/tests/hlsl-intrinsic/texture/texture-calculate-level-of-detail.slang new file mode 100644 index 000000000..0b623c1f6 --- /dev/null +++ b/tests/hlsl-intrinsic/texture/texture-calculate-level-of-detail.slang @@ -0,0 +1,27 @@ +//TEST:SIMPLE(filecheck=CHECK_HLSL): -stage fragment -entry fragmentMain -target hlsl +//TEST:SIMPLE(filecheck=CHECK_SPIRV): -stage fragment -entry fragmentMain -target spirv + +Texture2D t; +SamplerState s; +SamplerComparisonState sc; + +float fragmentMain() +{ + float result = 0.0; + + // CHECK_SPIRV: OpCapability ImageQuery + + // CHECK_HLSL: CalculateLevelOfDetail + // CHECK_HLSL: CalculateLevelOfDetailUnclamped + // CHECK_SPIRV: OpImageQueryLod + // CHECK_SPIRV: OpImageQueryLod + result += t.CalculateLevelOfDetail(s, float2(0,0)) + t.CalculateLevelOfDetailUnclamped(s, float2(0,0)); + + // CHECK_HLSL: CalculateLevelOfDetail + // CHECK_HLSL: CalculateLevelOfDetailUnclamped + // CHECK_SPIRV: OpImageQueryLod + // CHECK_SPIRV: OpImageQueryLod + result += t.CalculateLevelOfDetail(sc, float2(0,0)) + t.CalculateLevelOfDetailUnclamped(sc, float2(0,0)); + + return result; +} diff --git a/tests/metal/texture-sampler-less.slang b/tests/metal/texture-sampler-less.slang index 78d092e17..a2631e90e 100644 --- a/tests/metal/texture-sampler-less.slang +++ b/tests/metal/texture-sampler-less.slang @@ -236,6 +236,24 @@ bool TEST_texture_float() // METALLIB: call {{.*}}.calculate_clamped_lod_texture_cube_array( && float(0) == tCubeArray.CalculateLevelOfDetail(normalize(float3(u, 1 - u, u))) + // Shadow variant + + // METAL: d2D{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_depth_2d( + && float(0) == d2D.CalculateLevelOfDetail(float2(u, u)) + + // METAL: dCube{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_depth_cube( + && float(0) == dCube.CalculateLevelOfDetail(normalize(float3(u, 1 - u, u))) + + // METAL: d2DArray{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_depth_2d_array( + && float(0) == d2DArray.CalculateLevelOfDetail(float2(u, u)) + + // METAL: dCubeArray{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_depth_cube_array( + && float(0) == dCubeArray.CalculateLevelOfDetail(normalize(float3(u, 1 - u, u))) + // ======================================== // float CalculateLevelOfDetailUnclamped() // ======================================== @@ -260,6 +278,24 @@ bool TEST_texture_float() // METALLIB: call {{.*}}.calculate_unclamped_lod_texture_cube_array( && float(0) >= tCubeArray.CalculateLevelOfDetailUnclamped(normalize(float3(u, 1 - u, u))) + // Shadow variant + + // METAL: d2D{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_depth_2d( + && float(0) >= d2D.CalculateLevelOfDetailUnclamped(float2(u, u)) + + // METAL: dCube{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_depth_cube( + && float(0) >= dCube.CalculateLevelOfDetailUnclamped(normalize(float3(u, 1 - u, u))) + + // METAL: d2DArray{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_depth_2d_array( + && float(0) >= d2DArray.CalculateLevelOfDetailUnclamped(float2(u, u)) + + // METAL: dCubeArray{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_depth_cube_array( + && float(0) >= dCubeArray.CalculateLevelOfDetailUnclamped(normalize(float3(u, 1 - u, u))) + // =========== // T Sample() // =========== diff --git a/tests/metal/texture.slang b/tests/metal/texture.slang index feb0b4738..816c168ff 100644 --- a/tests/metal/texture.slang +++ b/tests/metal/texture.slang @@ -341,6 +341,31 @@ bool TEST_texture( // METALLIB: call {{.*}}.calculate_clamped_lod_texture_cube_array( && float(0) == tCubeArray.CalculateLevelOfDetail(samplerState, normalize(float3(u, 1 - u, u))) + // SamplerComparisonState variant + + // Functional tests that require SM higher than 6.6 (as of writing) cannot run. +#if !defined(EXCLUDE_SM_6_7) + // METAL: t2D{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_texture_2d( + && float(0) == t2D.CalculateLevelOfDetail(shadowSampler, float2(u, u)) + + // METAL: t3D{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_texture_3d( + && float(0) == t3D.CalculateLevelOfDetail(shadowSampler, float3(u, u, u)) + + // METAL: tCube{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_texture_cube( + && float(0) == tCube.CalculateLevelOfDetail(shadowSampler, normalize(float3(u, 1 - u, u))) + + // METAL: t2DArray{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_texture_2d_array( + && float(0) == t2DArray.CalculateLevelOfDetail(shadowSampler, float2(u, u)) + + // METAL: tCubeArray{{.*}}.calculate_clamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_clamped_lod_texture_cube_array( + && float(0) == tCubeArray.CalculateLevelOfDetail(shadowSampler, normalize(float3(u, 1 - u, u))) +#endif + // ======================================== // float CalculateLevelOfDetailUnclamped() // ======================================== @@ -367,6 +392,29 @@ bool TEST_texture( // METALLIB: call {{.*}}.calculate_unclamped_lod_texture_cube_array( && float(0) >= tCubeArray.CalculateLevelOfDetailUnclamped(samplerState, normalize(float3(u, 1 - u, u))) + // SamplerComparisonState variant +#if !defined(EXCLUDE_SM_6_7) + // METAL: t2D{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_texture_2d( + && float(0) >= t2D.CalculateLevelOfDetailUnclamped(shadowSampler, float2(u, u)) + + // METAL: t3D{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_texture_3d( + && float(0) >= t3D.CalculateLevelOfDetailUnclamped(shadowSampler, float3(u, u, u)) + + // METAL: tCube{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_texture_cube( + && float(0) >= tCube.CalculateLevelOfDetailUnclamped(shadowSampler, normalize(float3(u, 1 - u, u))) + + // METAL: t2DArray{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_texture_2d_array( + && float(0) >= t2DArray.CalculateLevelOfDetailUnclamped(shadowSampler, float2(u, u)) + + // METAL: tCubeArray{{.*}}.calculate_unclamped_lod({{.*}} + // METALLIB: call {{.*}}.calculate_unclamped_lod_texture_cube_array( + && float(0) >= tCubeArray.CalculateLevelOfDetailUnclamped(shadowSampler, normalize(float3(u, 1 - u, u))) +#endif + // =========== // T Sample() // =========== -- cgit v1.2.3