Skip to content

Commit 2ab2276

Browse files
authored
[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`
1 parent 2c31403 commit 2ab2276

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,18 @@ constexpr vector<T, N> smoothstep_vec_impl(vector<T, N> Min, vector<T, N> Max,
114114
#endif
115115
}
116116

117+
template <typename T> constexpr vector<T, 4> lit_impl(T NDotL, T NDotH, T M) {
118+
bool DiffuseCond = NDotL < 0;
119+
T Diffuse = select<T>(DiffuseCond, 0, NDotL);
120+
vector<T, 4> Result = {1, Diffuse, 0, 1};
121+
// clang-format off
122+
bool SpecularCond = or(DiffuseCond, (NDotH < 0));
123+
// clang-format on
124+
T SpecularExp = exp(log(NDotH) * M);
125+
Result[2] = select<T>(SpecularCond, 0, SpecularExp);
126+
return Result;
127+
}
128+
117129
} // namespace __detail
118130
} // namespace hlsl
119131

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,30 @@ const inline float length(__detail::HLSL_FIXED_VECTOR<float, N> X) {
292292
return __detail::length_vec_impl(X);
293293
}
294294

295+
//===----------------------------------------------------------------------===//
296+
// lit builtins
297+
//===----------------------------------------------------------------------===//
298+
299+
/// \fn vector<T, 4> lit(T NDotL, T NDotH, T M)
300+
/// \brief Returns a lighting coefficient vector.
301+
/// \param NDotL The dot product of the normalized surface normal and the
302+
/// light vector.
303+
/// \param NDotH The dot product of the half-angle vector and the surface
304+
/// normal.
305+
/// \param M A specular exponent.
306+
///
307+
/// This function returns a lighting coefficient vector (ambient, diffuse,
308+
/// specular, 1).
309+
310+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
311+
const inline half4 lit(half NDotL, half NDotH, half M) {
312+
return __detail::lit_impl(NDotL, NDotH, M);
313+
}
314+
315+
const inline float4 lit(float NDotL, float NDotH, float M) {
316+
return __detail::lit_impl(NDotL, NDotH, M);
317+
}
318+
295319
//===----------------------------------------------------------------------===//
296320
// D3DCOLORtoUBYTE4 builtin
297321
//===----------------------------------------------------------------------===//
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -o - | FileCheck %s
2+
3+
// CHECK-LABEL: test_lit_half
4+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt half %{{.*}}, 0xH0000
5+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, half 0xH0000, half %{{.*}}
6+
// CHECK: %vecinit.i = insertelement <4 x half> <half 0xH3C00, half poison, half poison, half poison>, half %{{.*}}, i32 1
7+
// CHECK: %vecinit2.i = insertelement <4 x half> %{{.*}}, half 0xH3C00, i32 3
8+
// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt half %{{.*}}, 0xH0000
9+
// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
10+
// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn half @llvm.log.f16(half %{{.*}})
11+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn half %elt.log.i, %{{.*}}
12+
// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16(half %mul.i)
13+
// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, half 0xH0000, half %{{.*}}
14+
// CHECK: %vecins.i = insertelement <4 x half> %{{.*}}, half %hlsl.select7.i, i32 2
15+
// CHECK: ret <4 x half> %{{.*}}
16+
half4 test_lit_half(half NDotL, half NDotH, half M) { return lit(NDotL, NDotH, M); }
17+
18+
// CHECK-LABEL: test_lit_float
19+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
20+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
21+
// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
22+
// CHECK: %vecinit2.i = insertelement <4 x float> %{{.*}}, float 1.000000e+00, i32 3
23+
// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
24+
// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
25+
// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
26+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
27+
// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
28+
// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
29+
// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
30+
// CHECK: ret <4 x float> %{{.*}}
31+
float4 test_lit_float(float NDotL, float NDotH, float M) { return lit(NDotL, NDotH, M); }

0 commit comments

Comments
 (0)