Skip to content

Commit 2f781b8

Browse files
committed
Added more tgmath functions
1 parent c95d042 commit 2f781b8

File tree

7 files changed

+223
-34
lines changed

7 files changed

+223
-34
lines changed

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

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ template<typename T, uint16_t Bits NBL_STRUCT_CONSTRAINABLE>
5959
struct bitReverseAs_helper;
6060
template<typename T NBL_STRUCT_CONSTRAINABLE>
6161
struct frac_helper;
62+
template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
63+
struct mix_helper;
6264

6365
#ifdef __HLSL_VERSION // HLSL only specializations
6466

@@ -197,6 +199,16 @@ struct inverse_helper<SquareMatrix NBL_PARTIAL_REQ_BOT(concepts::Matrix<SquareMa
197199
}
198200
};
199201

202+
template<typename T, typename U> NBL_PARTIAL_REQ_TOP(always_true<decltype(spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U>()))>)
203+
struct mix_helper<T, U NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U>()))>) >
204+
{
205+
using return_t = conditional_t<is_vector_v<T>, vector<typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>;
206+
static inline return_t __call(const T x, const T y, const U a)
207+
{
208+
return spirv::fMix<T>(x, y, a);
209+
}
210+
};
211+
200212
#else // C++ only specializations
201213

202214
template<typename T>
@@ -365,6 +377,17 @@ struct bitCount_helper<EnumT>
365377
}
366378
};
367379

380+
template<typename T, typename U>
381+
requires concepts::FloatingPoint<T> && (concepts::FloatingPoint<T> || concepts::Boolean<T>)
382+
struct mix_helper<T, U>
383+
{
384+
using return_t = T;
385+
static inline return_t __call(const T x, const T y, const U a)
386+
{
387+
return glm::mix(x, y, a);
388+
}
389+
};
390+
368391
#endif // C++ only specializations
369392

370393
// C++ and HLSL specializations
@@ -487,21 +510,21 @@ struct max_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
487510
};
488511

489512
template<typename LhsT, typename RhsT>
490-
NBL_PARTIAL_REQ_TOP(concepts::Matrix<LhsT> && concepts::Vector<RhsT>)
491-
struct mul_helper<LhsT, RhsT NBL_PARTIAL_REQ_BOT(concepts::Matricial<LhsT>&& concepts::Vectorial<RhsT>) >
513+
NBL_PARTIAL_REQ_TOP(concepts::Matrix<LhsT> && concepts::Vector<RhsT> && (matrix_traits<LhsT>::ColumnCount == vector_traits<RhsT>::Dimension))
514+
struct mul_helper<LhsT, RhsT NBL_PARTIAL_REQ_BOT(concepts::Matricial<LhsT> && concepts::Vectorial<RhsT> && (matrix_traits<LhsT>::column_count == vector_traits<RhsT>::Dimension)) >
492515
{
493516
using lhs_traits = matrix_traits<LhsT>;
494517
using rhs_traits = vector_traits<RhsT>;
495-
using return_t = matrix<typename lhs_traits::scalar_type, lhs_traits::RowCount, rhs_traits::Dimension>;
518+
using return_t = vector<typename lhs_traits::scalar_type, lhs_traits::RowCount>;
496519
static inline return_t __call(LhsT lhs, RhsT rhs)
497520
{
498521
return mul(lhs, rhs);
499522
}
500523
};
501524

502525
template<typename LhsT, typename RhsT>
503-
NBL_PARTIAL_REQ_TOP(concepts::Matrix<LhsT>&& concepts::Matrix<RhsT>)
504-
struct mul_helper<LhsT, RhsT NBL_PARTIAL_REQ_BOT(concepts::Matrix<LhsT>&& concepts::Matrix<RhsT>) >
526+
NBL_PARTIAL_REQ_TOP(concepts::Matrix<LhsT> && concepts::Matrix<RhsT> && (matrix_traits<LhsT>::ColumnCount == matrix_traits<RhsT>::RowCount))
527+
struct mul_helper<LhsT, RhsT NBL_PARTIAL_REQ_BOT(concepts::Matrix<LhsT> && concepts::Matrix<RhsT> && (matrix_traits<LhsT>::ColumnCount == matrix_traits<RhsT>::RowCount)) >
505528
{
506529
using lhs_traits = matrix_traits<LhsT>;
507530
using rhs_traits = matrix_traits<RhsT>;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ inline T frac(NBL_CONST_REF_ARG(T) val)
177177
return cpp_compat_intrinsics_impl::frac_helper<T>::__call(val);
178178
}
179179

