@@ -111,10 +111,14 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(find_lsb_helper, findILsb, FIND_MSB_LSB_RETU
111
111
#undef FIND_MSB_LSB_RETURN_TYPE
112
112
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (bitReverse_helper, bitReverse, T)
113
113
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (transpose_helper, transpose, T)
114
- AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (length_helper, length, T )
114
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (length_helper, length, typename vector_traits<T>::scalar_type )
115
115
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (normalize_helper, normalize, T)
116
116
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (rsqrt_helper, inverseSqrt, T)
117
117
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (frac_helper, fract, T)
118
+ #define BITCOUNT_HELPER_RETRUN_TYPE conditional_t<is_vector_v<T>, vector <int32_t, vector_traits<T>::Dimension>, int32_t>
119
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (bitCount_helper, bitCount, BITCOUNT_HELPER_RETRUN_TYPE)
120
+ #undef BITCOUNT_HELPER_RETRUN_TYPE
121
+
118
122
119
123
template<typename UInt64> NBL_PARTIAL_REQ_TOP (is_same_v<UInt64, uint64_t>)
120
124
struct find_msb_helper<UInt64 NBL_PARTIAL_REQ_BOT (is_same_v<UInt64, uint64_t>) >
@@ -161,8 +165,8 @@ struct find_lsb_helper<UInt64 NBL_PARTIAL_REQ_BOT(is_same_v<UInt64, uint64_t>) >
161
165
};
162
166
163
167
#define AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (HELPER_NAME, SPIRV_FUNCTION_NAME, RETURN_TYPE)\
164
- template<typename T> NBL_PARTIAL_REQ_TOP (always_true<decltype (spirv::SPIRV_FUNCTION_NAME<T>(experimental::declval<T>()))>)\
165
- struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT (always_true<decltype (spirv::SPIRV_FUNCTION_NAME<T>(experimental::declval<T>()))>) >\
168
+ template<typename T> NBL_PARTIAL_REQ_TOP (always_true<decltype (spirv::SPIRV_FUNCTION_NAME<T>(experimental::declval<T>(), experimental::declval<T>() ))>)\
169
+ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT (always_true<decltype (spirv::SPIRV_FUNCTION_NAME<T>(experimental::declval<T>(), experimental::declval<T>() ))>) >\
166
170
{\
167
171
using return_t = RETURN_TYPE;\
168
172
static inline return_t __call (const T a, const T b)\
@@ -174,9 +178,10 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::SPIRV_FUNCT
174
178
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (max_helper, fMax, T)
175
179
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (max_helper, uMax, T)
176
180
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (max_helper, sMax, T)
177
- AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, fMax, T)
178
- AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, uMax, T)
179
- AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, sMax, T)
181
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, fMin, T)
182
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, uMin, T)
183
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, sMin, T)
184
+ #undef AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC
180
185
181
186
#else // C++ only specializations
182
187
@@ -311,6 +316,20 @@ struct frac_helper<T>
311
316
}
312
317
};
313
318
319
+ template<typename Integer>
320
+ NBL_PARTIAL_REQ_TOP (concepts::IntegralScalar<Integer>)
321
+ struct bitCount_helper<Integer NBL_PARTIAL_REQ_BOT (concepts::IntegralScalar<Integer>) >
322
+ {
323
+ using return_t = int32_t;
324
+ static return_t __call (NBL_CONST_REF_ARG (Integer) val)
325
+ {
326
+ using UnsignedInteger = typename hlsl::unsigned_integer_of_size_t<sizeof (Integer)>;
327
+ constexpr int32_t BitCnt = sizeof (Integer) * 8u;
328
+ std::bitset<BitCnt> bitset (static_cast<UnsignedInteger>(val));
329
+ return bitset.count ();
330
+ }
331
+ };
332
+
314
333
#endif // C++ only specializations
315
334
316
335
// C++ and HLSL specializations
@@ -372,104 +391,86 @@ struct cross_helper<FloatingPointLikeVectorial NBL_PARTIAL_REQ_BOT(concepts::Flo
372
391
}
373
392
};
374
393
375
- template<typename Vector>
376
- NBL_PARTIAL_REQ_TOP (is_vector_v<Vector>)
377
- struct clamp_helper<Vector, typename vector_traits<Vector>::scalar_type NBL_PARTIAL_REQ_BOT (is_vector_v<Vector>) >
394
+ #ifdef __HLSL_VERSION
395
+ // SPIR-V already defines specializations for builtin vector types
396
+ #define VECTOR_SPECIALIZATION_CONCEPT concepts::Vectorial<T> && !is_vector_v<T>
397
+ #else
398
+ #define VECTOR_SPECIALIZATION_CONCEPT concepts::Vectorial<T>
399
+ #endif
400
+
401
+ template<typename T>
402
+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT)
403
+ struct clamp_helper<T, T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT) >
378
404
{
379
- using return_t = Vector ;
380
- static return_t __call (NBL_CONST_REF_ARG (Vector ) val, NBL_CONST_REF_ARG (typename vector_traits<Vector>::scalar_type ) min , NBL_CONST_REF_ARG (typename vector_traits<Vector>::scalar_type ) max )
405
+ using return_t = T ;
406
+ static return_t __call (NBL_CONST_REF_ARG (T ) val, NBL_CONST_REF_ARG (T ) min , NBL_CONST_REF_ARG (T ) max )
381
407
{
382
- using traits = hlsl::vector_traits<Vector >;
383
- array_get<Vector , typename traits::scalar_type> getter;
408
+ using traits = hlsl::vector_traits<T >;
409
+ array_get<T , typename traits::scalar_type> getter;
384
410
array_set<return_t, typename traits::scalar_type> setter;
385
411
386
412
return_t output;
387
413
for (uint32_t i = 0 ; i < traits::Dimension; ++i)
388
- setter (output, i, clamp_helper<typename traits::scalar_type, typename traits::scalar_type>::__call (getter (val, i), min , max ));
414
+ setter (output, i, clamp_helper<typename traits::scalar_type, typename traits::scalar_type>::__call (getter (val, i), getter ( min , i), getter ( max , i) ));
389
415
390
416
return output;
391
417
}
392
418
};
393
419
394
- template<typename Vector >
395
- NBL_PARTIAL_REQ_TOP (hlsl::is_vector_v<Vector> )
396
- struct bitReverse_helper<Vector NBL_PARTIAL_REQ_BOT (concepts::Vectorial<Vector> ) >
420
+ template<typename T >
421
+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT )
422
+ struct clamp_helper<T, typename vector_traits<T>::scalar_type NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT ) >
397
423
{
398
- static Vector __call (NBL_CONST_REF_ARG (Vector) vec)
424
+ using return_t = T;
425
+ static return_t __call (NBL_CONST_REF_ARG (T) val, NBL_CONST_REF_ARG (typename vector_traits<T>::scalar_type) min , NBL_CONST_REF_ARG (typename vector_traits<T>::scalar_type) max )
399
426
{
400
- #ifdef __HLSL_VERSION
401
- return spirv:: bitReverse (vec) ;
402
- #else
403
- Vector output;
404
- using traits = hlsl::vector_traits<Vector> ;
427
+ using traits = hlsl::vector_traits<T>;
428
+ array_get<T, typename traits::scalar_type> getter ;
429
+ array_set<return_t, typename traits::scalar_type> setter;
430
+
431
+ return_t output ;
405
432
for (uint32_t i = 0 ; i < traits::Dimension; ++i)
406
- output[i] = bitReverse_helper<traits::scalar_type>::__call (vec[i]);
433
+ setter (output, i, clamp_helper<typename traits::scalar_type, typename traits::scalar_type>::__call (getter (val, i), min , max ));
434
+
407
435
return output;
408
- #endif
409
436
}
410
437
};
411
438
412
- template<typename Vector >
413
- NBL_PARTIAL_REQ_TOP (is_vector_v<Vector> )
414
- struct min_helper<Vector NBL_PARTIAL_REQ_BOT (is_vector_v<Vector> ) >
439
+ template<typename T >
440
+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT )
441
+ struct min_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT ) >
415
442
{
416
- static Vector __call (NBL_CONST_REF_ARG (Vector ) a, NBL_CONST_REF_ARG (Vector ) b)
443
+ static T __call (NBL_CONST_REF_ARG (T ) a, NBL_CONST_REF_ARG (T ) b)
417
444
{
418
- using traits = hlsl::vector_traits<Vector >;
419
- array_get<Vector , typename traits::scalar_type> getter;
420
- array_set<Vector , typename traits::scalar_type> setter;
445
+ using traits = hlsl::vector_traits<T >;
446
+ array_get<T , typename traits::scalar_type> getter;
447
+ array_set<T , typename traits::scalar_type> setter;
421
448
422
- Vector output;
449
+ T output;
423
450
for (uint32_t i = 0 ; i < traits::Dimension; ++i)
424
451
setter (output, i, min_helper<typename traits::scalar_type>::__call (getter (a, i), getter (b, i)));
425
452
426
453
return output;
427
454
}
428
455
};
429
- template<typename Vector >
430
- NBL_PARTIAL_REQ_TOP (concepts::Vectorial<Vector> )
431
- struct max_helper<Vector NBL_PARTIAL_REQ_BOT (concepts::Vectorial<Vector> ) >
456
+ template<typename T >
457
+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT )
458
+ struct max_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT ) >
432
459
{
433
- static Vector __call (NBL_CONST_REF_ARG (Vector ) a, NBL_CONST_REF_ARG (Vector ) b)
460
+ static T __call (NBL_CONST_REF_ARG (T ) a, NBL_CONST_REF_ARG (T ) b)
434
461
{
435
- using traits = hlsl::vector_traits<Vector >;
436
- array_get<Vector , typename traits::scalar_type> getter;
437
- array_set<Vector , typename traits::scalar_type> setter;
462
+ using traits = hlsl::vector_traits<T >;
463
+ array_get<T , typename traits::scalar_type> getter;
464
+ array_set<T , typename traits::scalar_type> setter;
438
465
439
- Vector output;
466
+ T output;
440
467
for (uint32_t i = 0 ; i < traits::Dimension; ++i)
441
468
setter (output, i, max_helper<typename traits::scalar_type>::__call (getter (a, i), getter (b, i)));
442
469
443
470
return output;
444
471
}
445
472
};
446
473
447
- template<typename Integer>
448
- NBL_PARTIAL_REQ_TOP (concepts::IntegralScalar<Integer>)
449
- struct bitCount_helper<Integer NBL_PARTIAL_REQ_BOT (concepts::IntegralScalar<Integer>) >
450
- {
451
- using return_t = int32_t;
452
- static return_t __call (NBL_CONST_REF_ARG (Integer) val)
453
- {
454
- #ifdef __HLSL_VERSION
455
- if (sizeof (Integer) == 8u)
456
- {
457
- uint32_t lowBits = uint32_t (val);
458
- uint32_t highBits = uint32_t (uint64_t (val) >> 32u);
459
-
460
- return countbits (lowBits) + countbits (highBits);
461
- }
462
-
463
- return spirv::bitCount (val);
464
- #else
465
- using UnsignedInteger = typename hlsl::unsigned_integer_of_size_t<sizeof (Integer)>;
466
- constexpr int32_t BitCnt = sizeof (Integer) * 8u;
467
- std::bitset<BitCnt> bitset (static_cast<UnsignedInteger>(val));
468
- return bitset.count ();
469
- #endif
470
- }
471
- };
472
-
473
474
template<typename LhsT, typename RhsT>
474
475
NBL_PARTIAL_REQ_TOP (concepts::Matrix<LhsT> && (concepts::Matrix<RhsT> || concepts::Vector<RhsT>))
475
476
struct mul_helper<LhsT, RhsT NBL_PARTIAL_REQ_BOT (concepts::Matrix<LhsT> && (concepts::Matrix<RhsT> || concepts::Vector<RhsT>)) >
@@ -487,7 +488,7 @@ struct determinant_helper<SquareMatrix NBL_PARTIAL_REQ_BOT(matrix_traits<SquareM
487
488
static typename matrix_traits<SquareMatrix>::scalar_type __call (NBL_CONST_REF_ARG (SquareMatrix) mat)
488
489
{
489
490
#ifdef __HLSL_VERSION
490
- spirv::determinant (mat);
491
+ return spirv::determinant (mat);
491
492
#else
492
493
return glm::determinant (reinterpret_cast<typename SquareMatrix::Base const &>(mat));
493
494
#endif
@@ -517,8 +518,9 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
517
518
static return_t __call (NBL_CONST_REF_ARG (T) vec)\
518
519
{\
519
520
using traits = hlsl::vector_traits<T>;\
521
+ using return_t_traits = hlsl::vector_traits<return_t>;\
520
522
array_get<T, typename traits::scalar_type> getter;\
521
- array_set<T , typename traits ::scalar_type> setter;\
523
+ array_set<return_t , typename return_t_traits ::scalar_type> setter;\
522
524
\
523
525
return_t output;\
524
526
for (uint32_t i = 0 ; i < traits::Dimension; ++i)\
@@ -528,14 +530,8 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
528
530
}\
529
531
};
530
532
531
- #ifdef __HLSL_VERSION
532
- // SPIR-V already defines specializations for builtin vector types
533
- #define VECTOR_SPECIALIZATION_CONCEPT concepts::Vectorial<T> && !is_vector_v<T>
534
- #else
535
- #define VECTOR_SPECIALIZATION_CONCEPT concepts::Vectorial<T>
536
- #endif
537
-
538
533
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (rsqrt_helper, concepts::FloatingPointVectorial<T> && VECTOR_SPECIALIZATION_CONCEPT, T)
534
+ AUTO_SPECIALIZE_HELPER_FOR_VECTOR (bitReverse_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
539
535
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (frac_helper, VECTOR_SPECIALIZATION_CONCEPT,T)
540
536
#define INT32_VECTOR_TYPE vector <int32_t, hlsl::vector_traits<T>::Dimension>
541
537
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (bitCount_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
0 commit comments