From 7d7027853a94c83e9b90b8a11877e91cdaa3e81b Mon Sep 17 00:00:00 2001 From: pdeayton-nv <205388607+pdeayton-nv@users.noreply.github.com> Date: Thu, 1 May 2025 14:51:34 -0700 Subject: Add fwidth_coarse and fwidth_fine functions (#6941) Fixes #6940. Add new Slang fwidth_coarse and fwidth_fine functions, similar to GLSL's fwidthCoarse and fwidthFine. Move the implementation of the GLSL functions from glsl.meta.slang to hlsl.meta.slang. Update the existing spirv/fwidth.slang test with the new functions, and add a new hlsl-intrinsic/fragment-derivative.slang test to test HLSL, SPIR-V, and GLSL targets for the new functions. --- source/slang/glsl.meta.slang | 72 ++----------------------- source/slang/hlsl.meta.slang | 124 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 68 deletions(-) (limited to 'source') diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang index 85c8b174c..0ea7d1c89 100644 --- a/source/slang/glsl.meta.slang +++ b/source/slang/glsl.meta.slang @@ -8898,23 +8898,7 @@ public vector dFdyCoarse(vector p) [require(glsl_hlsl_spirv, fragmentprocessing_derivativecontrol)] public float fwidthFine(float p) { - __requireComputeDerivative(); - __target_switch - { - case hlsl: - { - return abs(ddx_fine(p)) + abs(ddy_fine(p)); - } - case glsl: __intrinsic_asm "fwidthFine($0)"; - case spirv: - { - return spirv_asm - { - OpCapability DerivativeControl; - OpFwidthFine $$float result $p; - }; - } - } + return fwidth_fine(p); } __generic [__NoSideEffect] @@ -8922,23 +8906,7 @@ __generic [require(glsl_hlsl_spirv, fragmentprocessing_derivativecontrol)] public vector fwidthFine(vector p) { - __requireComputeDerivative(); - __target_switch - { - case hlsl: - { - return abs(ddx_fine(p)) + abs(ddy_fine(p)); - } - case glsl: __intrinsic_asm "fwidthFine($0)"; - case spirv: - { - return spirv_asm - { - OpCapability DerivativeControl; - OpFwidthFine $$vector result $p; - }; - } - } + return fwidth_fine(p); } [__NoSideEffect] @@ -8946,23 +8914,7 @@ public vector fwidthFine(vector p) [require(glsl_hlsl_spirv, fragmentprocessing_derivativecontrol)] public float fwidthCoarse(float p) { - __requireComputeDerivative(); - __target_switch - { - case hlsl: - { - return abs(ddx_coarse(p)) + abs(ddy_coarse(p)); - } - case glsl: __intrinsic_asm "fwidthCoarse($0)"; - case spirv: - { - return spirv_asm - { - OpCapability DerivativeControl; - OpFwidthCoarse $$float result $p; - }; - } - } + return fwidth_coarse(p); } __generic [__NoSideEffect] @@ -8970,23 +8922,7 @@ __generic [require(glsl_hlsl_spirv, fragmentprocessing_derivativecontrol)] public vector fwidthCoarse(vector p) { - __requireComputeDerivative(); - __target_switch - { - case hlsl: - { - return abs(ddx_coarse(p)) + abs(ddy_coarse(p)); - } - case glsl: __intrinsic_asm "fwidthCoarse($0)"; - case spirv: - { - return spirv_asm - { - OpCapability DerivativeControl; - OpFwidthCoarse $$vector result $p; - }; - } - } + return fwidth_coarse(p); } [__NoSideEffect] diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 3d83e33c1..0f04006e5 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -9940,6 +9940,130 @@ matrix fwidth(matrix x) } } +/// Texture filter width (coarse). +/// Calculates the sum abs(ddx_coarse(`p`)) + abs(ddy_coarse(`p`)). +/// @param p The value to sum x and y partial derivative magnitudes for. +/// @return The sum of abs(ddx_coarse(`p`)) and abs(ddy_coarse(`p`)). +/// @remarks For SPIR-V, this function maps to `OpFwidthCoarse`. +/// @category derivative +__generic +[__readNone] +[require(glsl_hlsl_spirv, fragmentprocessing_derivativecontrol)] +T fwidth_coarse(T p) +{ + __requireComputeDerivative(); + __target_switch + { + case hlsl: + __intrinsic_asm "abs(ddx_coarse($0)) + abs(ddy_coarse($0))"; + case glsl: + __intrinsic_asm "fwidthCoarse($0)"; + case spirv: + return spirv_asm + { + OpCapability DerivativeControl; + OpFwidthCoarse $$T result $p; + }; + } +} + +__generic +[__readNone] +[require(glsl_hlsl_spirv, fragmentprocessing_derivativecontrol)] +vector fwidth_coarse(vector x) +{ + __requireComputeDerivative(); + __target_switch + { + case hlsl: + __intrinsic_asm "abs(ddx_coarse($0)) + abs(ddy_coarse($0))"; + case glsl: + __intrinsic_asm "fwidthCoarse($0)"; + case spirv: + return spirv_asm + { + OpCapability DerivativeControl; + OpFwidthCoarse $$vector result $x; + }; + } +} + +__generic +[__readNone] +[require(glsl_hlsl_spirv, fragmentprocessing)] +matrix fwidth_coarse(matrix x) +{ + __target_switch + { + case hlsl: + __intrinsic_asm "abs(ddx_coarse($0)) + abs(ddy_coarse($0))"; + default: + MATRIX_MAP_UNARY(T, N, M, fwidth_coarse, x); + } +} + +/// Texture filter width (fine). +/// Calculates the sum abs(ddx_fine(`p`)) + abs(ddy_fine(`p`)). +/// @param p The value to sum x and y partial derivative magnitudes for. +/// @return The sum of abs(ddx_fine(`p`)) and abs(ddy_fine(`p`)). +/// @remarks For SPIR-V, this function maps to `OpFwidthFine`. +/// @category derivative +__generic +[__readNone] +[require(glsl_hlsl_spirv, fragmentprocessing_derivativecontrol)] +T fwidth_fine(T p) +{ + __requireComputeDerivative(); + __target_switch + { + case hlsl: + __intrinsic_asm "abs(ddx_fine($0)) + abs(ddy_fine($0))"; + case glsl: + __intrinsic_asm "fwidthFine($0)"; + case spirv: + return spirv_asm + { + OpCapability DerivativeControl; + OpFwidthFine $$T result $p; + }; + } +} + +__generic +[__readNone] +[require(glsl_hlsl_spirv, fragmentprocessing_derivativecontrol)] +vector fwidth_fine(vector x) +{ + __requireComputeDerivative(); + __target_switch + { + case hlsl: + __intrinsic_asm "abs(ddx_fine($0)) + abs(ddy_fine($0))"; + case glsl: + __intrinsic_asm "fwidthFine($0)"; + case spirv: + return spirv_asm + { + OpCapability DerivativeControl; + OpFwidthFine $$vector result $x; + }; + } +} + +__generic +[__readNone] +[require(glsl_hlsl_spirv, fragmentprocessing)] +matrix fwidth_fine(matrix x) +{ + __target_switch + { + case hlsl: + __intrinsic_asm "abs(ddx_fine($0)) + abs(ddy_fine($0))"; + default: + MATRIX_MAP_UNARY(T, N, M, fwidth_fine, x); + } +} + __intrinsic_op($(kIROp_ResolveVaryingInputRef)) Ref __ResolveVaryingInputRef(__constref T attribute); -- cgit v1.2.3