1616#include <boost/preprocessor/punctuation/comma_if.hpp>
1717#include <boost/preprocessor/seq/for_each_i.hpp>
1818
19-
2019namespace nbl
2120{
2221namespace hlsl
@@ -63,7 +62,7 @@ struct any_helper;
6362template<typename T NBL_STRUCT_CONSTRAINABLE>
6463struct bitReverseAs_helper;
6564template<typename T NBL_STRUCT_CONSTRAINABLE>
66- struct frac_helper ;
65+ struct fract_helper ;
6766template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
6867struct mix_helper;
6968template<typename T NBL_STRUCT_CONSTRAINABLE>
@@ -123,7 +122,7 @@ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(transpose_helper, trans
123122template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (length_helper, length, (T), (T), typename vector_traits<T>::scalar_type)
124123template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (normalize_helper, normalize, (T), (T), T)
125124template<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)
127126template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (all_helper, any, (T), (T), T)
128127template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (any_helper, any, (T), (T), T)
129128template<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
212211 }
213212};
214213
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 >()))>) >
217216{
218217 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)
220229 {
221- T aAsT = a;
222- return spirv::fMix<T>(x, y, aAsT);
230+ return a ? x : y;
223231 }
224232};
225233
@@ -287,7 +295,8 @@ struct transpose_helper<Matrix>
287295
288296 static transposed_t __call (NBL_CONST_REF_ARG (Matrix) m)
289297 {
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)));
291300 }
292301};
293302template<typename Vector>
@@ -367,7 +376,7 @@ struct rsqrt_helper<FloatingPoint>
367376
368377template<typename T>
369378requires concepts::FloatingPointScalar<T>
370- struct frac_helper <T>
379+ struct fract_helper <T>
371380{
372381 using return_t = T;
373382 static inline return_t __call (const T x)
@@ -394,7 +403,8 @@ struct inverse_helper<SquareMatrix>
394403{
395404 static SquareMatrix __call (NBL_CONST_REF_ARG (SquareMatrix) mat)
396405 {
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)));
398408 }
399409};
400410
@@ -411,13 +421,13 @@ struct bitCount_helper<EnumT>
411421};
412422
413423template<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>))
415425struct mix_helper<T, U>
416426{
417427 using return_t = T;
418428 static inline return_t __call (const T x, const T y, const U a)
419429 {
420- return glm::mix (x, y, a);
430+ return glm::mix<T, U> (x, y, a);
421431 }
422432};
423433
@@ -532,15 +542,27 @@ struct refract_helper<T, U>
532542 }
533543};
534544
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+
535554template<typename T>
536555requires concepts::FloatingPoint<T>
537556struct nMin_helper<T>
538557{
539558 using return_t = T;
540559 static inline return_t __call (const T a, const T b)
541560 {
561+ using AsUint = typename unsigned_integer_of_size<sizeof (T)>::type;
562+ const bool isANaN = isnan_uint_impl (reinterpret_cast<const AsUint&>(a));
563+
542564 // comparison involving any NaN always returns false
543- return (b < a || std:: isnan (a) ) ? b : a;
565+ return (b < a || isANaN ) ? b : a;
544566 }
545567};
546568
@@ -551,8 +573,11 @@ struct nMax_helper<T>
551573 using return_t = T;
552574 static inline return_t __call (const T a, const T b)
553575 {
576+ using AsUint = typename unsigned_integer_of_size<sizeof (T)>::type;
577+ const bool isANaN = isnan_uint_impl (reinterpret_cast<const AsUint&>(a));
578+
554579 // comparison involving any NaN always returns false
555- return (a < b || std:: isnan (a) ) ? b : a;
580+ return (a < b || isANaN ) ? b : a;
556581 }
557582};
558583
@@ -729,7 +754,7 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
729754
730755AUTO_SPECIALIZE_HELPER_FOR_VECTOR (rsqrt_helper, concepts::FloatingPointVectorial<T> && VECTOR_SPECIALIZATION_CONCEPT, T)
731756AUTO_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)
733758AUTO_SPECIALIZE_HELPER_FOR_VECTOR (sign_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
734759AUTO_SPECIALIZE_HELPER_FOR_VECTOR (degrees_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
735760AUTO_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) >
816841 }
817842};
818843
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+
819865}
820866}
821867}
0 commit comments