1+ #ifndef _NBL_BUILTIN_HLSL_CPP_COMPAT_IMPL_INTRINSICS_IMPL_INCLUDED_
2+ #define _NBL_BUILTIN_HLSL_CPP_COMPAT_IMPL_INTRINSICS_IMPL_INCLUDED_
3+
4+ namespace nbl
5+ {
6+ namespace hlsl
7+ {
8+ namespace cpp_compat_intrinsics_impl
9+ {
10+ template<typename T>
11+ struct dot_helper
12+ {
13+ using scalar_type = typename vector_traits<T>::scalar_type;
14+
15+ static inline scalar_type dot (NBL_CONST_REF_ARG (T) lhs, NBL_CONST_REF_ARG (T) rhs)
16+ {
17+ static array_get<T, scalar_type> getter;
18+ scalar_type retval = getter (lhs, 0 ) * getter (rhs, 0 );
19+
20+ static const uint32_t ArrayDim = sizeof (T) / sizeof (scalar_type);
21+ for (uint32_t i = 1 ; i < ArrayDim; ++i)
22+ retval = retval + getter (lhs, i) * getter (rhs, i);
23+
24+ return retval;
25+ }
26+ };
27+
28+ #define DEFINE_BUILTIN_VECTOR_SPECIALIZATION (FLOAT_TYPE, RETURN_VALUE)\
29+ template<uint32_t N>\
30+ struct dot_helper<vector <FLOAT_TYPE, N> >\
31+ {\
32+ using VectorType = vector <FLOAT_TYPE, N>;\
33+ using ScalarType = typename vector_traits<VectorType>::scalar_type;\
34+ \
35+ static inline ScalarType dot (NBL_CONST_REF_ARG (VectorType) lhs, NBL_CONST_REF_ARG (VectorType) rhs)\
36+ {\
37+ return RETURN_VALUE;\
38+ }\
39+ };\
40+
41+ #ifdef __HLSL_VERSION
42+ #define BUILTIN_VECTOR_SPECIALIZATION_RET_VAL dot (lhs, rhs)
43+ #else
44+ #define BUILTIN_VECTOR_SPECIALIZATION_RET_VAL glm::dot (lhs, rhs)
45+ #endif
46+
47+ DEFINE_BUILTIN_VECTOR_SPECIALIZATION (float16_t, BUILTIN_VECTOR_SPECIALIZATION_RET_VAL)
48+ DEFINE_BUILTIN_VECTOR_SPECIALIZATION (float32_t, BUILTIN_VECTOR_SPECIALIZATION_RET_VAL)
49+ DEFINE_BUILTIN_VECTOR_SPECIALIZATION (float64_t, BUILTIN_VECTOR_SPECIALIZATION_RET_VAL)
50+
51+ #undef BUILTIN_VECTOR_SPECIALIZATION_RET_VAL
52+ #undef DEFINE_BUILTIN_VECTOR_SPECIALIZATION
53+
54+ #ifdef __HLSL_VERSION
55+ template<typename Integer>
56+ struct find_msb_helper;
57+ #else
58+ // legacy code wouldn't work without it
59+ template<typename Integer>
60+ struct find_msb_helper
61+ {
62+ static int findMSB (NBL_CONST_REF_ARG (Integer) val)
63+ {
64+ if (is_signed_v<Integer>)
65+ {
66+ // GLM accepts only integer types, so idea is to cast input to integer type
67+ using as_int = typename integer_of_size<sizeof (Integer)>::type;
68+ const as_int valAsInt = reinterpret_cast<const as_int&>(val);
69+ return glm::findMSB (valAsInt);
70+ }
71+ else
72+ {
73+ // GLM accepts only integer types, so idea is to cast input to integer type
74+ using as_uint = typename unsigned_integer_of_size<sizeof (Integer)>::type;
75+ const as_uint valAsUnsignedInt = reinterpret_cast<const as_uint&>(val);
76+ return glm::findMSB (valAsUnsignedInt);
77+ }
78+ }
79+ };
80+ #endif
81+
82+ template<>
83+ struct find_msb_helper<uint32_t>
84+ {
85+ static int32_t findMSB (NBL_CONST_REF_ARG (uint32_t) val)
86+ {
87+ #ifdef __HLSL_VERSION
88+ return spirv::findUMsb (val);
89+ #else
90+ return glm::findMSB (val);
91+ #endif
92+ }
93+ };
94+
95+ template<>
96+ struct find_msb_helper<int32_t>
97+ {
98+ static int32_t findMSB (NBL_CONST_REF_ARG (int32_t) val)
99+ {
100+ #ifdef __HLSL_VERSION
101+ return spirv::findSMsb (val);
102+ #else
103+ return glm::findMSB (val);
104+ #endif
105+ }
106+ };
107+
108+ template<int N>
109+ struct find_msb_helper<vector <uint32_t, N> >
110+ {
111+ static vector <int32_t, N> findMSB (NBL_CONST_REF_ARG (vector <uint32_t, N>) val)
112+ {
113+ #ifdef __HLSL_VERSION
114+ return spirv::findUMsb (val);
115+ #else
116+ return glm::findMSB (val);
117+ #endif
118+ }
119+ };
120+
121+ template<int N>
122+ struct find_msb_helper<vector <int32_t, N> >
123+ {
124+ static vector <int32_t, N> findMSB (NBL_CONST_REF_ARG (vector <int32_t, N>) val)
125+ {
126+ #ifdef __HLSL_VERSION
127+ return spirv::findSMsb (val);
128+ #else
129+ return glm::findMSB (val);
130+ #endif
131+ }
132+ };
133+
134+ #ifdef __HLSL_VERSION
135+ template<typename Integer>
136+ struct find_lsb_helper;
137+ #else
138+ // legacy code wouldn't work without it
139+ template<typename Integer>
140+ struct find_lsb_helper
141+ {
142+ static int32_t findLSB (NBL_CONST_REF_ARG (Integer) val)
143+ {
144+ #ifdef __HLSL_VERSION
145+ return spirv::findILsb (val);
146+ #else
147+ if (is_signed_v<Integer>)
148+ {
149+ // GLM accepts only integer types, so idea is to cast input to integer type
150+ using as_int = typename integer_of_size<sizeof (Integer)>::type;
151+ const as_int valAsInt = reinterpret_cast<const as_int&>(val);
152+ return glm::findLSB (valAsInt);
153+ }
154+ else
155+ {
156+ // GLM accepts only integer types, so idea is to cast input to integer type
157+ using as_uint = typename unsigned_integer_of_size<sizeof (Integer)>::type;
158+ const as_uint valAsUnsignedInt = reinterpret_cast<const as_uint&>(val);
159+ return glm::findLSB (valAsUnsignedInt);
160+ }
161+ #endif
162+ }
163+ };
164+ #endif
165+
166+ template<>
167+ struct find_lsb_helper<int32_t>
168+ {
169+ static int32_t findLSB (NBL_CONST_REF_ARG (int32_t) val)
170+ {
171+ #ifdef __HLSL_VERSION
172+ return spirv::findILsb (val);
173+ #else
174+ return glm::findLSB (val);
175+ #endif
176+ }
177+ };
178+
179+ template<>
180+ struct find_lsb_helper<uint32_t>
181+ {
182+ static int32_t findLSB (NBL_CONST_REF_ARG (uint32_t) val)
183+ {
184+ #ifdef __HLSL_VERSION
185+ return spirv::findILsb (val);
186+ #else
187+ return glm::findLSB (val);
188+ #endif
189+ }
190+ };
191+
192+ template<int N>
193+ struct find_lsb_helper<vector <int32_t, N> >
194+ {
195+ static vector <int32_t, N> findLSB (NBL_CONST_REF_ARG (vector <int32_t, N>) val)
196+ {
197+ #ifdef __HLSL_VERSION
198+ return spirv::findILsb (val);
199+ #else
200+ return glm::findLSB (val);
201+ #endif
202+ }
203+ };
204+
205+ template<int N>
206+ struct find_lsb_helper<vector <uint32_t, N> >
207+ {
208+ static vector <int32_t, N> findLSB (NBL_CONST_REF_ARG (vector <uint32_t, N>) val)
209+ {
210+ #ifdef __HLSL_VERSION
211+ return spirv::findILsb (val);
212+ #else
213+ return glm::findLSB (val);
214+ #endif
215+ }
216+ };
217+
218+ template<typename Integer>
219+ struct find_msb_return_type
220+ {
221+ using type = int32_t;
222+ };
223+ template<typename Integer, int N>
224+ struct find_msb_return_type<vector <Integer, N> >
225+ {
226+ using type = vector <int32_t, N>;
227+ };
228+ template<typename Integer>
229+ using find_lsb_return_type = find_msb_return_type<Integer>;
230+
231+ template<typename T, typename U>
232+ struct lerp_helper;
233+
234+ #ifdef __HLSL_VERSION
235+ #define MIX_FUNCTION spirv::fMix
236+ #else
237+ #define MIX_FUNCTION glm::mix
238+ #endif
239+
240+ #define DEFINE_LERP_HELPER_COMMON_SPECIALIZATION (TYPE)\
241+ template<>\
242+ struct lerp_helper<TYPE, TYPE>\
243+ {\
244+ static inline TYPE lerp (NBL_CONST_REF_ARG (TYPE) x, NBL_CONST_REF_ARG (TYPE) y, NBL_CONST_REF_ARG (TYPE) a)\
245+ {\
246+ return MIX_FUNCTION (x, y, a);\
247+ }\
248+ };\
249+ \
250+ template<int N>\
251+ struct lerp_helper<vector <TYPE, N>, vector <TYPE, N> >\
252+ {\
253+ static inline vector <TYPE, N> lerp (NBL_CONST_REF_ARG (vector <TYPE, N>) x, NBL_CONST_REF_ARG (vector <TYPE, N>) y, NBL_CONST_REF_ARG (vector <TYPE, N>) a)\
254+ {\
255+ return MIX_FUNCTION (x, y, a);\
256+ }\
257+ };\
258+ \
259+ template<int N>\
260+ struct lerp_helper<vector <TYPE, N>, TYPE>\
261+ {\
262+ static inline vector <TYPE, N> lerp (NBL_CONST_REF_ARG (vector <TYPE, N>) x, NBL_CONST_REF_ARG (vector <TYPE, N>) y, NBL_CONST_REF_ARG (TYPE) a)\
263+ {\
264+ return MIX_FUNCTION (x, y, a);\
265+ }\
266+ };\
267+
268+ DEFINE_LERP_HELPER_COMMON_SPECIALIZATION (float32_t)
269+ DEFINE_LERP_HELPER_COMMON_SPECIALIZATION (float64_t)
270+
271+ #undef DEFINE_LERP_HELPER_COMMON_SPECIALIZATION
272+ #undef MIX_FUNCTION
273+
274+ template<typename T>
275+ struct lerp_helper<T, bool >
276+ {
277+ static inline T lerp (NBL_CONST_REF_ARG (T) x, NBL_CONST_REF_ARG (T) y, NBL_CONST_REF_ARG (bool ) a)
278+ {
279+ return a ? y : x;
280+ }
281+ };
282+
283+ template<typename T, int N>
284+ struct lerp_helper<vector <T, N>, vector <bool , N> >
285+ {
286+ using output_vec_t = vector <T, N>;
287+
288+ static inline output_vec_t lerp (NBL_CONST_REF_ARG (output_vec_t) x, NBL_CONST_REF_ARG (output_vec_t) y, NBL_CONST_REF_ARG (vector <bool , N>) a)
289+ {
290+ output_vec_t retval;
291+ for (uint32_t i = 0 ; i < vector_traits<output_vec_t>::Dimension; i++)
292+ retval[i] = a[i] ? y[i] : x[i];
293+ return retval;
294+ }
295+ };
296+
297+ }
298+ }
299+ }
300+
301+ #endif
0 commit comments