@@ -59,7 +59,7 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
59
59
struct all_helper;
60
60
template<typename T NBL_STRUCT_CONSTRAINABLE>
61
61
struct any_helper;
62
- template<typename T, uint16_t Bits NBL_STRUCT_CONSTRAINABLE>
62
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
63
63
struct bitReverseAs_helper;
64
64
template<typename T NBL_STRUCT_CONSTRAINABLE>
65
65
struct frac_helper;
@@ -81,6 +81,13 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
81
81
struct reflect_helper;
82
82
template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
83
83
struct 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
+
84
91
85
92
#ifdef __HLSL_VERSION // HLSL only specializations
86
93
@@ -136,6 +143,9 @@ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(clamp_helper, sClamp, (
136
143
template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (smoothStep_helper, smoothStep, (T), (T)(T)(T), T)
137
144
template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (faceForward_helper, faceForward, (T), (T)(T)(T), T)
138
145
template<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)
139
149
140
150
#define BITCOUNT_HELPER_RETRUN_TYPE conditional_t<is_vector_v<T>, vector <int32_t, vector_traits<T>::Dimension>, int32_t>
141
151
template<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
221
231
}
222
232
};
223
233
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
+
224
244
#else // C++ only specializations
225
245
226
246
#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>
284
304
{
285
305
static inline Vectorial __call (NBL_CONST_REF_ARG (Vectorial) vec)
286
306
{
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);
288
309
}
289
310
};
290
311
@@ -299,8 +320,8 @@ struct find_lsb_helper<T>
299
320
}
300
321
};
301
322
template<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>
304
325
{
305
326
using return_t = int32_t;
306
327
static return_t __call (NBL_CONST_REF_ARG (Integer) val)
@@ -389,7 +410,7 @@ struct bitCount_helper<EnumT>
389
410
};
390
411
391
412
template<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>) )
393
414
struct mix_helper<T, U>
394
415
{
395
416
using return_t = T;
@@ -422,7 +443,7 @@ struct radians_helper<T>
422
443
using return_t = T;
423
444
static inline return_t __call (const T degrees)
424
445
{
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 ));
426
447
}
427
448
};
428
449
@@ -433,7 +454,7 @@ struct degrees_helper<T>
433
454
using return_t = T;
434
455
static inline return_t __call (const T radians)
435
456
{
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>) );
437
458
}
438
459
};
439
460
@@ -456,7 +477,7 @@ struct smoothStep_helper<T>
456
477
static inline return_t __call (const T edge0, const T edge1, const T x)
457
478
{
458
479
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);
460
481
}
461
482
};
462
483
@@ -510,19 +531,57 @@ struct refract_helper<T, U>
510
531
}
511
532
};
512
533
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;
514
545
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
+ };
516
565
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 >
520
569
{
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)
522
572
{
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 );
524
574
}
575
+ };
576
+
577
+ #endif // C++ only specializations
525
578
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
+ {
526
585
static T __call (NBL_CONST_REF_ARG (T) val, uint16_t bits)
527
586
{
528
587
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>)
547
606
return retval;
548
607
}
549
608
};
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
- };
572
609
573
610
#ifdef __HLSL_VERSION
574
611
// SPIR-V already defines specializations for builtin vector types
@@ -596,6 +633,25 @@ struct clamp_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
596
633
}
597
634
};
598
635
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
+
599
655
template<typename T>
600
656
NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT)
601
657
struct min_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT) >
@@ -689,17 +745,19 @@ AUTO_SPECIALIZE_HELPER_FOR_VECTOR(bitCount_helper, VECTOR_SPECIALIZATION_CONCEPT
689
745
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (find_msb_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
690
746
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (find_lsb_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
691
747
#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)
692
750
#undef AUTO_SPECIALIZE_HELPER_FOR_VECTOR
693
751
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 >) >
697
755
{
698
- static bool __call (NBL_CONST_REF_ARG (BooleanVector ) x)
756
+ static bool __call (NBL_CONST_REF_ARG (T ) x)
699
757
{
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;
703
761
704
762
bool output = true ;
705
763
for (uint32_t i = 0 ; i < traits::Dimension; ++i)
@@ -709,15 +767,15 @@ struct all_helper<BooleanVector NBL_PARTIAL_REQ_BOT(concepts::Vectorial<BooleanV
709
767
}
710
768
};
711
769
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 >) >
715
773
{
716
- static bool __call (NBL_CONST_REF_ARG (BooleanVector ) x)
774
+ static bool __call (NBL_CONST_REF_ARG (T ) x)
717
775
{
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;
721
779
722
780
bool output = false ;
723
781
for (uint32_t i = 0 ; i < traits::Dimension; ++i)
0 commit comments