16
16
#include <boost/preprocessor/punctuation/comma_if.hpp>
17
17
#include <boost/preprocessor/seq/for_each_i.hpp>
18
18
19
-
20
19
namespace nbl
21
20
{
22
21
namespace hlsl
@@ -63,7 +62,7 @@ struct any_helper;
63
62
template<typename T NBL_STRUCT_CONSTRAINABLE>
64
63
struct bitReverseAs_helper;
65
64
template<typename T NBL_STRUCT_CONSTRAINABLE>
66
- struct frac_helper ;
65
+ struct fract_helper ;
67
66
template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
68
67
struct mix_helper;
69
68
template<typename T NBL_STRUCT_CONSTRAINABLE>
@@ -123,7 +122,7 @@ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(transpose_helper, trans
123
122
template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (length_helper, length, (T), (T), typename vector_traits<T>::scalar_type)
124
123
template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (normalize_helper, normalize, (T), (T), T)
125
124
template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (rsqrt_helper, inverseSqrt, (T), (T), T)
126
- template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (frac_helper , fract, (T), (T), T)
125
+ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (fract_helper , fract, (T), (T), T)
127
126
template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (all_helper, any, (T), (T), T)
128
127
template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (any_helper, any, (T), (T), T)
129
128
template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (sign_helper, fSign, (T), (T), T)
@@ -212,14 +211,23 @@ struct inverse_helper<SquareMatrix NBL_PARTIAL_REQ_BOT(concepts::Matrix<SquareMa
212
211
}
213
212
};
214
213
215
- template<typename T, typename U > NBL_PARTIAL_REQ_TOP (always_true<decltype (spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U >()))>)
216
- struct mix_helper<T, U NBL_PARTIAL_REQ_BOT (always_true<decltype (spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U >()))>) >
214
+ template<typename T> NBL_PARTIAL_REQ_TOP (always_true<decltype (spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T >()))>)
215
+ struct mix_helper<T, T NBL_PARTIAL_REQ_BOT (always_true<decltype (spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T >()))>) >
217
216
{
218
217
using return_t = conditional_t<is_vector_v<T>, vector <typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>;
219
- static inline return_t __call (const T x, const T y, const U a)
218
+ static inline return_t __call (const T x, const T y, const T a)
219
+ {
220
+ return spirv::fMix<T>(x, y, a);
221
+ }
222
+ };
223
+
224
+ template<typename T> NBL_PARTIAL_REQ_TOP (concepts::FloatingPointScalar<T>)
225
+ struct mix_helper<T, bool NBL_PARTIAL_REQ_BOT (concepts::FloatingPointScalar<T>) >
226
+ {
227
+ using return_t = conditional_t<is_vector_v<T>, vector <typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>;
228
+ static inline return_t __call (const T x, const T y, const bool a)
220
229
{
221
- T aAsT = a;
222
- return spirv::fMix<T>(x, y, aAsT);
230
+ return a ? x : y;
223
231
}
224
232
};
225
233
@@ -287,7 +295,8 @@ struct transpose_helper<Matrix>
287
295
288
296
static transposed_t __call (NBL_CONST_REF_ARG (Matrix) m)
289
297
{
290
- return reinterpret_cast<transposed_t&>(glm::transpose (reinterpret_cast<typename Matrix::Base const &>(m)));
298
+ using traits = matrix_traits<Matrix>;
299
+ return reinterpret_cast<transposed_t&>(glm::transpose<traits::ColumnCount, traits::RowCount, traits::scalar_type, glm::qualifier::highp>(reinterpret_cast<typename Matrix::Base const &>(m)));
291
300
}
292
301
};
293
302
template<typename Vector>
@@ -367,7 +376,7 @@ struct rsqrt_helper<FloatingPoint>
367
376
368
377
template<typename T>
369
378
requires concepts::FloatingPointScalar<T>
370
- struct frac_helper <T>
379
+ struct fract_helper <T>
371
380
{
372
381
using return_t = T;
373
382
static inline return_t __call (const T x)
@@ -394,7 +403,8 @@ struct inverse_helper<SquareMatrix>
394
403
{
395
404
static SquareMatrix __call (NBL_CONST_REF_ARG (SquareMatrix) mat)
396
405
{
397
- return reinterpret_cast<SquareMatrix&>(glm::inverse (reinterpret_cast<typename SquareMatrix::Base const &>(mat)));
406
+ using traits = matrix_traits<SquareMatrix>;
407
+ return reinterpret_cast<SquareMatrix&>(glm::inverse<traits::ColumnCount, traits::RowCount, traits::scalar_type, glm::qualifier::highp>(reinterpret_cast<typename SquareMatrix::Base const &>(mat)));
398
408
}
399
409
};
400
410
@@ -411,13 +421,13 @@ struct bitCount_helper<EnumT>
411
421
};
412
422
413
423
template<typename T, typename U>
414
- requires (concepts::FloatingPoint <T> && (concepts::FloatingPoint <U> || concepts::Boolean <U>))
424
+ requires (concepts::FloatingPointScalar <T> && (concepts::FloatingPointScalar <U> || concepts::BooleanScalar <U>))
415
425
struct mix_helper<T, U>
416
426
{
417
427
using return_t = T;
418
428
static inline return_t __call (const T x, const T y, const U a)
419
429
{
420
- return glm::mix (x, y, a);
430
+ return glm::mix<T, U> (x, y, a);
421
431
}
422
432
};
423
433
@@ -532,15 +542,27 @@ struct refract_helper<T, U>
532
542
}
533
543
};
534
544
545
+ template<typename UnsignedInteger NBL_FUNC_REQUIRES (hlsl::is_integral_v<UnsignedInteger>&& hlsl::is_unsigned_v<UnsignedInteger>)
546
+ inline bool isnan_uint_impl (UnsignedInteger val)
547
+ {
548
+ using AsFloat = typename float_of_size<sizeof (UnsignedInteger)>::type;
549
+ constexpr UnsignedInteger Mask = ~static_cast<UnsignedInteger>(0 );
550
+ UnsignedInteger absVal = val & Mask;
551
+ return absVal > (ieee754::traits<AsFloat>::specialValueExp << ieee754::traits<AsFloat>::mantissaBitCnt);
552
+ }
553
+
535
554
template<typename T>
536
555
requires concepts::FloatingPoint<T>
537
556
struct nMin_helper<T>
538
557
{
539
558
using return_t = T;
540
559
static inline return_t __call (const T a, const T b)
541
560
{
561
+ using AsUint = typename unsigned_integer_of_size<sizeof (T)>::type;
562
+ const bool isANaN = isnan_uint_impl (reinterpret_cast<const AsUint&>(a));
563
+
542
564
// comparison involving any NaN always returns false
543
- return (b < a || std:: isnan (a) ) ? b : a;
565
+ return (b < a || isANaN ) ? b : a;
544
566
}
545
567
};
546
568
@@ -551,8 +573,11 @@ struct nMax_helper<T>
551
573
using return_t = T;
552
574
static inline return_t __call (const T a, const T b)
553
575
{
576
+ using AsUint = typename unsigned_integer_of_size<sizeof (T)>::type;
577
+ const bool isANaN = isnan_uint_impl (reinterpret_cast<const AsUint&>(a));
578
+
554
579
// comparison involving any NaN always returns false
555
- return (a < b || std:: isnan (a) ) ? b : a;
580
+ return (a < b || isANaN ) ? b : a;
556
581
}
557
582
};
558
583
@@ -729,7 +754,7 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
729
754
730
755
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (rsqrt_helper, concepts::FloatingPointVectorial<T> && VECTOR_SPECIALIZATION_CONCEPT, T)
731
756
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (bitReverse_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
732
- AUTO_SPECIALIZE_HELPER_FOR_VECTOR (frac_helper , VECTOR_SPECIALIZATION_CONCEPT,T)
757
+ AUTO_SPECIALIZE_HELPER_FOR_VECTOR (fract_helper , VECTOR_SPECIALIZATION_CONCEPT,T)
733
758
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (sign_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
734
759
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (degrees_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
735
760
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (radians_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
@@ -816,6 +841,27 @@ struct smoothStep_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
816
841
}
817
842
};
818
843
844
+ template<typename T, typename U>
845
+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT && vector_traits<T>::Dimension == vector_traits<U>::Dimension)
846
+ struct mix_helper<T, U NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT && vector_traits<T>::Dimension == vector_traits<U>::Dimension) >
847
+ {
848
+ using return_t = T;
849
+ static return_t __call (NBL_CONST_REF_ARG (T) x, NBL_CONST_REF_ARG (T) y, NBL_CONST_REF_ARG (U) a)
850
+ {
851
+ using traitsT = hlsl::vector_traits<T>;
852
+ using traitsU = hlsl::vector_traits<U>;
853
+ array_get<T, typename traitsT::scalar_type> getterT;
854
+ array_get<U, typename traitsU::scalar_type> getterU;
855
+ array_set<return_t, typename traitsT::scalar_type> setter;
856
+
857
+ return_t output;
858
+ for (uint32_t i = 0 ; i < traitsT::Dimension; ++i)
859
+ setter (output, i, mix_helper<typename traitsT::scalar_type, typename traitsU::scalar_type>::__call (getterT (x, i), getterT (y, i), getterU (a, i)));
860
+
861
+ return output;
862
+ }
863
+ };
864
+
819
865
}
820
866
}
821
867
}
0 commit comments