Author: Kaitlin Peng Date: 2025-04-09T12:12:26-07:00 New Revision: 2ab2276ee079478b7ba9dd42c62b796d3dab1759
URL: https://github.com/llvm/llvm-project/commit/2ab2276ee079478b7ba9dd42c62b796d3dab1759 DIFF: https://github.com/llvm/llvm-project/commit/2ab2276ee079478b7ba9dd42c62b796d3dab1759.diff LOG: [HLSL] Implement the `lit` intrinsic (#134171) Closes #99135. Tasks completed: - Wrote implementation in `hlsl_intrinsics.h`/`hlsl_intrinsic_helpers.h` - Added codegen tests to `clang/test/CodeGenHLSL/builtins/lit.hlsl` Added: clang/test/CodeGenHLSL/builtins/lit.hlsl Modified: clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h clang/lib/Headers/hlsl/hlsl_intrinsics.h Removed: ################################################################################ diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h index b5d88ee1f65cb..3a8a9b6fa2a45 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h @@ -114,6 +114,18 @@ constexpr vector<T, N> smoothstep_vec_impl(vector<T, N> Min, vector<T, N> Max, #endif } +template <typename T> constexpr vector<T, 4> lit_impl(T NDotL, T NDotH, T M) { + bool DiffuseCond = NDotL < 0; + T Diffuse = select<T>(DiffuseCond, 0, NDotL); + vector<T, 4> Result = {1, Diffuse, 0, 1}; + // clang-format off + bool SpecularCond = or(DiffuseCond, (NDotH < 0)); + // clang-format on + T SpecularExp = exp(log(NDotH) * M); + Result[2] = select<T>(SpecularCond, 0, SpecularExp); + return Result; +} + } // namespace __detail } // namespace hlsl diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 8197b5ddf078d..35ff80052cf43 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -292,6 +292,30 @@ const inline float length(__detail::HLSL_FIXED_VECTOR<float, N> X) { return __detail::length_vec_impl(X); } +//===----------------------------------------------------------------------===// +// lit builtins +//===----------------------------------------------------------------------===// + +/// \fn vector<T, 4> lit(T NDotL, T NDotH, T M) +/// \brief Returns a lighting coefficient vector. +/// \param NDotL The dot product of the normalized surface normal and the +/// light vector. +/// \param NDotH The dot product of the half-angle vector and the surface +/// normal. +/// \param M A specular exponent. +/// +/// This function returns a lighting coefficient vector (ambient, diff use, +/// specular, 1). + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +const inline half4 lit(half NDotL, half NDotH, half M) { + return __detail::lit_impl(NDotL, NDotH, M); +} + +const inline float4 lit(float NDotL, float NDotH, float M) { + return __detail::lit_impl(NDotL, NDotH, M); +} + //===----------------------------------------------------------------------===// // D3DCOLORtoUBYTE4 builtin //===----------------------------------------------------------------------===// diff --git a/clang/test/CodeGenHLSL/builtins/lit.hlsl b/clang/test/CodeGenHLSL/builtins/lit.hlsl new file mode 100644 index 0000000000000..44b3e96ef88bf --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/lit.hlsl @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -o - | FileCheck %s + +// CHECK-LABEL: test_lit_half +// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt half %{{.*}}, 0xH0000 +// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, half 0xH0000, half %{{.*}} +// CHECK: %vecinit.i = insertelement <4 x half> <half 0xH3C00, half poison, half poison, half poison>, half %{{.*}}, i32 1 +// CHECK: %vecinit2.i = insertelement <4 x half> %{{.*}}, half 0xH3C00, i32 3 +// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt half %{{.*}}, 0xH0000 +// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i +// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn half @llvm.log.f16(half %{{.*}}) +// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn half %elt.log.i, %{{.*}} +// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16(half %mul.i) +// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, half 0xH0000, half %{{.*}} +// CHECK: %vecins.i = insertelement <4 x half> %{{.*}}, half %hlsl.select7.i, i32 2 +// CHECK: ret <4 x half> %{{.*}} +half4 test_lit_half(half NDotL, half NDotH, half M) { return lit(NDotL, NDotH, M); } + +// CHECK-LABEL: test_lit_float +// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00 +// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}} +// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1 +// CHECK: %vecinit2.i = insertelement <4 x float> %{{.*}}, float 1.000000e+00, i32 3 +// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00 +// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i +// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}}) +// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}} +// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i) +// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}} +// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2 +// CHECK: ret <4 x float> %{{.*}} +float4 test_lit_float(float NDotL, float NDotH, float M) { return lit(NDotL, NDotH, M); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits