@@ -111,10 +111,14 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(find_lsb_helper, findILsb, FIND_MSB_LSB_RETU
111111#undef FIND_MSB_LSB_RETURN_TYPE
112112AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (bitReverse_helper, bitReverse, T)
113113AUTO_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 )
115115AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (normalize_helper, normalize, T)
116116AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (rsqrt_helper, inverseSqrt, T)
117117AUTO_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+
118122
119123template<typename UInt64> NBL_PARTIAL_REQ_TOP (is_same_v<UInt64, uint64_t>)
120124struct 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>) >
161165};
162166
163167#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>() ))>) >\
166170{\
167171 using return_t = RETURN_TYPE;\
168172 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
174178AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (max_helper, fMax, T)
175179AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (max_helper, uMax, T)
176180AUTO_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
180185
181186#else // C++ only specializations
182187
@@ -311,6 +316,20 @@ struct frac_helper<T>
311316 }
312317};
313318
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+
314333#endif // C++ only specializations
315334
316335// C++ and HLSL specializations
@@ -372,104 +391,86 @@ struct cross_helper<FloatingPointLikeVectorial NBL_PARTIAL_REQ_BOT(concepts::Flo
372391 }
373392};
374393
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) >
378404{
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 )
381407 {
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;
384410 array_set<return_t, typename traits::scalar_type> setter;
385411
386412 return_t output;
387413 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) ));
389415
390416 return output;
391417 }
392418};
393419
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 ) >
397423{
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 )
399426 {
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 ;
405432 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+
407435 return output;
408- #endif
409436 }
410437};
411438
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 ) >
415442{
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)
417444 {
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;
421448
422- Vector output;
449+ T output;
423450 for (uint32_t i = 0 ; i < traits::Dimension; ++i)
424451 setter (output, i, min_helper<typename traits::scalar_type>::__call (getter (a, i), getter (b, i)));
425452
426453 return output;
427454 }
428455};
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 ) >
432459{
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)
434461 {
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;
438465
439- Vector output;
466+ T output;
440467 for (uint32_t i = 0 ; i < traits::Dimension; ++i)
441468 setter (output, i, max_helper<typename traits::scalar_type>::__call (getter (a, i), getter (b, i)));
442469
443470 return output;
444471 }
445472};
446473
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-
473474template<typename LhsT, typename RhsT>
474475NBL_PARTIAL_REQ_TOP (concepts::Matrix<LhsT> && (concepts::Matrix<RhsT> || concepts::Vector<RhsT>))
475476struct 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
487488 static typename matrix_traits<SquareMatrix>::scalar_type __call (NBL_CONST_REF_ARG (SquareMatrix) mat)
488489 {
489490#ifdef __HLSL_VERSION
490- spirv::determinant (mat);
491+ return spirv::determinant (mat);
491492#else
492493 return glm::determinant (reinterpret_cast<typename SquareMatrix::Base const &>(mat));
493494#endif
@@ -517,8 +518,9 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
517518 static return_t __call (NBL_CONST_REF_ARG (T) vec)\
518519 {\
519520 using traits = hlsl::vector_traits<T>;\
521+ using return_t_traits = hlsl::vector_traits<return_t>;\
520522 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;\
522524\
523525 return_t output;\
524526 for (uint32_t i = 0 ; i < traits::Dimension; ++i)\
@@ -528,14 +530,8 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
528530 }\
529531};
530532
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-
538533AUTO_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)
539535AUTO_SPECIALIZE_HELPER_FOR_VECTOR (frac_helper, VECTOR_SPECIALIZATION_CONCEPT,T)
540536#define INT32_VECTOR_TYPE vector <int32_t, hlsl::vector_traits<T>::Dimension>
541537AUTO_SPECIALIZE_HELPER_FOR_VECTOR (bitCount_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
0 commit comments