Skip to content

Commit 3d3d31f

Browse files
committed
Added more intrinsics.hlsl functions
1 parent 2f781b8 commit 3d3d31f

File tree

4 files changed

+305
-16
lines changed

4 files changed

+305
-16
lines changed

include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl

Lines changed: 217 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <nbl/builtin/hlsl/concepts/vector.hlsl>
1212
#include <nbl/builtin/hlsl/concepts/matrix.hlsl>
1313
#include <nbl/builtin/hlsl/cpp_compat/promote.hlsl>
14+
#include <nbl/builtin/hlsl/numbers.hlsl>
1415

1516
namespace nbl
1617
{
@@ -61,6 +62,22 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
6162
struct frac_helper;
6263
template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
6364
struct mix_helper;
65+
template<typename T NBL_STRUCT_CONSTRAINABLE>
66+
struct sign_helper;
67+
template<typename T NBL_STRUCT_CONSTRAINABLE>
68+
struct radians_helper;
69+
template<typename T NBL_STRUCT_CONSTRAINABLE>
70+
struct degrees_helper;
71+
template<typename T NBL_STRUCT_CONSTRAINABLE>
72+
struct step_helper;
73+
template<typename T NBL_STRUCT_CONSTRAINABLE>
74+
struct smoothStep_helper;
75+
template<typename T NBL_STRUCT_CONSTRAINABLE>
76+
struct faceForward_helper;
77+
template<typename T NBL_STRUCT_CONSTRAINABLE>
78+
struct reflect_helper;
79+
template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
80+
struct refract_helper;
6481

6582
#ifdef __HLSL_VERSION // HLSL only specializations
6683

@@ -91,6 +108,10 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(frac_helper, fract, T)
91108
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(inverse_helper, matrixInverse, T)
92109
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(all_helper, any, T)
93110
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(any_helper, any, T)
111+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(sign_helper, fSign, T)
112+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(sign_helper, sSign, T)
113+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(radians_helper, radians, T)
114+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(degrees_helper, degrees, T)
94115

95116
#define BITCOUNT_HELPER_RETRUN_TYPE conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t>
96117
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(bitCount_helper, bitCount, BITCOUNT_HELPER_RETRUN_TYPE)
@@ -115,6 +136,9 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC(max_helper, sMax, T)
115136
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC(min_helper, fMin, T)
116137
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC(min_helper, uMin, T)
117138
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC(min_helper, sMin, T)
139+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC(step_helper, step, T)
140+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC(reflect_helper, reflect, T)
141+
118142
#undef AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC
119143

120144
template<typename T> NBL_PARTIAL_REQ_TOP(always_true<decltype(spirv::fClamp<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>)
@@ -205,7 +229,47 @@ struct mix_helper<T, U NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::fMix<T>(e
205229
using return_t = conditional_t<is_vector_v<T>, vector<typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>;
206230
static inline return_t __call(const T x, const T y, const U a)
207231
{
208-
return spirv::fMix<T>(x, y, a);
232+
T aAsT = a;
233+
return spirv::fMix<T>(x, y, aAsT);
234+
}
235+
};
236+
237+
template<typename T> NBL_PARTIAL_REQ_TOP(always_true<decltype(spirv::smoothStep<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>)
238+
struct smoothStep_helper<T NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::smoothStep<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>) >
239+
{
240+
using return_t = T;
241+
static inline return_t __call(const T edge0, const T edge1, const T x)
242+
{
243+
return spirv::smoothStep<T>(edge0, edge1, x);
244+
}
245+
};
246+
247+
template<typename T> NBL_PARTIAL_REQ_TOP(always_true<decltype(spirv::faceForward<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>)
248+
struct faceForward_helper<T NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::faceForward<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>) >
249+
{
250+
using return_t = T;
251+
static inline return_t __call(const T N, const T I, const T Nref)
252+
{
253+
return spirv::faceForward<T>(N, I, Nref);
254+
}
255+
};
256+
257+
template<typename SquareMatrix> NBL_PARTIAL_REQ_TOP(matrix_traits<SquareMatrix>::Square)
258+
struct determinant_helper<SquareMatrix NBL_PARTIAL_REQ_BOT(matrix_traits<SquareMatrix>::Square) >
259+
{
260+
static typename matrix_traits<SquareMatrix>::scalar_type __call(NBL_CONST_REF_ARG(SquareMatrix) mat)
261+
{
262+
return spirv::determinant(mat);
263+
}
264+
};
265+
266+
template<typename T, typename U> NBL_PARTIAL_REQ_TOP(always_true<decltype(spirv::refract<T, U>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U>()))>)
267+
struct refract_helper<T, U NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::refract<T, U>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U>()))>) >
268+
{
269+
using return_t = T;
270+
static inline return_t __call(const T I, const T N, const U eta)
271+
{
272+
return spirv::refract<T>(I, N, eta);
209273
}
210274
};
211275