180+
template<typename T, typename U>
181+
inline T mix(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a)
182+
{
183+
return cpp_compat_intrinsics_impl::mix_helper<T, U>::__call(x, y, a);
184+
}
185+
180186
}
181187
}
182188

include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl

Lines changed: 126 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,20 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
6565
struct acos_helper;
6666
template<typename T NBL_STRUCT_CONSTRAINABLE>
6767
struct sqrt_helper;
68-
template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
69-
struct mix_helper;
7068
template<typename T NBL_STRUCT_CONSTRAINABLE>
7169
struct modf_helper;
70+
template<typename T NBL_STRUCT_CONSTRAINABLE>
71+
struct round_helper;
72+
template<typename T NBL_STRUCT_CONSTRAINABLE>
73+
struct roundEven_helper;
74+
template<typename T NBL_STRUCT_CONSTRAINABLE>
75+
struct trunc_helper;
76+
template<typename T NBL_STRUCT_CONSTRAINABLE>
77+
struct ceil_helper;
78+
template<typename T NBL_STRUCT_CONSTRAINABLE>
79+
struct fma_helper;
80+
template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
81+
struct ldexp_helper;
7282

7383
#ifdef __HLSL_VERSION
7484

@@ -104,6 +114,11 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(log2_helper, log2, T)
104114
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(exp2_helper, exp2, T)
105115
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(exp_helper, exp, T)
106116
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(floor_helper, floor, T)
117+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(round_helper, round, T)
118+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(roundEven_helper, roundEven, T)
119+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(trunc_helper, trunc, T)
120+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(ceil_helper, ceil, T)
121+
107122
#define ISINF_AND_ISNAN_RETURN_TYPE conditional_t<is_vector_v<T>, vector<bool, vector_traits<T>::Dimension>, bool>
108123
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(isinf_helper, isInf, ISINF_AND_ISNAN_RETURN_TYPE)
109124
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(isnan_helper, isNan, ISINF_AND_ISNAN_RETURN_TYPE)
@@ -120,16 +135,6 @@ struct pow_helper<T NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::pow<T>(exper
120135
}
121136
};
122137

123-
template<typename T, typename U> NBL_PARTIAL_REQ_TOP(always_true<decltype(spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U>()))>)
124-
struct mix_helper<T, U NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U>()))>) >
125-
{
126-
using return_t = conditional_t<is_vector_v<T>, vector<typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>;
127-
static inline return_t __call(const T x, const T y, const U a)
128-
{
129-
return spirv::fMix<T>(x, y, a);
130-
}
131-
};
132-
133138
template<typename T> NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<T>)
134139
struct modf_helper<T NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<T>) >
135140
{
@@ -186,6 +191,26 @@ struct erf_helper<FloatingPoint NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScala
186191
}
187192
};
188193

194+
template<typename T> NBL_PARTIAL_REQ_TOP(always_true<decltype(spirv::fma<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>)
195+
struct fma_helper<T NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::fma<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>) >
196+
{
197+
using return_t = T;
198+
static inline return_t __call(const T x, const T y, const T z)
199+
{
200+
return spirv::fma<T>(x, y, z);
201+
}
202+
};
203+
204+
template<typename T, typename U> NBL_PARTIAL_REQ_TOP(always_true<decltype(spirv::ldexp<T>(experimental::declval<T>(), experimental::declval<U>()))>)
205+
struct ldexp_helper<T, U NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::ldexp<T>(experimental::declval<T>(), experimental::declval<U>()))>) >
206+
{
207+
using return_t = T;
208+
static inline return_t __call(const T arg, const U exp)
209+
{
210+
return spirv::ldexp<T, U>(arg, exp);
211+
}
212+
};
213+
189214
#else // C++ only specializations
190215

191216

@@ -212,6 +237,11 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(log2_helper, concepts::FloatingPointScalar<T
212237
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(exp2_helper, concepts::Scalar<T>, exp2, T)
213238
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(exp_helper, concepts::Scalar<T>, exp, T)
214239
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(floor_helper, concepts::FloatingPointScalar<T>, floor, T)
240+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(round_helper, concepts::FloatingPointScalar<T>, round, T)
241+
// TODO: uncomment when C++23
242+
//AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(roundEven_helper, concepts::FloatingPointScalar<T>, roundeven, T)
243+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(trunc_helper, concepts::FloatingPointScalar<T>, trunc, T)
244+
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(ceil_helper, concepts::FloatingPointScalar<T>, ceil, T)
215245
#undef AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER
216246

217247
template<typename T>
@@ -265,24 +295,54 @@ struct isnan_helper<T>
265295
}
266296
};
267297

