|
15 | 15 | #include <boost/preprocessor/comparison/not_equal.hpp>
|
16 | 16 | #include <boost/preprocessor/punctuation/comma_if.hpp>
|
17 | 17 | #include <boost/preprocessor/seq/for_each_i.hpp>
|
| 18 | +#include <nbl/builtin/hlsl/spirv_intrinsics/output_structs.hlsl> |
18 | 19 |
|
19 | 20 | namespace nbl
|
20 | 21 | {
|
@@ -81,6 +82,10 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
|
81 | 82 | struct reflect_helper;
|
82 | 83 | template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
|
83 | 84 | struct refract_helper;
|
| 85 | +template<typename T NBL_STRUCT_CONSTRAINABLE> |
| 86 | +struct modfStruct_helper; |
| 87 | +template<typename T NBL_STRUCT_CONSTRAINABLE> |
| 88 | +struct frexpStruct_helper; |
84 | 89 |
|
85 | 90 | #ifdef __HLSL_VERSION // HLSL only specializations
|
86 | 91 |
|
@@ -136,6 +141,8 @@ template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(clamp_helper, sClamp, (
|
136 | 141 | template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(smoothStep_helper, smoothStep, (T), (T)(T)(T), T)
|
137 | 142 | template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(faceForward_helper, faceForward, (T), (T)(T)(T), T)
|
138 | 143 | template<typename T, typename U> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(refract_helper, refract, (T)(U), (T)(T)(U), T)
|
| 144 | +template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(modfStruct_helper, modfStruct, (T), (T), ModfOutput<T>) |
| 145 | +template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(frexpStruct_helper, frexpStruct, (T), (T), FrexpOutput<T>) |
139 | 146 |
|
140 | 147 | #define BITCOUNT_HELPER_RETRUN_TYPE conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t>
|
141 | 148 | template<typename T> AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(bitCount_helper, bitCount, (T), (T), BITCOUNT_HELPER_RETRUN_TYPE)
|
@@ -510,6 +517,34 @@ struct refract_helper<T, U>
|
510 | 517 | }
|
511 | 518 | };
|
512 | 519 |
|
| 520 | +template<typename T> |
| 521 | +requires concepts::FloatingPointScalar<T> |
| 522 | +struct modfStruct_helper<T> |
| 523 | +{ |
| 524 | + using return_t = ModfOutput<T>; |
| 525 | + static inline return_t __call(const T val) |
| 526 | + { |
| 527 | + return_t output; |
| 528 | + output.fractionalPart = std::modf(val, &output.wholeNumberPart); |
| 529 | + |
| 530 | + return output; |
| 531 | + } |
| 532 | +}; |
| 533 | + |
| 534 | +template<typename T> |
| 535 | +requires concepts::FloatingPointScalar<T> |
| 536 | +struct frexpStruct_helper<T> |
| 537 | +{ |
| 538 | + using return_t = FrexpOutput<T>; |
| 539 | + static inline return_t __call(const T val) |
| 540 | + { |
| 541 | + return_t output; |
| 542 | + output.significand = std::frexp(val, &output.exponent); |
| 543 | + |
| 544 | + return output; |
| 545 | + } |
| 546 | +}; |
| 547 | + |
513 | 548 | #endif // C++ only specializations
|
514 | 549 |
|
515 | 550 | // C++ and HLSL specializations
|
@@ -765,6 +800,67 @@ struct smoothStep_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
|
765 | 800 | }
|
766 | 801 | };
|
767 | 802 |
|
| 803 | +template<typename T> |
| 804 | +NBL_PARTIAL_REQ_TOP(VECTOR_SPECIALIZATION_CONCEPT) |
| 805 | +struct modfStruct_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) > |
| 806 | +{ |
| 807 | + using return_t = ModfOutput<T>; |
| 808 | + static return_t __call(NBL_CONST_REF_ARG(T) x) |
| 809 | + { |
| 810 | + using traits = hlsl::vector_traits<T>; |
| 811 | + array_get<T, typename traits::scalar_type> getter; |
| 812 | + array_set<T, typename traits::scalar_type> setter; |
| 813 | + |
| 814 | + T fracPartOut; |
| 815 | + T intPartOut; |
| 816 | + for (uint32_t i = 0; i < traits::Dimension; ++i) |
| 817 | + { |
| 818 | + using component_return_t = ModfOutput<typename vector_traits<T>::scalar_type>; |
| 819 | + component_return_t result = modfStruct_helper<typename traits::scalar_type>::__call(getter(x, i)); |
| 820 | + |
| 821 | + setter(fracPartOut, i, result.fractionalPart); |
| 822 | + setter(intPartOut, i, result.wholeNumberPart); |
| 823 | + } |
| 824 | + |
| 825 | + return_t output; |
| 826 | + output.fractionalPart = fracPartOut; |
| 827 | + output.wholeNumberPart = intPartOut; |
| 828 | + |
| 829 | + return output; |
| 830 | + } |
| 831 | +}; |
| 832 | + |
| 833 | +template<typename T> |
| 834 | +NBL_PARTIAL_REQ_TOP(VECTOR_SPECIALIZATION_CONCEPT) |
| 835 | +struct frexpStruct_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) > |
| 836 | +{ |
| 837 | + using return_t = FrexpOutput<T>; |
| 838 | + static return_t __call(NBL_CONST_REF_ARG(T) x) |
| 839 | + { |
| 840 | + using traits = hlsl::vector_traits<T>; |
| 841 | + array_get<T, typename traits::scalar_type> getter; |
| 842 | + array_set<T, typename traits::scalar_type> significandSetter; |
| 843 | + array_set<T, typename traits::scalar_type> exponentSetter; |
| 844 | + |
| 845 | + T significandOut; |
| 846 | + T exponentOut; |
| 847 | + for (uint32_t i = 0; i < traits::Dimension; ++i) |
| 848 | + { |
| 849 | + using component_return_t = FrexpOutput<typename vector_traits<T>::scalar_type>; |
| 850 | + component_return_t result = frexpStruct_helper<typename traits::scalar_type>::__call(getter(x, i)); |
| 851 | + |
| 852 | + significandSetter(significandOut, i, result.significand); |
| 853 | + exponentSetter(exponentOut, i, result.exponent); |
| 854 | + } |
| 855 | + |
| 856 | + return_t output; |
| 857 | + output.significand = significandOut; |
| 858 | + output.exponent = exponentOut; |
| 859 | + |
| 860 | + return output; |
| 861 | + } |
| 862 | +}; |
| 863 | + |
768 | 864 | }
|
769 | 865 | }
|
770 | 866 | }
|
|
0 commit comments