@@ -388,6 +452,117 @@ struct mix_helper<T, U>
388452
}
389453
};
390454

455+
template<typename T>
456+
requires concepts::FloatingPointScalar<T> || concepts::IntegralScalar<T>
457+
struct sign_helper<T>
458+
{
459+
using return_t = T;
460+
static inline return_t __call(const T val)
461+
{
462+
if (val < 0)
463+
return -1;
464+
if (val > 0)
465+
return 1;
466+
467+
return 0;
468+
}
469+
};
470+
471+
template<typename T>
472+
requires concepts::FloatingPointScalar<T>
473+
struct radians_helper<T>
474+
{
475+
using return_t = T;
476+
static inline return_t __call(const T degrees)
477+
{
478+
return degrees * (numbers::pi<T> / static_cast<T>(180.0));
479+
}
480+
};
481+
482+
template<typename T>
483+
requires concepts::FloatingPointScalar<T>
484+
struct degrees_helper<T>
485+
{
486+
using return_t = T;
487+
static inline return_t __call(const T radians)
488+
{
489+
return radians * (static_cast<T>(180.0) / numbers::pi<T>);
490+
}
491+
};
492+
493+
template<typename T>
494+
requires concepts::FloatingPointScalar<T>
495+
struct step_helper<T>
496+
{
497+
using return_t = T;
498+
static inline return_t __call(const T edge, const T x)
499+
{
500+
return x < edge ? 0.0 : 1.0;
501+
}
502+
};
503+
504+
template<typename T>
505+
requires concepts::FloatingPointScalar<T>
506+
struct smoothStep_helper<T>
507+
{
508+
using return_t = T;
509+
static inline return_t __call(const T edge0, const T edge1, const T x)
510+
{
511+
T t = clamp_helper<T>::__call((x - edge0) / (edge1 - edge0), 0, 1);
512+
return t * t * (3 - 2 * t);
513+
}
514+
};
515+
516+
template<typename SquareMatrix>
517+
NBL_PARTIAL_REQ_TOP(matrix_traits<SquareMatrix>::Square)
518+
struct determinant_helper<SquareMatrix NBL_PARTIAL_REQ_BOT(matrix_traits<SquareMatrix>::Square) >
519+
{
520+
static typename matrix_traits<SquareMatrix>::scalar_type __call(NBL_CONST_REF_ARG(SquareMatrix) mat)
521+
{
522+
return glm::determinant(reinterpret_cast<typename SquareMatrix::Base const&>(mat));
523+
}
524+
};
525+
526+
template<typename T>
527+
requires concepts::FloatingPointVectorial<T>
528+
struct faceForward_helper<T>
529+
{
530+
using return_t = T;
531+
static inline return_t __call(const T N, const T I, const T Nref)
532+
{
533+
if (dot_helper<T>::__call(Nref, I) < 0.0)
534+
return N;
535+
else
536+
return -N;
537+
}
538+
};
539+
540+
template<typename T>
541+
requires concepts::FloatingPointVector<T>
542+
struct reflect_helper<T>
543+
{
544+
using return_t = T;
545+
static inline return_t __call(const T I, const T N)
546+
{
547+
return I - T(2.0 * dot_helper<T>::__call(N, I)) * N;
548+
}
549+
};
550+
551+
template<typename T, typename U>
552+
requires concepts::FloatingPointVector<T> && concepts::FloatingPointScalar<U>
553+
struct refract_helper<T, U>
554+
{
555+
using return_t = T;
556+
static inline return_t __call(const T I, const T N, const U eta)
557+
{
558+
U k = 1.0 - eta * eta * (1.0 - dot_helper<T>::__call(N, I) * dot_helper<T>::__call(N, I));
559+
if (k < 0.0)
560+
return T(0.0);
561+
562+
return eta * I - (eta * dot_helper<T>::__call(N, I) + std::sqrt(k)) * N;
563+
}
564+
};
565+
391566
#endif // C++ only specializations
392567

