@@ -68,8 +68,8 @@ struct cross_helper;
68
68
69
69
//! this specialization will work only with hlsl::vector<T, 3> type
70
70
template<typename FloatingPointVector>
71
- NBL_PARTIAL_REQ_TOP (hlsl:: is_floating_point_v<FloatingPointVector> && hlsl:: is_vector_v<FloatingPointVector> && (vector_traits<FloatingPointVector>::Dimension == 3 ))
72
- struct cross_helper<FloatingPointVector NBL_PARTIAL_REQ_BOT (hlsl:: is_floating_point_v<FloatingPointVector>&& hlsl:: is_vector_v<FloatingPointVector>&& (vector_traits<FloatingPointVector>::Dimension == 3 )) >
71
+ NBL_PARTIAL_REQ_TOP (is_floating_point_v<FloatingPointVector> && is_vector_v<FloatingPointVector> && (vector_traits<FloatingPointVector>::Dimension == 3 ))
72
+ struct cross_helper<FloatingPointVector NBL_PARTIAL_REQ_BOT (is_floating_point_v<FloatingPointVector>&& is_vector_v<FloatingPointVector>&& (vector_traits<FloatingPointVector>::Dimension == 3 )) >
73
73
{
74
74
static FloatingPointVector __call (NBL_CONST_REF_ARG (FloatingPointVector) lhs, NBL_CONST_REF_ARG (FloatingPointVector) rhs)
75
75
{
@@ -86,6 +86,69 @@ struct cross_helper<FloatingPointVector NBL_PARTIAL_REQ_BOT(hlsl::is_floating_po
86
86
}
87
87
};
88
88
89
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
90
+ struct clamp_helper;
91
+
92
+ template<typename FloatingPoint>
93
+ NBL_PARTIAL_REQ_TOP (is_floating_point_v<FloatingPoint> && is_scalar_v<FloatingPoint>)
94
+ struct clamp_helper<FloatingPoint NBL_PARTIAL_REQ_BOT (is_floating_point_v<FloatingPoint> && is_scalar_v<FloatingPoint>) >
95
+ {
96
+ static FloatingPoint __call (NBL_CONST_REF_ARG (FloatingPoint) val, NBL_CONST_REF_ARG (FloatingPoint) min , NBL_CONST_REF_ARG (FloatingPoint) max )
97
+ {
98
+ #ifdef __HLSL_VERSION
99
+ return spirv::fClamp (val, min , max );
100
+ #else
101
+ return std::clamp (val, min , max );
102
+ #endif
103
+ }
104
+ };
105
+
106
+ template<typename UnsignedInteger>
107
+ NBL_PARTIAL_REQ_TOP (is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger> && is_scalar_v<UnsignedInteger>)
108
+ struct clamp_helper<UnsignedInteger NBL_PARTIAL_REQ_BOT (is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>) >
109
+ {
110
+ static UnsignedInteger __call (NBL_CONST_REF_ARG (UnsignedInteger) val, NBL_CONST_REF_ARG (UnsignedInteger) min , NBL_CONST_REF_ARG (UnsignedInteger) max )
111
+ {
112
+ #ifdef __HLSL_VERSION
113
+ return spirv::uClamp (val, min , max );
114
+ #else
115
+ return std::clamp (val, min , max );
116
+ #endif
117
+ }
118
+ };
119
+
120
+ template<typename Integer>
121
+ NBL_PARTIAL_REQ_TOP (is_integral_v<Integer> && is_signed_v<Integer>&& is_scalar_v<Integer>)
122
+ struct clamp_helper<Integer NBL_PARTIAL_REQ_BOT (is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>) >
123
+ {
124
+ static Integer __call (NBL_CONST_REF_ARG (Integer) val, NBL_CONST_REF_ARG (Integer) min , NBL_CONST_REF_ARG (Integer) max )
125
+ {
126
+ #ifdef __HLSL_VERSION
127
+ return spirv::sClamp (val, min , max );
128
+ #else
129
+ return std::clamp (val, min , max );
130
+ #endif
131
+ }
132
+ };
133
+
134
+ template<typename Vector>
135
+ NBL_PARTIAL_REQ_TOP (is_vector_v<Vector>)
136
+ struct clamp_helper<Vector NBL_PARTIAL_REQ_BOT (is_vector_v<Vector>) >
137
+ {
138
+ static Vector __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 )
139
+ {
140
+ using traits = hlsl::vector_traits<Vector>;
141
+ array_get<Vector, typename traits::scalar_type> getter;
142
+ array_set<Vector, typename traits::scalar_type> setter;
143
+
144
+ Vector output;
145
+ for (uint32_t i = 0 ; i < traits::Dimension; ++i)
146
+ setter (output, i, clamp_helper<typename traits::scalar_type>::__call (getter (val, i), min , max ));
147
+
148
+ return output;
149
+ }
150
+ };
151
+
89
152
template<typename Integer>
90
153
struct find_msb_helper;
91
154
@@ -512,6 +575,136 @@ struct normalize_helper<Vector NBL_PARTIAL_REQ_BOT(hlsl::is_floating_point_v<Vec
512
575
}
513
576
};
514
577
578
+ // MIN
579
+
580
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
581
+ struct min_helper;
582
+
583
+ template<typename FloatingPoint>
584
+ NBL_PARTIAL_REQ_TOP (is_floating_point_v<FloatingPoint>&& is_scalar_v<FloatingPoint>)
585
+ struct min_helper<FloatingPoint NBL_PARTIAL_REQ_BOT (is_floating_point_v<FloatingPoint>&& is_scalar_v<FloatingPoint>) >
586
+ {
587
+ static FloatingPoint __call (NBL_CONST_REF_ARG (FloatingPoint) a, NBL_CONST_REF_ARG (FloatingPoint) b)
588
+ {
589
+ #ifdef __HLSL_VERSION
590
+ return spirv::fMin (a, b);
591
+ #else
592
+ return std::min (a, b);
593
+ #endif
594
+ }
595
+ };
596
+
597
+ template<typename UnsignedInteger>
598
+ NBL_PARTIAL_REQ_TOP (is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>)
599
+ struct min_helper<UnsignedInteger NBL_PARTIAL_REQ_BOT (is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>) >
600
+ {
601
+ static UnsignedInteger __call (NBL_CONST_REF_ARG (UnsignedInteger) a, NBL_CONST_REF_ARG (UnsignedInteger) b)
602
+ {
603
+ #ifdef __HLSL_VERSION
604
+ return spirv::uMin (a, b);
605
+ #else
606
+ return std::min (a, b);
607
+ #endif
608
+ }
609
+ };
610
+
611
+ template<typename Integer>
612
+ NBL_PARTIAL_REQ_TOP (is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>)
613
+ struct min_helper<Integer NBL_PARTIAL_REQ_BOT (is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>) >
614
+ {
615
+ static Integer __call (NBL_CONST_REF_ARG (Integer) a, NBL_CONST_REF_ARG (Integer) b)
616
+ {
617
+ #ifdef __HLSL_VERSION
618
+ return spirv::sMin (a, b);
619
+ #else
620
+ return std::min (a, b);
621
+ #endif
622
+ }
623
+ };
624
+
625
+ template<typename Vector>
626
+ NBL_PARTIAL_REQ_TOP (is_vector_v<Vector>)
627
+ struct min_helper<Vector NBL_PARTIAL_REQ_BOT (is_vector_v<Vector>) >
628
+ {
629
+ static Vector __call (NBL_CONST_REF_ARG (Vector) a, NBL_CONST_REF_ARG (Vector) b)
630
+ {
631
+ using traits = hlsl::vector_traits<Vector>;
632
+ array_get<Vector, typename traits::scalar_type> getter;
633
+ array_set<Vector, typename traits::scalar_type> setter;
634
+
635
+ Vector output;
636
+ for (uint32_t i = 0 ; i < traits::Dimension; ++i)
637
+ setter (output, i, min_helper<typename traits::scalar_type>::__call (getter (a, i), getter (b, i)));
638
+
639
+ return output;
640
+ }
641
+ };
642
+
643
+ // MAX
644
+
645
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
646
+ struct max_helper;
647
+
648
+ template<typename FloatingPoint>
649
+ NBL_PARTIAL_REQ_TOP (is_floating_point_v<FloatingPoint>&& is_scalar_v<FloatingPoint>)
650
+ struct max_helper<FloatingPoint NBL_PARTIAL_REQ_BOT (is_floating_point_v<FloatingPoint>&& is_scalar_v<FloatingPoint>) >
651
+ {
652
+ static FloatingPoint __call (NBL_CONST_REF_ARG (FloatingPoint) a, NBL_CONST_REF_ARG (FloatingPoint) b)
653
+ {
654
+ #ifdef __HLSL_VERSION
655
+ return spirv::fMax (a, b);
656
+ #else
657
+ return std::max (a, b);
658
+ #endif
659
+ }
660
+ };
661
+
662
+ template<typename UnsignedInteger>
663
+ NBL_PARTIAL_REQ_TOP (is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>)
664
+ struct max_helper<UnsignedInteger NBL_PARTIAL_REQ_BOT (is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>) >
665
+ {
666
+ static UnsignedInteger __call (NBL_CONST_REF_ARG (UnsignedInteger) a, NBL_CONST_REF_ARG (UnsignedInteger) b)
667
+ {
668
+ #ifdef __HLSL_VERSION
669
+ return spirv::uMax (a, b);
670
+ #else
671
+ return std::max (a, b);
672
+ #endif
673
+ }
674
+ };
675
+
676
+ template<typename Integer>
677
+ NBL_PARTIAL_REQ_TOP (is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>)
678
+ struct max_helper<Integer NBL_PARTIAL_REQ_BOT (is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>) >
679
+ {
680
+ static Integer __call (NBL_CONST_REF_ARG (Integer) a, NBL_CONST_REF_ARG (Integer) b)
681
+ {
682
+ #ifdef __HLSL_VERSION
683
+ return spirv::sMax (a, b);
684
+ #else
685
+ return std::max (a, b);
686
+ #endif
687
+ }
688
+ };
689
+
690
+ template<typename Vector>
691
+ NBL_PARTIAL_REQ_TOP (is_vector_v<Vector>)
692
+ struct max_helper<Vector NBL_PARTIAL_REQ_BOT (is_vector_v<Vector>) >
693
+ {
694
+ static Vector __call (NBL_CONST_REF_ARG (Vector) a, NBL_CONST_REF_ARG (Vector) b)
695
+ {
696
+ using traits = hlsl::vector_traits<Vector>;
697
+ array_get<Vector, typename traits::scalar_type> getter;
698
+ array_set<Vector, typename traits::scalar_type> setter;
699
+
700
+ Vector output;
701
+ for (uint32_t i = 0 ; i < traits::Dimension; ++i)
702
+ setter (output, i, max_helper<typename traits::scalar_type>::__call (getter (a, i), getter (b, i)));
703
+
704
+ return output;
705
+ }
706
+ };
707
+
515
708
}
516
709
}
517
710
}
0 commit comments