@@ -20,10 +20,19 @@ namespace hlsl
20
20
{
21
21
22
22
template<typename Integer>
23
- int bitCount (NBL_CONST_REF_ARG (Integer) val)
23
+ inline int bitCount (NBL_CONST_REF_ARG (Integer) val)
24
24
{
25
25
#ifdef __HLSL_VERSION
26
+ if (sizeof (Integer) == 8u)
27
+ {
28
+ uint32_t lowBits = val;
29
+ uint32_t highBits = val >> 32u;
30
+
31
+ return countbits (lowBits) + countbits (highBits);
32
+ }
33
+
26
34
return countbits (val);
35
+
27
36
#else
28
37
return glm::bitCount (val);
29
38
#endif
@@ -49,7 +58,7 @@ T clamp(NBL_CONST_REF_ARG(T) val, NBL_CONST_REF_ARG(T) min, NBL_CONST_REF_ARG(T)
49
58
#endif
50
59
}
51
60
52
- namespace dot_product_impl
61
+ namespace cpp_compat_intrinsics_impl
53
62
{
54
63
template<typename T>
55
64
struct dot_helper
@@ -100,18 +109,19 @@ DEFINE_BUILTIN_VECTOR_SPECIALIZATION(float64_t, BUILTIN_VECTOR_SPECIALIZATION_RE
100
109
template<typename T>
101
110
typename vector_traits<T>::scalar_type dot (NBL_CONST_REF_ARG (T) lhs, NBL_CONST_REF_ARG (T) rhs)
102
111
{
103
- return dot_product_impl ::dot_helper<T>::dot (lhs, rhs);
112
+ return cpp_compat_intrinsics_impl ::dot_helper<T>::dot (lhs, rhs);
104
113
}
105
114
115
+ // TODO: for clearer error messages, use concepts to ensure that input type is a square matrix
106
116
// determinant not defined cause its implemented via hidden friend
107
117
// https://stackoverflow.com/questions/67459950/why-is-a-friend-function-not-treated-as-a-member-of-a-namespace-of-a-class-it-wa
108
- template<typename T, uint16_t N, uint16_t M >
109
- inline T determinant (NBL_CONST_REF_ARG (matrix <T, N, M >) m)
118
+ template<typename T, uint16_t N>
119
+ inline T determinant (NBL_CONST_REF_ARG (matrix <T, N, N >) m)
110
120
{
111
121
#ifdef __HLSL_VERSION
112
-
122
+ spirv:: determinant (m);
113
123
#else
114
- return glm::determinant (reinterpret_cast<typename matrix <T, N, M >::Base const &>(m));
124
+ return glm::determinant (reinterpret_cast<typename matrix <T, N, N >::Base const &>(m));
115
125
#endif
116
126
}
117
127
@@ -169,7 +179,7 @@ int findMSB(NBL_CONST_REF_ARG(Integer) val)
169
179
}
170
180
171
181
// TODO: some of the functions in this header should move to `tgmath`
172
- template<typename T> //requires ::nbl::hlsl::is_floating_point_v<T>
182
+ template<typename T>
173
183
inline T floor (NBL_CONST_REF_ARG (T) val)
174
184
{
175
185
#ifdef __HLSL_VERSION
@@ -191,28 +201,52 @@ inline matrix<T, N, M> inverse(NBL_CONST_REF_ARG(matrix<T, N, M>) m)
191
201
#endif
192
202
}
193
203
204
+ namespace cpp_compat_intrinsics_impl
205
+ {
206
+
207
+ // TODO: concept requiring T to be a float
194
208
template<typename T, typename U>
195
- inline T lerp ( NBL_CONST_REF_ARG (T) x, NBL_CONST_REF_ARG (T) y, NBL_CONST_REF_ARG (U) a)
209
+ struct lerp_helper
196
210
{
211
+ static inline T lerp (NBL_CONST_REF_ARG (T) x, NBL_CONST_REF_ARG (T) y, NBL_CONST_REF_ARG (U) a)
212
+ {
197
213
#ifdef __HLSL_VERSION
198
- return spirv::fMix (x, y, a);
214
+ return spirv::fMix (x, y, a);
199
215
#else
200
- if constexpr (std::is_same_v<U, bool >)
216
+ return glm::mix<T, U>(x, y, a);
217
+ #endif
218
+ }
219
+ };
220
+
221
+ template<typename T>
222
+ struct lerp_helper<T, bool >
223
+ {
224
+ static inline T lerp (NBL_CONST_REF_ARG (T) x, NBL_CONST_REF_ARG (T) y, NBL_CONST_REF_ARG (bool ) a)
225
+ {
201
226
return a ? y : x;
202
- else
227
+ }
228
+ };
229
+
230
+ template<typename T, int N>
231
+ struct lerp_helper<vector <T, N>, vector <bool , N> >
232
+ {
233
+ using output_vec_t = vector <T, N>;
234
+
235
+ static inline output_vec_t lerp (NBL_CONST_REF_ARG (output_vec_t) x, NBL_CONST_REF_ARG (output_vec_t) y, NBL_CONST_REF_ARG (vector <bool , N>) a)
203
236
{
204
- if constexpr (std::is_same_v<scalar_type_t<U>, bool >)
205
- {
206
- T retval;
207
- // whatever has a `scalar_type` specialization should be a pure vector
208
- for (auto i = 0 ; i < sizeof (a) / sizeof (scalar_type_t<U>); i++)
209
- retval[i] = a[i] ? y[i] : x[i];
210
- return retval;
211
- }
212
- else
213
- return glm::mix<T, U>(x, y, a);
237
+ output_vec_t retval;
238
+ for (uint32_t i = 0 ; i < vector_traits<output_vec_t>::Dimension; i++)
239
+ retval[i] = a[i] ? y[i] : x[i];
240
+ return retval;
214
241
}
215
- #endif
242
+ };
243
+
244
+ }
245
+
246
+ template<typename T, typename U>
247
+ inline T lerp (NBL_CONST_REF_ARG (T) x, NBL_CONST_REF_ARG (T) y, NBL_CONST_REF_ARG (U) a)
248
+ {
249
+ return cpp_compat_intrinsics_impl::lerp_helper<T, U>::lerp (x, y, a);
216
250
}
217
251
218
252
// transpose not defined cause its implemented via hidden friend
@@ -232,14 +266,18 @@ inline T min(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b)
232
266
#ifdef __HLSL_VERSION
233
267
min (a, b);
234
268
#else
235
- return std ::min (a, b);
269
+ return glm ::min (a, b);
236
270
#endif
237
271
}
238
272
239
273
template<typename T>
240
274
inline T max (NBL_CONST_REF_ARG (T) a, NBL_CONST_REF_ARG (T) b)
241
275
{
242
- return lerp<T>(a, b, b > a);
276
+ #ifdef __HLSL_VERSION
277
+ max (a, b);
278
+ #else
279
+ return glm::max (a, b);
280
+ #endif
243
281
}
244
282
245
283
template<typename FloatingPoint>
@@ -289,6 +327,7 @@ DEFINE_EXP2_SPECIALIZATION(uint64_t)
289
327
template<typename FloatingPoint>
290
328
inline FloatingPoint rsqrt (FloatingPoint x)
291
329
{
330
+ // TODO: https://stackoverflow.com/a/62239778
292
331
#ifdef __HLSL_VERSION
293
332
return spirv::inverseSqrt (x);
294
333
#else
0 commit comments