393568
// C++ and HLSL specializations
@@ -535,20 +710,6 @@ struct mul_helper<LhsT, RhsT NBL_PARTIAL_REQ_BOT(concepts::Matrix<LhsT> && conce
535710
}
536711
};
537712

538-
template<typename SquareMatrix>
539-
NBL_PARTIAL_REQ_TOP(matrix_traits<SquareMatrix>::Square)
540-
struct determinant_helper<SquareMatrix NBL_PARTIAL_REQ_BOT(matrix_traits<SquareMatrix>::Square) >
541-
{
542-
static typename matrix_traits<SquareMatrix>::scalar_type __call(NBL_CONST_REF_ARG(SquareMatrix) mat)
543-
{
544-
#ifdef __HLSL_VERSION
545-
return spirv::determinant(mat);
546-
#else
547-
return glm::determinant(reinterpret_cast<typename SquareMatrix::Base const&>(mat));
548-
#endif
549-
}
550-
};
551-
552713
#define AUTO_SPECIALIZE_HELPER_FOR_VECTOR(HELPER_NAME, REQUIREMENT, RETURN_TYPE)\
553714
template<typename T>\
554715
NBL_PARTIAL_REQ_TOP(REQUIREMENT)\
@@ -573,6 +734,9 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
573734
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(rsqrt_helper, concepts::FloatingPointVectorial<T> && VECTOR_SPECIALIZATION_CONCEPT, T)
574735
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(bitReverse_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
575736
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(frac_helper, VECTOR_SPECIALIZATION_CONCEPT,T)
737+
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(sign_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
738+
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(degrees_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
739+
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(radians_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
576740
#define INT32_VECTOR_TYPE vector<int32_t, hlsl::vector_traits<T>::Dimension>
577741
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(bitCount_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
578742
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(find_msb_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
@@ -616,6 +780,44 @@ struct any_helper<BooleanVector NBL_PARTIAL_REQ_BOT(concepts::Vectorial<BooleanV
616780
}
617781
};
618782

783+
template<typename T>
784+
NBL_PARTIAL_REQ_TOP(VECTOR_SPECIALIZATION_CONCEPT)
785+
struct step_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
786+
{
787+
using return_t = T;
788+
static return_t __call(NBL_CONST_REF_ARG(T) edge, NBL_CONST_REF_ARG(T) x)
789+
{
790+
using traits = hlsl::vector_traits<T>;
791+
array_get<T, typename traits::scalar_type> getter;
792+
array_set<return_t, typename traits::scalar_type> setter;
793+
794+
return_t output;
795+
for (uint32_t i = 0; i < traits::Dimension; ++i)
796+
setter(output, i, step_helper<typename traits::scalar_type>::__call(getter(edge, i), getter(x, i)));
797+
798+
return output;
799+
}
800+
};
801+
802+
template<typename T>
803+
NBL_PARTIAL_REQ_TOP(VECTOR_SPECIALIZATION_CONCEPT)
804+
struct smoothStep_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
805+
{
806+
using return_t = T;
807+
static return_t __call(NBL_CONST_REF_ARG(T) edge0, NBL_CONST_REF_ARG(T) edge1, NBL_CONST_REF_ARG(T) x)
808+
{
809+
using traits = hlsl::vector_traits<T>;
810+
array_get<T, typename traits::scalar_type> getter;
811+
array_set<return_t, typename traits::scalar_type> setter;
812+
813+
return_t output;
814+
for (uint32_t i = 0; i < traits::Dimension; ++i)
815+
setter(output, i, smoothStep_helper<typename traits::scalar_type>::__call(getter(edge0, i), getter(edge1, i), getter(x, i)));
816+
817+
return output;
818+
}
819+
};
820+
619821
}
620822
}
621823
}

include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,57 @@ inline T mix(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U
183183
return cpp_compat_intrinsics_impl::mix_helper<T, U>::__call(x, y, a);
184184
}
185185

186+
template<typename T>
187+
inline T sign(NBL_CONST_REF_ARG(T) val)
188+
{
189+
return cpp_compat_intrinsics_impl::sign_helper<T>::__call(val);
190+
}
191+
192+
template<typename T>
193+
inline T radians(NBL_CONST_REF_ARG(T) degrees)
194+
{
195+
return cpp_compat_intrinsics_impl::radians_helper<T>::__call(degrees);
196+
}
197+
198+
template<typename T>
199+
inline T degrees(NBL_CONST_REF_ARG(T) radians)
200+
{
201+
return cpp_compat_intrinsics_impl::degrees_helper<T>::__call(radians);
202+
}
203+
204+
template<typename T>
205+
inline T step(NBL_CONST_REF_ARG(T) edge, NBL_CONST_REF_ARG(T) x)
206+
{
207+
return cpp_compat_intrinsics_impl::step_helper<T>::__call(edge, x);
208+
}
209+
210+
template<typename T>
211+
inline T smoothStep(NBL_CONST_REF_ARG(T) edge0, NBL_CONST_REF_ARG(T) edge1, NBL_CONST_REF_ARG(T) x)
212+
{
213+
return cpp_compat_intrinsics_impl::smoothStep_helper<T>::__call(edge0, edge1, x);
214+
}
215+
216+
template<typename T>
217+
inline T faceForward(NBL_CONST_REF_ARG(T) N, NBL_CONST_REF_ARG(T) I, NBL_CONST_REF_ARG(T) Nref)
218+
{
219+
return cpp_compat_intrinsics_impl::faceForward_helper<T>::__call(N, I, Nref);
220+
}
221+
222+
template<typename T>
223+
inline T reflect(NBL_CONST_REF_ARG(T) I, NBL_CONST_REF_ARG(T) N)
224+
{
225+
return cpp_compat_intrinsics_impl::reflect_helper<T>::__call(I, N);
226+
}
227+
228+
template<typename T, typename U>
229+
inline T refract(NBL_CONST_REF_ARG(T) I, NBL_CONST_REF_ARG(T) N, NBL_CONST_REF_ARG(U) eta)
230+
{
231+
return cpp_compat_intrinsics_impl::refract_helper<T, U>::__call(I, N, eta);
232+
}
233+
234+
// TODO: implement
235+
//pack and unpack intrinsics
236+
186237
}
187238
}
188239

