From 2249d6ffb19e4db8580c76ccb04ab4ca3ddc8394 Mon Sep 17 00:00:00 2001 From: Darren Wihandi <65404740+fairywreath@users.noreply.github.com> Date: Wed, 8 Jan 2025 22:50:57 -0500 Subject: Add SampleCmpLevel intrinsics (#6004) * add SampleCmpLevel intrinsics * update tests * fix typo * fix broken glsl test * refactor SampleCmpLevelZero * fix metallib test * fix broken test on dx12 --------- Co-authored-by: Yong He --- source/slang/hlsl.meta.slang | 310 ++++++++++++++++++++++++++++--------------- 1 file changed, 202 insertions(+), 108 deletions(-) (limited to 'source') diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index d5b59427f..a27cafbd4 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -649,41 +649,41 @@ float __glsl_texture_offset_1d_shadow(TSampler s, TCo __glsl_extension(GL_EXT_texture_shadow_lod) [require(glsl, texture_sm_4_1)] -float __glsl_texture_level_zero(TSampler s, TCoord value) +float __glsl_texture_level(TSampler s, TCoord value, float level) { __target_switch { - case glsl: __intrinsic_asm "textureLod($0, $1, 0)"; + case glsl: __intrinsic_asm "textureLod($0, $1, $2)"; } } __glsl_extension(GL_EXT_texture_shadow_lod) [require(glsl, texture_shadowlod)] -float __glsl_texture_level_zero_1d_shadow(TSampler s, TCoord value) +float __glsl_texture_level_1d_shadow(TSampler s, TCoord value, float level) { __target_switch { - case glsl: __intrinsic_asm "textureLod($0, $1, 0)"; + case glsl: __intrinsic_asm "textureLod($0, $1, $2)"; } } __glsl_extension(GL_EXT_texture_shadow_lod) [require(glsl, texture_shadowlod)] -float __glsl_texture_offset_level_zero(TSampler s, TCoord value, constexpr TOffset offset) +float __glsl_texture_level_offset(TSampler s, TCoord value, float level, constexpr TOffset offset) { __target_switch { - case glsl: __intrinsic_asm "textureLodOffset($0, $1, 0, $2)"; + case glsl: __intrinsic_asm "textureLodOffset($0, $1, $2, $3)"; } } __glsl_extension(GL_EXT_texture_shadow_lod) [require(glsl, texture_shadowlod)] -float __glsl_texture_offset_level_zero_1d_shadow(TSampler s, TCoord value, constexpr TOffset offset) +float __glsl_texture_level_offset_1d_shadow(TSampler s, TCoord value, float level, constexpr TOffset offset) { __target_switch { - case glsl: __intrinsic_asm "textureLodOffset($0, $1, 0, $2)"; + case glsl: __intrinsic_asm "textureLodOffset($0, $1, $2, $3)"; } } @@ -736,41 +736,41 @@ float __glsl_texture_offset_1d_shadow(TTexture t,Samp } [require(glsl, texture_sm_4_1)] -float __glsl_texture_level_zero(TTexture t,SamplerComparisonState s, TCoord value) +float __glsl_texture_level(TTexture t,SamplerComparisonState s, TCoord value, float level) { __target_switch { - case glsl: __intrinsic_asm "textureLod($p, $2, 0)"; + case glsl: __intrinsic_asm "textureLod($p, $2, $3)"; } } __glsl_extension(GL_EXT_texture_shadow_lod) [require(glsl, texture_shadowlod)] -float __glsl_texture_level_zero_1d_shadow(TTexture t,SamplerComparisonState s, TCoord value) +float __glsl_texture_level_1d_shadow(TTexture t,SamplerComparisonState s, TCoord value, float level) { __target_switch { - case glsl: __intrinsic_asm "textureLod($p, $2, 0)"; + case glsl: __intrinsic_asm "textureLod($p, $2, $3)"; } } __glsl_extension(GL_EXT_texture_shadow_lod) [require(glsl, texture_shadowlod)] -float __glsl_texture_offset_level_zero(TTexture t,SamplerComparisonState s, TCoord value, constexpr TOffset offset) +float __glsl_texture_level_offset(TTexture t,SamplerComparisonState s, TCoord value, float level, constexpr TOffset offset) { __target_switch { - case glsl: __intrinsic_asm "textureLodOffset($p, $2, 0, $3)"; + case glsl: __intrinsic_asm "textureLodOffset($p, $2, $3, $4)"; } } __glsl_extension(GL_EXT_texture_shadow_lod) [require(glsl, texture_shadowlod)] -float __glsl_texture_offset_level_zero_1d_shadow(TTexture t,SamplerComparisonState s, TCoord value, constexpr TOffset offset) +float __glsl_texture_level_offset_1d_shadow(TTexture t,SamplerComparisonState s, TCoord value, float level, constexpr TOffset offset) { __target_switch { - case glsl: __intrinsic_asm "textureLodOffset($p, $2, 0, $3)"; + case glsl: __intrinsic_asm "textureLodOffset($p, $2, $3, $4)"; } } @@ -854,7 +854,7 @@ extension _Texture /// This parameter is currently only used when targeting HLSL. /// For other targets, the result status is always 0. ///@return The sampled texture value. - ///@see `SampleBias`, `SampleLevel`, `SampleGrad`, `SampleCmp`, `SampleCmpLevelZero`. + ///@see `SampleBias`, `SampleLevel`, `SampleGrad`, `SampleCmp`, `SampleCmpLevelZero`, `SampleCmpLevel`. ///@remarks /// The `Sample` function is defined for all read-only texture types, including /// `Texture1D`, `Texture2D`, `Texture3D`, `TextureCube`, @@ -1118,30 +1118,15 @@ extension _Texture { __target_switch { - case glsl: - if (Shape.dimensions == 1 && isArray == 0) - { - return __glsl_texture_level_zero_1d_shadow(this, __makeVector(__makeVector(location, 0.0), compareValue)); - } - else - { - return __glsl_texture_level_zero(this, __makeVector(location, compareValue)); - } case hlsl: static_assert(T is float || T is vector || T is vector || T is vector || T is half || T is vector || T is vector || T is vector , "HLSL supports only float and half type textures"); return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue); - case metal: - return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue); - case spirv: - const float zeroFloat = 0.0f; - return spirv_asm - { - result:$$float = OpImageSampleDrefExplicitLod $this $location $compareValue Lod $zeroFloat; - }; case wgsl: return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue); + default: + return SampleCmpLevel(location, compareValue, 0.0); } } @@ -1200,48 +1185,110 @@ extension _Texture [ForceInline] [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmpLevelZero(vector location, float compareValue, constexpr vector offset) + { + __target_switch + { + case hlsl: + static_assert(T is float || T is vector || T is vector || T is vector + || T is half || T is vector || T is vector || T is vector + , "HLSL supports only float and half type textures"); + return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset); + case wgsl: + return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset); + default: + return SampleCmpLevel(location, compareValue, 0.0, offset); + } + } + + [__readNone] + [ForceInline] + [require(hlsl, sm_5_0)] + float SampleCmpLevelZero(vector location, float compareValue, constexpr vector offset, out uint status) + { + __target_switch + { + case hlsl: + static_assert(T is float || T is vector || T is vector || T is vector + || T is half || T is vector || T is vector || T is vector + , "HLSL supports only float and half type textures"); + return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset, status); + } + } + + [__readNone] + [ForceInline] + [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + float SampleCmpLevel(vector location, float compareValue, float level) { __target_switch { case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_offset_level_zero_1d_shadow(this, __makeVector(__makeVector(location,0.0), compareValue), offset); + return __glsl_texture_level_1d_shadow(this, __makeVector(__makeVector(location, 0.0), compareValue), level); } else { - return __glsl_texture_offset_level_zero(this, __makeVector(location, compareValue), offset); + return __glsl_texture_level(this, __makeVector(location, compareValue), level); } case hlsl: static_assert(T is float || T is vector || T is vector || T is vector || T is half || T is vector || T is vector || T is vector , "HLSL supports only float and half type textures"); - return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset); + return __getTexture().SampleCmpLevel(__getComparisonSampler(), location, compareValue, level); case metal: - return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset); + return __getTexture().SampleCmpLevel(__getComparisonSampler(), location, compareValue, level); case spirv: - const float zeroFloat = 0.0f; return spirv_asm { - result:$$float = OpImageSampleDrefExplicitLod $this $location $compareValue Lod|ConstOffset $zeroFloat $offset; + result:$$float = OpImageSampleDrefExplicitLod $this $location $compareValue Lod $level; }; - case wgsl: - return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset); } } [__readNone] [ForceInline] - [require(hlsl, sm_5_0)] - float SampleCmpLevelZero(vector location, float compareValue, constexpr vector offset, out uint status) + [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + float SampleCmpLevel(vector location, float compareValue, float level, constexpr vector offset) { __target_switch { + case glsl: + if (Shape.dimensions == 1 && isArray == 0) + { + return __glsl_texture_level_offset_1d_shadow(this, __makeVector(__makeVector(location,0.0), compareValue), level, offset); + } + else + { + return __glsl_texture_level_offset(this, __makeVector(location, compareValue), level, offset); + } case hlsl: static_assert(T is float || T is vector || T is vector || T is vector || T is half || T is vector || T is vector || T is vector , "HLSL supports only float and half type textures"); - return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset, status); + return __getTexture().SampleCmpLevel(__getComparisonSampler(), location, compareValue, level, offset); + case metal: + return __getTexture().SampleCmpLevel(__getComparisonSampler(), location, compareValue, level, offset); + case spirv: + return spirv_asm + { + result:$$float = OpImageSampleDrefExplicitLod $this $location $compareValue Lod|ConstOffset $level $offset; + }; + } + } + + [__readNone] + [ForceInline] + [require(hlsl, texture_shadowlod)] + float SampleCmpLevel(vector location, float compareValue, float level, constexpr vector offset, out uint status) + { + __target_switch + { + case hlsl: + static_assert(T is float || T is vector || T is vector || T is vector + || T is half || T is vector || T is vector || T is vector + , "HLSL supports only float and half type textures"); + return __getTexture().SampleCmpLevel(__getComparisonSampler(), location, compareValue, level, offset, status); } } @@ -1956,48 +2003,11 @@ extension _Texture { __target_switch { - case glsl: - if (Shape.dimensions == 1 && isArray == 0) - { - return __glsl_texture_level_zero_1d_shadow(this, s, __makeVector(__makeVector(location, 0.0), compareValue)); - } - else - { - return __glsl_texture_level_zero(this, s, __makeVector(location,compareValue)); - } case hlsl: static_assert(T is float || T is vector || T is vector || T is vector || T is half || T is vector || T is vector || T is vector , "HLSL supports only float and half type textures"); __intrinsic_asm ".SampleCmpLevelZero"; - case metal: - if (isArray == 1) - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, level(0))"; - case $(SLANG_TEXTURE_CUBE): - __intrinsic_asm "$0.sample_compare($1, ($2).xyz, uint(($2).w), $3, level(0))"; - } - } - else - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - case $(SLANG_TEXTURE_CUBE): - __intrinsic_asm "$0.sample_compare($1, $2, $3, level(0))"; - } - } - __intrinsic_asm ""; - case spirv: - const float zeroFloat = 0.0f; - return spirv_asm - { - %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; - result:$$float = OpImageSampleDrefExplicitLod %sampledImage $location $compareValue Lod $zeroFloat; - }; case wgsl: static_assert(T is float || T is vector || T is vector || T is vector , "WGSL supports only f32 type textures"); @@ -2014,6 +2024,8 @@ extension _Texture } } __intrinsic_asm "textureSampleCompareLevel($0, $1, $2, $3)"; + default: + return SampleCmpLevel(s, location, compareValue, 0.0); } } @@ -2102,23 +2114,122 @@ extension _Texture [ForceInline] [require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)] float SampleCmpLevelZero(SamplerComparisonState s, vector location, float compareValue, constexpr vector offset) + { + __target_switch + { + case hlsl: + static_assert(T is float || T is vector || T is vector || T is vector + || T is half || T is vector || T is vector || T is vector + , "HLSL supports only float and half type textures"); + __intrinsic_asm ".SampleCmpLevelZero"; + case wgsl: + static_assert(T is float || T is vector || T is vector || T is vector + , "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)"; + default: + return SampleCmpLevel(s, location, compareValue, 0.0, offset); + } + } + + [__readNone] + [ForceInline] + [require(hlsl, sm_5_0)] + float SampleCmpLevelZero(SamplerComparisonState s, vector location, float compareValue, constexpr vector offset, out uint status) + { + __target_switch + { + case hlsl: + static_assert(T is float || T is vector || T is vector || T is vector + || T is half || T is vector || T is vector || T is vector + , "HLSL supports only float and half type textures"); + __intrinsic_asm ".SampleCmpLevelZero"; + } + } + + [__readNone] + [ForceInline] + [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + float SampleCmpLevel(SamplerComparisonState s, vector location, float compareValue, float level) { __target_switch { case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_offset_level_zero_1d_shadow(this, s, __makeVector(__makeVector(location,0.0),compareValue), offset); + return __glsl_texture_level_1d_shadow(this, s, __makeVector(__makeVector(location, 0.0), compareValue), level); } else { - return __glsl_texture_offset_level_zero(this, s, __makeVector(location,compareValue), offset); + return __glsl_texture_level(this, s, __makeVector(location,compareValue), level); } case hlsl: static_assert(T is float || T is vector || T is vector || T is vector || T is half || T is vector || T is vector || T is vector , "HLSL supports only float and half type textures"); - __intrinsic_asm ".SampleCmpLevelZero"; + __intrinsic_asm ".SampleCmpLevel"; + case metal: + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, level($4))"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "$0.sample_compare($1, ($2).xyz, uint(($2).w), $3, level($4))"; + } + } + else + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "$0.sample_compare($1, $2, $3, level($4))"; + } + } + __intrinsic_asm ""; + case spirv: + return spirv_asm + { + %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; + result:$$float = OpImageSampleDrefExplicitLod %sampledImage $location $compareValue Lod $level; + }; + } + } + + [__readNone] + [ForceInline] + [require(glsl_hlsl_metal_spirv, texture_shadowlod)] + float SampleCmpLevel(SamplerComparisonState s, vector location, float compareValue, float level, constexpr vector offset) + { + __target_switch + { + case glsl: + if (Shape.dimensions == 1 && isArray == 0) + { + return __glsl_texture_level_offset_1d_shadow(this, s, __makeVector(__makeVector(location,0.0),compareValue), level, offset); + } + else + { + return __glsl_texture_level_offset(this, s, __makeVector(location,compareValue), level, offset); + } + case hlsl: + static_assert(T is float || T is vector || T is vector || T is vector + || T is half || T is vector || T is vector || T is vector + , "HLSL supports only float and half type textures"); + __intrinsic_asm ".SampleCmpLevel"; case metal: if (isShadow == 1) { @@ -2128,47 +2239,30 @@ extension _Texture if (isArray == 1) { // T sample_compare(sampler s, float2 coord, uint array, float compare_value, lod_options options, int2 offset = int2(0)) const - __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, level(0), $4)"; + __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, level($4), $5)"; } else { // T sample_compare(sampler s, float2 coord, float compare_value, lod_options options, int2 offset = int2(0)) const - __intrinsic_asm "$0.sample_compare($1, $2, $3, level(0), $4)"; + __intrinsic_asm "$0.sample_compare($1, $2, $3, level($4), $5)"; } break; } } __intrinsic_asm ""; case spirv: - const float zeroFloat = 0.0f; return spirv_asm { %sampledImage : __sampledImageType(this) = OpSampledImage $this $s; - result:$$float = OpImageSampleDrefExplicitLod %sampledImage $location $compareValue Lod|ConstOffset $zeroFloat $offset; + result:$$float = OpImageSampleDrefExplicitLod %sampledImage $location $compareValue Lod|ConstOffset $level $offset; }; - case wgsl: - static_assert(T is float || T is vector || T is vector || T is vector - , "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(hlsl, sm_5_0)] - float SampleCmpLevelZero(SamplerComparisonState s, vector location, float compareValue, constexpr vector offset, out uint status) + [require(hlsl, texture_shadowlod)] + float SampleCmpLevel(SamplerComparisonState s, vector location, float compareValue, float level, constexpr vector offset, out uint status) { __target_switch { @@ -2176,7 +2270,7 @@ extension _Texture static_assert(T is float || T is vector || T is vector || T is vector || T is half || T is vector || T is vector || T is vector , "HLSL supports only float and half type textures"); - __intrinsic_asm ".SampleCmpLevelZero"; + __intrinsic_asm ".SampleCmpLevel"; } } -- cgit v1.2.3