@@ -59,7 +59,7 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
5959struct all_helper;
6060template<typename T NBL_STRUCT_CONSTRAINABLE>
6161struct any_helper;
62- template<typename T, uint16_t Bits NBL_STRUCT_CONSTRAINABLE>
62+ template<typename T NBL_STRUCT_CONSTRAINABLE>
6363struct bitReverseAs_helper;
6464template<typename T NBL_STRUCT_CONSTRAINABLE>
6565struct frac_helper;
@@ -81,6 +81,13 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
8181struct reflect_helper;
8282template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
8383struct refract_helper;
84+ template<typename T NBL_STRUCT_CONSTRAINABLE>
85+ struct nMin_helper;
86+ template<typename T NBL_STRUCT_CONSTRAINABLE>
87+ struct nMax_helper;
88+ template<typename T NBL_STRUCT_CONSTRAINABLE>
89+ struct nClamp_helper;
90+
8491
8592#ifdef __HLSL_VERSION // HLSL only specializations
8693
@@ -136,6 +143,9 @@ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(clamp_helper, sClamp, (
136143template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (smoothStep_helper, smoothStep, (T), (T)(T)(T), T)
137144template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (faceForward_helper, faceForward, (T), (T)(T)(T), T)
138145template<typename T, typename U> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (refract_helper, refract, (T)(U), (T)(T)(U), T)
146+ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (nMax_helper, nMax, (T), (T)(T), T)
147+ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (nMin_helper, nMin, (T), (T)(T), T)
148+ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (nClamp_helper, nClamp, (T), (T)(T), T)
139149
140150#define BITCOUNT_HELPER_RETRUN_TYPE conditional_t<is_vector_v<T>, vector <int32_t, vector_traits<T>::Dimension>, int32_t>
141151template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (bitCount_helper, bitCount, (T), (T), BITCOUNT_HELPER_RETRUN_TYPE)
@@ -221,6 +231,16 @@ struct determinant_helper<SquareMatrix NBL_PARTIAL_REQ_BOT(matrix_traits<SquareM
221231 }
222232};
223233
234+ template<typename T>
235+ NBL_PARTIAL_REQ_TOP (concepts::FloatingPointVector<T> && (vector_traits<T>::Dimension == 3 ))
236+ struct cross_helper<T NBL_PARTIAL_REQ_BOT (concepts::FloatingPointVector<T> && (vector_traits<T>::Dimension == 3 )) >
237+ {
238+ static T __call (NBL_CONST_REF_ARG (T) lhs, NBL_CONST_REF_ARG (T) rhs)
239+ {
240+ return spirv::cross<T>(lhs, rhs);
241+ }
242+ };
243+
224244#else // C++ only specializations
225245
226246#define DECL_ARG (r,data,i,_T) BOOST_PP_COMMA_IF (BOOST_PP_NOT_EQUAL (i,0 )) const _T arg##i
@@ -284,7 +304,8 @@ struct normalize_helper<Vectorial>
284304{
285305 static inline Vectorial __call (NBL_CONST_REF_ARG (Vectorial) vec)
286306 {
287- return vec / length_helper<Vectorial>::__call (vec);
307+ auto squareLen = dot_helper<Vectorial>::__call (vec, vec);
308+ return vec * rsqrt_helper<typename vector_traits<Vectorial>::scalar_type>::__call (squareLen);
288309 }
289310};
290311
@@ -299,8 +320,8 @@ struct find_lsb_helper<T>
299320 }
300321};
301322template<typename Integer>
302- NBL_PARTIAL_REQ_TOP ( concepts::IntegralScalar<Integer>)
303- struct find_msb_helper<Integer NBL_PARTIAL_REQ_BOT (concepts::IntegralScalar<Integer>) >
323+ requires concepts::IntegralScalar<Integer>
324+ struct find_msb_helper<Integer>
304325{
305326 using return_t = int32_t;
306327 static return_t __call (NBL_CONST_REF_ARG (Integer) val)
@@ -389,7 +410,7 @@ struct bitCount_helper<EnumT>
389410};
390411
391412template<typename T, typename U>
392- requires concepts::FloatingPoint<T> && (concepts::FloatingPoint<T > || concepts::Boolean<T> )
413+ requires ( concepts::FloatingPoint<T> && (concepts::FloatingPoint<U > || concepts::Boolean<U>) )
393414struct mix_helper<T, U>
394415{
395416 using return_t = T;
@@ -422,7 +443,7 @@ struct radians_helper<T>
422443 using return_t = T;
423444 static inline return_t __call (const T degrees)
424445 {
425- return degrees * (numbers::pi<T> / static_cast<T>(180.0 ));
446+ return degrees * (bit_cast<T>( numbers::pi<T>) / static_cast<T>(180.0 ));
426447 }
427448};
428449
@@ -433,7 +454,7 @@ struct degrees_helper<T>
433454 using return_t = T;
434455 static inline return_t __call (const T radians)
435456 {
436- return radians * (static_cast<T>(180.0 ) / numbers::pi<T>);
457+ return radians * (static_cast<T>(180.0 ) / bit_cast<T>( numbers::pi<T>) );
437458 }
438459};
439460
@@ -456,7 +477,7 @@ struct smoothStep_helper<T>
456477 static inline return_t __call (const T edge0, const T edge1, const T x)
457478 {
458479 T t = clamp_helper<T>::__call ((x - edge0) / (edge1 - edge0), 0 , 1 );
459- return t * t * (3 - 2 * t);
480+ return t * t * (T ( 3 ) - T ( 2 ) * t);
460481 }
461482};
462483
@@ -510,19 +531,57 @@ struct refract_helper<T, U>
510531 }
511532};
512533
513- #endif // C++ only specializations
534+ template<typename T>
535+ requires concepts::FloatingPoint<T>
536+ struct nMin_helper<T>
537+ {
538+ using return_t = T;
539+ static inline return_t __call (const T a, const T b)
540+ {
541+ if (std::isnan (a))
542+ return b;
543+ if (std::isnan (b))
544+ return a;
514545
515- // C++ and HLSL specializations
546+ return std::min (a, b);
547+ }
548+ };
549+
550+ template<typename T>
551+ requires concepts::FloatingPoint<T>
552+ struct nMax_helper<T>
553+ {
554+ using return_t = T;
555+ static inline return_t __call (const T a, const T b)
556+ {
557+ if (std::isnan (a))
558+ return b;
559+ if (std::isnan (b))
560+ return a;
561+
562+ return std::max (a, b);
563+ }
564+ };
516565
517- template<typename T, uint16_t Bits >
518- NBL_PARTIAL_REQ_TOP ( concepts::UnsignedIntegralScalar <T> && (Bits <= sizeof (T) * 8 ))
519- struct bitReverseAs_helper<T, Bits NBL_PARTIAL_REQ_BOT (concepts::UnsignedIntegralScalar<T> && (Bits <= sizeof (T) * 8 )) >
566+ template<typename T>
567+ requires concepts::FloatingPoint <T>
568+ struct nClamp_helper<T >
520569{
521- static T __call (NBL_CONST_REF_ARG (T) val)
570+ using return_t = T;
571+ static inline return_t __call (const T x, const T _min, const T _max)
522572 {
523- return bitReverse_helper<T>:: __call (val) >> promote<T, scalar_type_t<T> >(scalar_type_t <T>( sizeof (T) * 8 - Bits) );
573+ return nMin_helper:: _call (nMax_helper:: _call (x, _min), _max );
524574 }
575+ };
576+
577+ #endif // C++ only specializations
525578
579+ // C++ and HLSL specializations
580+
581+ template<typename T>
582+ NBL_PARTIAL_REQ_TOP (concepts::UnsignedIntegralScalar<T>)
583+ struct bitReverseAs_helper<T NBL_PARTIAL_REQ_BOT (concepts::UnsignedIntegralScalar<T>) >
584+ {
526585 static T __call (NBL_CONST_REF_ARG (T) val, uint16_t bits)
527586 {
528587 return bitReverse_helper<T>::__call (val) >> promote<T, scalar_type_t<T> >(scalar_type_t <T>(sizeof (T) * 8 - bits));
@@ -547,28 +606,6 @@ struct dot_helper<Vectorial NBL_PARTIAL_REQ_BOT(concepts::Vectorial<Vectorial>)
547606 return retval;
548607 }
549608};
550- template<typename FloatingPointLikeVectorial>
551- NBL_PARTIAL_REQ_TOP (concepts::FloatingPointLikeVectorial<FloatingPointLikeVectorial> && (vector_traits<FloatingPointLikeVectorial>::Dimension == 3 ))
552- struct cross_helper<FloatingPointLikeVectorial NBL_PARTIAL_REQ_BOT (concepts::FloatingPointLikeVectorial<FloatingPointLikeVectorial> && (vector_traits<FloatingPointLikeVectorial>::Dimension == 3 )) >
553- {
554- static FloatingPointLikeVectorial __call (NBL_CONST_REF_ARG (FloatingPointLikeVectorial) lhs, NBL_CONST_REF_ARG (FloatingPointLikeVectorial) rhs)
555- {
556- #ifdef __HLSL_VERSION
557- return spirv::cross (lhs, rhs);
558- #else
559- using traits = hlsl::vector_traits<FloatingPointLikeVectorial>;
560- array_get<FloatingPointLikeVectorial, typename traits::scalar_type> getter;
561- array_set<FloatingPointLikeVectorial, typename traits::scalar_type> setter;
562-
563- FloatingPointLikeVectorial output;
564- setter (output, 0 , getter (lhs, 1 ) * getter (rhs, 2 ) - getter (rhs, 1 ) * getter (lhs, 2 ));
565- setter (output, 1 , getter (lhs, 2 ) * getter (rhs, 0 ) - getter (rhs, 2 ) * getter (lhs, 0 ));
566- setter (output, 2 , getter (lhs, 0 ) * getter (rhs, 1 ) - getter (rhs, 0 ) * getter (lhs, 1 ));
567-
568- return output;
569- #endif
570- }
571- };
572609
573610#ifdef __HLSL_VERSION
574611// SPIR-V already defines specializations for builtin vector types
@@ -596,6 +633,25 @@ struct clamp_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
596633 }
597634};
598635
636+ template<typename T>
637+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT && concepts::FloatingPointLikeVectorial<T> && (vector_traits<T>::Dimension == 3 ))
638+ struct cross_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT && concepts::FloatingPointLikeVectorial<T> && (vector_traits<T>::Dimension == 3 )) >
639+ {
640+ static T __call (NBL_CONST_REF_ARG (T) lhs, NBL_CONST_REF_ARG (T) rhs)
641+ {
642+ using traits = hlsl::vector_traits<T>;
643+ array_get<T, typename traits::scalar_type> getter;
644+ array_set<T, typename traits::scalar_type> setter;
645+
646+ T output;
647+ setter (output, 0 , getter (lhs, 1 ) * getter (rhs, 2 ) - getter (rhs, 1 ) * getter (lhs, 2 ));
648+ setter (output, 1 , getter (lhs, 2 ) * getter (rhs, 0 ) - getter (rhs, 2 ) * getter (lhs, 0 ));
649+ setter (output, 2 , getter (lhs, 0 ) * getter (rhs, 1 ) - getter (rhs, 0 ) * getter (lhs, 1 ));
650+
651+ return output;
652+ }
653+ };
654+
599655template<typename T>
600656NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT)
601657struct min_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT) >
@@ -689,17 +745,19 @@ AUTO_SPECIALIZE_HELPER_FOR_VECTOR(bitCount_helper, VECTOR_SPECIALIZATION_CONCEPT
689745AUTO_SPECIALIZE_HELPER_FOR_VECTOR (find_msb_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
690746AUTO_SPECIALIZE_HELPER_FOR_VECTOR (find_lsb_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
691747#undef INT32_VECTOR_TYPE
748+ AUTO_SPECIALIZE_HELPER_FOR_VECTOR (nMin_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
749+ AUTO_SPECIALIZE_HELPER_FOR_VECTOR (nMax_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
692750#undef AUTO_SPECIALIZE_HELPER_FOR_VECTOR
693751
694- template<typename BooleanVector >
695- NBL_PARTIAL_REQ_TOP (concepts::Vectorial<BooleanVector> && is_same_v<typename vector_traits<BooleanVector >::scalar_type, bool >)
696- struct all_helper<BooleanVector NBL_PARTIAL_REQ_BOT (concepts::Vectorial<BooleanVector> && is_same_v<typename vector_traits<BooleanVector >::scalar_type, bool >) >
752+ template<typename T >
753+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT && is_same_v<typename vector_traits<T >::scalar_type, bool >)
754+ struct all_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT && is_same_v<typename vector_traits<T >::scalar_type, bool >) >
697755{
698- static bool __call (NBL_CONST_REF_ARG (BooleanVector ) x)
756+ static bool __call (NBL_CONST_REF_ARG (T ) x)
699757 {
700- using traits = hlsl::vector_traits<BooleanVector >;
701- array_get<BooleanVector , typename traits::scalar_type> getter;
702- array_set<BooleanVector , typename traits::scalar_type> setter;
758+ using traits = hlsl::vector_traits<T >;
759+ array_get<T , typename traits::scalar_type> getter;
760+ array_set<T , typename traits::scalar_type> setter;
703761
704762 bool output = true ;
705763 for (uint32_t i = 0 ; i < traits::Dimension; ++i)
@@ -709,15 +767,15 @@ struct all_helper<BooleanVector NBL_PARTIAL_REQ_BOT(concepts::Vectorial<BooleanV
709767 }
710768};
711769
712- template<typename BooleanVector >
713- NBL_PARTIAL_REQ_TOP (concepts::Vectorial<BooleanVector> && is_same_v<typename vector_traits<BooleanVector >::scalar_type, bool >)
714- struct any_helper<BooleanVector NBL_PARTIAL_REQ_BOT (concepts::Vectorial<BooleanVector> && is_same_v<typename vector_traits<BooleanVector >::scalar_type, bool >) >
770+ template<typename T >
771+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT && is_same_v<typename vector_traits<T >::scalar_type, bool >)
772+ struct any_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT && is_same_v<typename vector_traits<T >::scalar_type, bool >) >
715773{
716- static bool __call (NBL_CONST_REF_ARG (BooleanVector ) x)
774+ static bool __call (NBL_CONST_REF_ARG (T ) x)
717775 {
718- using traits = hlsl::vector_traits<BooleanVector >;
719- array_get<BooleanVector , typename traits::scalar_type> getter;
720- array_set<BooleanVector , typename traits::scalar_type> setter;
776+ using traits = hlsl::vector_traits<T >;
777+ array_get<T , typename traits::scalar_type> getter;
778+ array_set<T , typename traits::scalar_type> setter;
721779
722780 bool output = false ;
723781 for (uint32_t i = 0 ; i < traits::Dimension; ++i)
0 commit comments