@@ -25,8 +25,8 @@ inline int bitCount(NBL_CONST_REF_ARG(Integer) val)
25
25
#ifdef __HLSL_VERSION
26
26
if (sizeof (Integer) == 8u)
27
27
{
28
- uint32_t lowBits = val;
29
- uint32_t highBits = val >> 32u;
28
+ uint32_t lowBits = uint32_t ( val) ;
29
+ uint32_t highBits = uint32_t ( uint64_t ( val) >> 32u) ;
30
30
31
31
return countbits (lowBits) + countbits (highBits);
32
32
}
@@ -125,57 +125,198 @@ inline T determinant(NBL_CONST_REF_ARG(matrix<T, N, N>) m)
125
125
#endif
126
126
}
127
127
128
- template<typename Integer>
129
- int findLSB (NBL_CONST_REF_ARG (Integer) val)
128
+ namespace cpp_compat_intrinsics_impl
130
129
{
130
+
131
131
#ifdef __HLSL_VERSION
132
- return spirv::findILsb (val);
132
+ template<typename Integer>
133
+ struct find_msb_helper;
133
134
#else
134
- if (is_signed_v<Integer>)
135
+ // legacy code wouldn't work without it
136
+ template<typename Integer>
137
+ struct find_msb_helper
138
+ {
139
+ static int findMSB (NBL_CONST_REF_ARG (Integer) val)
135
140
{
136
- // GLM accepts only integer types, so idea is to cast input to integer type
137
- using as_int = typename integer_of_size<sizeof (Integer)>::type;
138
- const as_int valAsInt = reinterpret_cast<const as_int&>(val);
139
- return glm::findLSB (valAsInt);
141
+ if (is_signed_v<Integer>)
142
+ {
143
+ // GLM accepts only integer types, so idea is to cast input to integer type
144
+ using as_int = typename integer_of_size<sizeof (Integer)>::type;
145
+ const as_int valAsInt = reinterpret_cast<const as_int&>(val);
146
+ return glm::findMSB (valAsInt);
147
+ }
148
+ else
149
+ {
150
+ // GLM accepts only integer types, so idea is to cast input to integer type
151
+ using as_uint = typename unsigned_integer_of_size<sizeof (Integer)>::type;
152
+ const as_uint valAsUnsignedInt = reinterpret_cast<const as_uint&>(val);
153
+ return glm::findMSB (valAsUnsignedInt);
154
+ }
140
155
}
141
- else
156
+ };
157
+ #endif
158
+
159
+ template<>
160
+ struct find_msb_helper<uint32_t>
161
+ {
162
+ static int32_t findMSB (NBL_CONST_REF_ARG (uint32_t) val)
142
163
{
143
- // GLM accepts only integer types, so idea is to cast input to integer type
144
- using as_uint = typename unsigned_integer_of_size<sizeof (Integer)>::type;
145
- const as_uint valAsUnsignedInt = reinterpret_cast<const as_uint&>(val);
146
- return glm::findLSB (valAsUnsignedInt);
164
+ #ifdef __HLSL_VERSION
165
+ return spirv::findUMsb (val);
166
+ #else
167
+ return glm::findMSB (val);
168
+ #endif
147
169
}
170
+ };
171
+
172
+ template<>
173
+ struct find_msb_helper<int32_t>
174
+ {
175
+ static int32_t findMSB (NBL_CONST_REF_ARG (int32_t) val)
176
+ {
177
+ #ifdef __HLSL_VERSION
178
+ return spirv::findSMsb (val);
179
+ #else
180
+ return glm::findMSB (val);
148
181
#endif
149
- }
182
+ }
183
+ };
150
184
151
- template<typename Integer >
152
- int findMSB ( NBL_CONST_REF_ARG (Integer) val)
185
+ template<int N >
186
+ struct find_msb_helper< vector <uint32_t, N> >
153
187
{
188
+ static vector <int32_t, N> findMSB (NBL_CONST_REF_ARG (vector <uint32_t, N>) val)
189
+ {
154
190
#ifdef __HLSL_VERSION
155
- if (is_signed_v<Integer>)
191
+ return spirv::findUMsb (val);
192
+ #else
193
+ return glm::findMSB (val);
194
+ #endif
195
+ }
196
+ };
197
+
198
+ template<int N>
199
+ struct find_msb_helper<vector <int32_t, N> >
200
+ {
201
+ static vector <int32_t, N> findMSB (NBL_CONST_REF_ARG (vector <int32_t, N>) val)
156
202
{
203
+ #ifdef __HLSL_VERSION
157
204
return spirv::findSMsb (val);
205
+ #else
206
+ return glm::findMSB (val);
207
+ #endif
158
208
}
159
- else
209
+ };
210
+
211
+ #ifdef __HLSL_VERSION
212
+ template<typename Integer>
213
+ struct find_lsb_helper;
214
+ #else
215
+ // legacy code wouldn't work without it
216
+ template<typename Integer>
217
+ struct find_lsb_helper
218
+ {
219
+ static int32_t findLSB (NBL_CONST_REF_ARG (Integer) val)
160
220
{
161
- return spirv::findUMsb (val);
221
+ #ifdef __HLSL_VERSION
222
+ return spirv::findILsb (val);
223
+ #else
224
+ if (is_signed_v<Integer>)
225
+ {
226
+ // GLM accepts only integer types, so idea is to cast input to integer type
227
+ using as_int = typename integer_of_size<sizeof (Integer)>::type;
228
+ const as_int valAsInt = reinterpret_cast<const as_int&>(val);
229
+ return glm::findLSB (valAsInt);
230
+ }
231
+ else
232
+ {
233
+ // GLM accepts only integer types, so idea is to cast input to integer type
234
+ using as_uint = typename unsigned_integer_of_size<sizeof (Integer)>::type;
235
+ const as_uint valAsUnsignedInt = reinterpret_cast<const as_uint&>(val);
236
+ return glm::findLSB (valAsUnsignedInt);
237
+ }
238
+ #endif
162
239
}
240
+ };
241
+ #endif
242
+
243
+ template<>
244
+ struct find_lsb_helper<int32_t>
245
+ {
246
+ static int32_t findLSB (NBL_CONST_REF_ARG (int32_t) val)
247
+ {
248
+ #ifdef __HLSL_VERSION
249
+ return spirv::findILsb (val);
163
250
#else
164
- if (is_signed_v<Integer>)
251
+ return glm::findLSB (val);
252
+ #endif
253
+ }
254
+ };
255
+
256
+ template<>
257
+ struct find_lsb_helper<uint32_t>
258
+ {
259
+ static int32_t findLSB (NBL_CONST_REF_ARG (uint32_t) val)
165
260
{
166
- // GLM accepts only integer types, so idea is to cast input to integer type
167
- using as_int = typename integer_of_size<sizeof (Integer)>::type;
168
- const as_int valAsInt = reinterpret_cast<const as_int&>(val);
169
- return glm::findMSB (valAsInt);
261
+ #ifdef __HLSL_VERSION
262
+ return spirv::findILsb (val);
263
+ #else
264
+ return glm::findLSB (val);
265
+ #endif
170
266
}
171
- else
267
+ };
268
+
269
+ template<int N>
270
+ struct find_lsb_helper<vector <int32_t, N> >
271
+ {
272
+ static vector <int32_t, N> findLSB (NBL_CONST_REF_ARG (vector <int32_t, N>) val)
172
273
{
173
- // GLM accepts only integer types, so idea is to cast input to integer type
174
- using as_uint = typename unsigned_integer_of_size<sizeof (Integer)>::type;
175
- const as_uint valAsUnsignedInt = reinterpret_cast<const as_uint&>(val);
176
- return glm::findMSB (valAsUnsignedInt);
274
+ #ifdef __HLSL_VERSION
275
+ return spirv::findILsb (val);
276
+ #else
277
+ return glm::findLSB (val);
278
+ #endif
177
279
}
280
+ };
281
+
282
+ template<int N>
283
+ struct find_lsb_helper<vector <uint32_t, N> >
284
+ {
285
+ static vector <int32_t, N> findLSB (NBL_CONST_REF_ARG (vector <uint32_t, N>) val)
286
+ {
287
+ #ifdef __HLSL_VERSION
288
+ return spirv::findILsb (val);
289
+ #else
290
+ return glm::findLSB (val);
178
291
#endif
292
+ }
293
+ };
294
+
295
+ template<typename Integer>
296
+ struct find_msb_return_type
297
+ {
298
+ using type = int32_t;
299
+ };
300
+ template<typename Integer, int N>
301
+ struct find_msb_return_type<vector <Integer, N> >
302
+ {
303
+ using type = vector <int32_t, N>;
304
+ };
305
+ template<typename Integer>
306
+ using find_lsb_return_type = find_msb_return_type<Integer>;
307
+
308
+ }
309
+
310
+ template<typename Integer>
311
+ inline typename cpp_compat_intrinsics_impl::find_lsb_return_type<Integer>::type findLSB (NBL_CONST_REF_ARG (Integer) val)
312
+ {
313
+ return cpp_compat_intrinsics_impl::find_lsb_helper<Integer>::findLSB (val);
314
+ }
315
+
316
+ template<typename Integer>
317
+ inline typename cpp_compat_intrinsics_impl::find_msb_return_type<Integer>::type findMSB (NBL_CONST_REF_ARG (Integer) val)
318
+ {
319
+ return cpp_compat_intrinsics_impl::find_msb_helper<Integer>::findMSB (val);
179
320
}
180
321
181
322
// TODO: some of the functions in this header should move to `tgmath`
@@ -204,19 +345,48 @@ inline matrix<T, N, N> inverse(NBL_CONST_REF_ARG(matrix<T, N, N>) m)
204
345
205
346
namespace cpp_compat_intrinsics_impl
206
347
{
207
- // TODO: concept requiring T to be a float when U is not bool
208
348
template<typename T, typename U>
209
- struct lerp_helper
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
- {
349
+ struct lerp_helper;
350
+
213
351
#ifdef __HLSL_VERSION
214
- return spirv::fMix (x, y, a);
352
+ #define MIX_FUNCTION spirv::fMix
215
353
#else
216
- return glm::mix<T, U>(x, y, a);
354
+ #define MIX_FUNCTION glm::mix
217
355
#endif
218
- }
219
- };
356
+
357
+ #define DEFINE_LERP_HELPER_COMMON_SPECIALIZATION (TYPE)\
358
+ template<>\
359
+ struct lerp_helper<TYPE, TYPE>\
360
+ {\
361
+ static inline TYPE lerp (NBL_CONST_REF_ARG (TYPE) x, NBL_CONST_REF_ARG (TYPE) y, NBL_CONST_REF_ARG (TYPE) a)\
362
+ {\
363
+ return MIX_FUNCTION (x, y, a);\
364
+ }\
365
+ };\
366
+ \
367
+ template<int N>\
368
+ struct lerp_helper<vector <TYPE, N>, vector <TYPE, N> >\
369
+ {\
370
+ static inline vector <TYPE, N> lerp (NBL_CONST_REF_ARG (vector <TYPE, N>) x, NBL_CONST_REF_ARG (vector <TYPE, N>) y, NBL_CONST_REF_ARG (vector <TYPE, N>) a)\
371
+ {\
372
+ return MIX_FUNCTION (x, y, a);\
373
+ }\
374
+ };\
375
+ \
376
+ template<int N>\
377
+ struct lerp_helper<vector <TYPE, N>, TYPE>\
378
+ {\
379
+ static inline vector <TYPE, N> lerp (NBL_CONST_REF_ARG (vector <TYPE, N>) x, NBL_CONST_REF_ARG (vector <TYPE, N>) y, NBL_CONST_REF_ARG (TYPE) a)\
380
+ {\
381
+ return MIX_FUNCTION (x, y, a);\
382
+ }\
383
+ };\
384
+
385
+ DEFINE_LERP_HELPER_COMMON_SPECIALIZATION (float32_t)
386
+ DEFINE_LERP_HELPER_COMMON_SPECIALIZATION (float64_t)
387
+
388
+ #undef DEFINE_LERP_HELPER_COMMON_SPECIALIZATION
389
+ #undef MIX_FUNCTION
220
390
221
391
template<typename T>
222
392
struct lerp_helper<T, bool >
0 commit comments