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