268-
template<typename T, typename U>
269-
requires concepts::FloatingPoint<T> && (concepts::FloatingPoint<T> || concepts::Boolean<T>)
270-
struct mix_helper<T, U>
298+
template<typename FloatingPoint>
299+
NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<FloatingPoint>)
300+
struct erf_helper<FloatingPoint NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<FloatingPoint>) >
271301
{
272-
using return_t = T;
273-
static inline return_t __call(const T x, const T y, const U a)
274-
{
275-
return glm::mix(x, y ,a);
302+
static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x)
303+
{
304+
return std::erf<FloatingPoint>(x);
276305
}
277306
};
278307

308+
// TODO: remove when C++23
279309
template<typename FloatingPoint>
280310
NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<FloatingPoint>)
281-
struct erf_helper<FloatingPoint NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<FloatingPoint>) >
311+
struct roundEven_helper<FloatingPoint NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<FloatingPoint>) >
282312
{
283313
static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x)
284314
{
285-
return std::erf<FloatingPoint>(x);
315+
// TODO: no way this is optimal, find a better implementation
316+
float tmp;
317+
if (std::abs(std::modf(x, &tmp)) == 0.5f)
318+
{
319+
int32_t result = static_cast<int32_t>(x);
320+
if (result % 2 != 0)
321+
result >= 0 ? ++result : --result;
322+
return result;
323+
}
324+
325+
return std::round(x);
326+
}
327+
};
328+
329+
template<typename FloatingPoint>
330+
NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<FloatingPoint>)
331+
struct fma_helper<FloatingPoint NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<FloatingPoint>) >
332+
{
333+
static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x, NBL_CONST_REF_ARG(FloatingPoint) y, NBL_CONST_REF_ARG(FloatingPoint) z)
334+
{
335+
return std::fma(x, y, z);
336+
}
337+
};
338+
339+
template<typename T, typename U>
340+
NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<T> && concepts::IntegralScalar<U>)
341+
struct ldexp_helper<T, U NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<T> && concepts::IntegralScalar<U>) >
342+
{
343+
static T __call(NBL_CONST_REF_ARG(T) arg, NBL_CONST_REF_ARG(U) exp)
344+
{
345+
return std::ldexp(arg, exp);
286346
}
287347
};
288348

@@ -372,6 +432,10 @@ AUTO_SPECIALIZE_HELPER_FOR_VECTOR(cos_helper, T)
372432
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(sin_helper, T)
373433
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(acos_helper, T)
374434
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(modf_helper, T)
435+
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(round_helper, T)
436+
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(roundEven_helper, T)
437+
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(trunc_helper, T)
438+
AUTO_SPECIALIZE_HELPER_FOR_VECTOR(ceil_helper, T)
375439

376440
#undef INT_VECTOR_RETURN_TYPE
377441
#undef AUTO_SPECIALIZE_HELPER_FOR_VECTOR
@@ -394,6 +458,47 @@ struct pow_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
394458
return output;
395459
}
396460
};
461+
462+
template<typename T>
463+
NBL_PARTIAL_REQ_TOP(VECTOR_SPECIALIZATION_CONCEPT)
464+
struct fma_helper<T NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT) >
465+
{
466+
using return_t = T;
467+
static return_t __call(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(T) z)
468+
{
469+
using traits = hlsl::vector_traits<T>;
470+
array_get<T, typename traits::scalar_type> getter;
471+
array_set<T, typename traits::scalar_type> setter;
472+
473+
return_t output;
474+
for (uint32_t i = 0; i < traits::Dimension; ++i)
475+
setter(output, i, fma_helper<typename traits::scalar_type>::__call(getter(x, i), getter(y, i), getter(z, i)));
476+
477+
return output;
478+
}
479+
};
480+
481+
template<typename T, typename U>
482+
NBL_PARTIAL_REQ_TOP(VECTOR_SPECIALIZATION_CONCEPT && (vector_traits<T>::Dimension == vector_traits<U>::Dimension))
483+
struct ldexp_helper<T, U NBL_PARTIAL_REQ_BOT(VECTOR_SPECIALIZATION_CONCEPT && (vector_traits<T>::Dimension == vector_traits<U>::Dimension)) >
484+
{
485+
using return_t = T;
486+
static return_t __call(NBL_CONST_REF_ARG(T) arg, NBL_CONST_REF_ARG(U) exp)
487+
{
488+
using arg_traits = hlsl::vector_traits<T>;
489+
using exp_traits = hlsl::vector_traits<U>;
490+
array_get<T, typename arg_traits::scalar_type> argGetter;
491+
array_get<U, typename exp_traits::scalar_type> expGetter;
492+
array_set<T, typename arg_traits::scalar_type> setter;
493+
494+
return_t output;
495+
for (uint32_t i = 0; i < arg_traits::Dimension; ++i)
496+
setter(output, i, ldexp_helper<typename arg_traits::scalar_type, typename exp_traits::scalar_type>::__call(argGetter(arg, i), expGetter(exp, i)));
497+
498+
return output;
499+
}
500+
};
501+
397502
#undef VECTOR_SPECIALIZATION_CONCEPT
398503