include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,42 @@ template<typename T, typename U NBL_FUNC_REQUIRES(concepts::FloatingPointVectorO
198198
[[vk::ext_instruction(GLSLstd450Ldexp, "GLSL.std.450")]]
199199
T ldexp(T arg, U exp);
200200

201+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
202+
[[vk::ext_instruction(GLSLstd450FSign, "GLSL.std.450")]]
203+
T fSign(T val);
204+
205+
template<typename T NBL_FUNC_REQUIRES(concepts::IntegralVectorOrScalar<T>)
206+
[[vk::ext_instruction(GLSLstd450SSign, "GLSL.std.450")]]
207+
T sSign(T val);
208+
209+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar32or16BitSize<T>)
210+
[[vk::ext_instruction(GLSLstd450Radians, "GLSL.std.450")]]
211+
T radians(T degrees);
212+
213+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar32or16BitSize<T>)
214+
[[vk::ext_instruction(GLSLstd450Degrees, "GLSL.std.450")]]
215+
T degrees(T radians);
216+
217+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
218+
[[vk::ext_instruction(GLSLstd450Step, "GLSL.std.450")]]
219+
T step(T edge, T x);
220+
221+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
222+
[[vk::ext_instruction(GLSLstd450SmoothStep, "GLSL.std.450")]]
223+
T smoothStep(T edge0, T edge1, T x);
224+
225+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
226+
[[vk::ext_instruction(GLSLstd450FaceForward, "GLSL.std.450")]]
227+
T faceForward(T N, T I, T Nref);
228+
229+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
230+
[[vk::ext_instruction(GLSLstd450Reflect, "GLSL.std.450")]]
231+
T reflect(T I, T N);
232+
233+
template<typename T, typename U NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
234+
[[vk::ext_instruction(GLSLstd450Refract, "GLSL.std.450")]]
235+
T refract(T I, T N, U Nref);
236+
201237
}
202238
}
203239
}

0 commit comments

Comments
 (0)