399504
}

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,32 @@ template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
172172
[[vk::ext_instruction(GLSLstd450Fract, "GLSL.std.450")]]
173173
T fract(T val);
174174

175+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
176+
[[vk::ext_instruction(GLSLstd450Round, "GLSL.std.450")]]
177+
T round(T val);
178+
179+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
180+
[[vk::ext_instruction(GLSLstd450RoundEven, "GLSL.std.450")]]
181+
T roundEven(T val);
182+
183+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
184+
[[vk::ext_instruction(GLSLstd450Trunc, "GLSL.std.450")]]
185+
T trunc(T val);
186+
187+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
188+
[[vk::ext_instruction(GLSLstd450Ceil, "GLSL.std.450")]]
189+
T ceil(T val);
190+
191+
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T>)
192+
[[vk::ext_instruction(GLSLstd450Fma, "GLSL.std.450")]]
193+
T fma(T x, T y, T z);
194+
195+
template<typename T, typename U NBL_FUNC_REQUIRES(concepts::FloatingPointVectorOrScalar<T> &&
196+
(concepts::IntegralVectorOrScalar<U> || concepts::UnsignedIntegralVectorOrScalar<U>) &&
197+
(vector_traits<T>::Dimension == vector_traits<U>::Dimension))
198+
[[vk::ext_instruction(GLSLstd450Ldexp, "GLSL.std.450")]]
199+
T ldexp(T arg, U exp);
200+
175201
}
176202
}
177203
}

include/nbl/builtin/hlsl/tgmath.hlsl

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ inline T floor(NBL_CONST_REF_ARG(T) val)
4141
return tgmath_impl::floor_helper<T>::__call(val);
4242
}
4343

44-
template<typename T, typename U>
45-
inline T mix(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a)
46-
{
47-
return tgmath_impl::mix_helper<T, U>::__call(x, y, a);
48-
}
49-
5044
template<typename T>
5145
inline typename tgmath_impl::isnan_helper<T>::return_t isnan(NBL_CONST_REF_ARG(T) val)
5246
{
@@ -132,6 +126,42 @@ inline T modf(NBL_CONST_REF_ARG(T) val)
132126
return tgmath_impl::modf_helper<T>::__call(val);
133127
}
134128

129+
template<typename T>
130+
inline T round(NBL_CONST_REF_ARG(T) val)
131+
{
132+
return tgmath_impl::round_helper<T>::__call(val);
133+
}
134+
135+
template<typename T>
136+
inline T roundEven(NBL_CONST_REF_ARG(T) val)
137+
{
138+
return tgmath_impl::roundEven_helper<T>::__call(val);
139+
}
140+
141+
template<typename T>
142+
inline T trunc(NBL_CONST_REF_ARG(T) val)
143+
{
144+
return tgmath_impl::trunc_helper<T>::__call(val);
145+
}
146+
147+
template<typename T>
148+
inline T ceil(NBL_CONST_REF_ARG(T) val)
149+
{
150+
return tgmath_impl::ceil_helper<T>::__call(val);
151+
}
152+
153+
template<typename T>
154+
inline T fma(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(T) z)
155+
{
156+
return tgmath_impl::fma_helper<T>::__call(x, y, z);
157+
}
158+
159+
template<typename T, typename U>
160+
inline T ldexp(NBL_CONST_REF_ARG(T) arg, NBL_CONST_REF_ARG(U) exp)
161+
{
162+
return tgmath_impl::ldexp_helper<T, U>::__call(arg, exp);
163+
}
164+
135165
}
136166
}
137167

src/nbl/builtin/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/ieee754/impl.hlsl")
226226
LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/array_accessors.hlsl")
227227
LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/vector_utils/vector_traits.hlsl")
228228
LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/matrix_traits.hlsl")
229-
LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/mul_output_t.hlsl")
230229
LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/tgmath.hlsl")
231230
LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/impl/tgmath_impl.hlsl")
232231

0 commit comments

Comments
 (0)