Skip to content

Commit 677b176

Browse files
committed
Refactor
1 parent 9dc8b43 commit 677b176

File tree

3 files changed

+238
-19
lines changed

3 files changed

+238
-19
lines changed

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

Lines changed: 195 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ struct cross_helper;
6868

6969
//! this specialization will work only with hlsl::vector<T, 3> type
7070
template<typename FloatingPointVector>
71-
NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v<FloatingPointVector> && hlsl::is_vector_v<FloatingPointVector> && (vector_traits<FloatingPointVector>::Dimension == 3))
72-
struct cross_helper<FloatingPointVector NBL_PARTIAL_REQ_BOT(hlsl::is_floating_point_v<FloatingPointVector>&& hlsl::is_vector_v<FloatingPointVector>&& (vector_traits<FloatingPointVector>::Dimension == 3)) >
71+
NBL_PARTIAL_REQ_TOP(is_floating_point_v<FloatingPointVector> && is_vector_v<FloatingPointVector> && (vector_traits<FloatingPointVector>::Dimension == 3))
72+
struct cross_helper<FloatingPointVector NBL_PARTIAL_REQ_BOT(is_floating_point_v<FloatingPointVector>&& is_vector_v<FloatingPointVector>&& (vector_traits<FloatingPointVector>::Dimension == 3)) >
7373
{
7474
static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_REF_ARG(FloatingPointVector) rhs)
7575
{
@@ -86,6 +86,69 @@ struct cross_helper<FloatingPointVector NBL_PARTIAL_REQ_BOT(hlsl::is_floating_po
8686
}
8787
};
8888

89+
template<typename T NBL_STRUCT_CONSTRAINABLE>
90+
struct clamp_helper;
91+
92+
template<typename FloatingPoint>
93+
NBL_PARTIAL_REQ_TOP(is_floating_point_v<FloatingPoint> && is_scalar_v<FloatingPoint>)
94+
struct clamp_helper<FloatingPoint NBL_PARTIAL_REQ_BOT(is_floating_point_v<FloatingPoint> && is_scalar_v<FloatingPoint>) >
95+
{
96+
static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) val, NBL_CONST_REF_ARG(FloatingPoint) min, NBL_CONST_REF_ARG(FloatingPoint) max)
97+
{
98+
#ifdef __HLSL_VERSION
99+
return spirv::fClamp(val, min, max);
100+
#else
101+
return std::clamp(val, min, max);
102+
#endif
103+
}
104+
};
105+
106+
template<typename UnsignedInteger>
107+
NBL_PARTIAL_REQ_TOP(is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger> && is_scalar_v<UnsignedInteger>)
108+
struct clamp_helper<UnsignedInteger NBL_PARTIAL_REQ_BOT(is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>) >
109+
{
110+
static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) val, NBL_CONST_REF_ARG(UnsignedInteger) min, NBL_CONST_REF_ARG(UnsignedInteger) max)
111+
{
112+
#ifdef __HLSL_VERSION
113+
return spirv::uClamp(val, min, max);
114+
#else
115+
return std::clamp(val, min, max);
116+
#endif
117+
}
118+
};
119+
120+
template<typename Integer>
121+
NBL_PARTIAL_REQ_TOP(is_integral_v<Integer> && is_signed_v<Integer>&& is_scalar_v<Integer>)
122+
struct clamp_helper<Integer NBL_PARTIAL_REQ_BOT(is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>) >
123+
{
124+
static Integer __call(NBL_CONST_REF_ARG(Integer) val, NBL_CONST_REF_ARG(Integer) min, NBL_CONST_REF_ARG(Integer) max)
125+
{
126+
#ifdef __HLSL_VERSION
127+
return spirv::sClamp(val, min, max);
128+
#else
129+
return std::clamp(val, min, max);
130+
#endif
131+
}
132+
};
133+
134+
template<typename Vector>
135+
NBL_PARTIAL_REQ_TOP(is_vector_v<Vector>)
136+
struct clamp_helper<Vector NBL_PARTIAL_REQ_BOT(is_vector_v<Vector>) >
137+
{
138+
static Vector __call(NBL_CONST_REF_ARG(Vector) val, NBL_CONST_REF_ARG(typename vector_traits<Vector>::scalar_type) min, NBL_CONST_REF_ARG(typename vector_traits<Vector>::scalar_type) max)
139+
{
140+
using traits = hlsl::vector_traits<Vector>;
141+
array_get<Vector, typename traits::scalar_type> getter;
142+
array_set<Vector, typename traits::scalar_type> setter;
143+
144+
Vector output;
145+
for (uint32_t i = 0; i < traits::Dimension; ++i)
146+
setter(output, i, clamp_helper<typename traits::scalar_type>::__call(getter(val, i), min, max));
147+
148+
return output;
149+
}
150+
};
151+
89152
template<typename Integer>
90153
struct find_msb_helper;
91154

@@ -512,6 +575,136 @@ struct normalize_helper<Vector NBL_PARTIAL_REQ_BOT(hlsl::is_floating_point_v<Vec
512575
}
513576
};
514577

578+
// MIN
579+
580+
template<typename T NBL_STRUCT_CONSTRAINABLE>
581+
struct min_helper;
582+
583+
template<typename FloatingPoint>
584+
NBL_PARTIAL_REQ_TOP(is_floating_point_v<FloatingPoint>&& is_scalar_v<FloatingPoint>)
585+
struct min_helper<FloatingPoint NBL_PARTIAL_REQ_BOT(is_floating_point_v<FloatingPoint>&& is_scalar_v<FloatingPoint>) >
586+
{
587+
static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) a, NBL_CONST_REF_ARG(FloatingPoint) b)
588+
{
589+
#ifdef __HLSL_VERSION
590+
return spirv::fMin(a, b);
591+
#else
592+
return std::min(a, b);
593+
#endif
594+
}
595+
};
596+
597+
template<typename UnsignedInteger>
598+
NBL_PARTIAL_REQ_TOP(is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>)
599+
struct min_helper<UnsignedInteger NBL_PARTIAL_REQ_BOT(is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>) >
600+
{
601+
static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) a, NBL_CONST_REF_ARG(UnsignedInteger) b)
602+
{
603+
#ifdef __HLSL_VERSION
604+
return spirv::uMin(a, b);
605+
#else
606+
return std::min(a, b);
607+
#endif
608+
}
609+
};
610+
611+
template<typename Integer>
612+
NBL_PARTIAL_REQ_TOP(is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>)
613+
struct min_helper<Integer NBL_PARTIAL_REQ_BOT(is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>) >
614+
{
615+
static Integer __call(NBL_CONST_REF_ARG(Integer) a, NBL_CONST_REF_ARG(Integer) b)
616+
{
617+
#ifdef __HLSL_VERSION
618+
return spirv::sMin(a, b);
619+
#else
620+
return std::min(a, b);
621+
#endif
622+
}
623+
};
624+
625+
template<typename Vector>
626+
NBL_PARTIAL_REQ_TOP(is_vector_v<Vector>)
627+
struct min_helper<Vector NBL_PARTIAL_REQ_BOT(is_vector_v<Vector>) >
628+
{
629+
static Vector __call(NBL_CONST_REF_ARG(Vector) a, NBL_CONST_REF_ARG(Vector) b)
630+
{
631+
using traits = hlsl::vector_traits<Vector>;
632+
array_get<Vector, typename traits::scalar_type> getter;
633+
array_set<Vector, typename traits::scalar_type> setter;
634+
635+
Vector output;
636+
for (uint32_t i = 0; i < traits::Dimension; ++i)
637+
setter(output, i, min_helper<typename traits::scalar_type>::__call(getter(a, i), getter(b, i)));
638+
639+
return output;
640+
}
641+
};
642+
643+
// MAX
644+
645+
template<typename T NBL_STRUCT_CONSTRAINABLE>
646+
struct max_helper;
647+
648+
template<typename FloatingPoint>
649+
NBL_PARTIAL_REQ_TOP(is_floating_point_v<FloatingPoint>&& is_scalar_v<FloatingPoint>)
650+
struct max_helper<FloatingPoint NBL_PARTIAL_REQ_BOT(is_floating_point_v<FloatingPoint>&& is_scalar_v<FloatingPoint>) >
651+
{
652+
static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) a, NBL_CONST_REF_ARG(FloatingPoint) b)
653+
{
654+
#ifdef __HLSL_VERSION
655+
return spirv::fMax(a, b);
656+
#else
657+
return std::max(a, b);
658+
#endif
659+
}
660+
};
661+
662+
template<typename UnsignedInteger>
663+
NBL_PARTIAL_REQ_TOP(is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>)
664+
struct max_helper<UnsignedInteger NBL_PARTIAL_REQ_BOT(is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>&& is_scalar_v<UnsignedInteger>) >
665+
{
666+
static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) a, NBL_CONST_REF_ARG(UnsignedInteger) b)
667+
{
668+
#ifdef __HLSL_VERSION
669+
return spirv::uMax(a, b);
670+
#else
671+
return std::max(a, b);
672+
#endif
673+
}
674+
};
675+
676+
template<typename Integer>
677+
NBL_PARTIAL_REQ_TOP(is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>)
678+
struct max_helper<Integer NBL_PARTIAL_REQ_BOT(is_integral_v<Integer>&& is_signed_v<Integer>&& is_scalar_v<Integer>) >
679+
{
680+
static Integer __call(NBL_CONST_REF_ARG(Integer) a, NBL_CONST_REF_ARG(Integer) b)
681+
{
682+
#ifdef __HLSL_VERSION
683+
return spirv::sMax(a, b);
684+
#else
685+
return std::max(a, b);
686+
#endif
687+
}
688+
};
689+
690+
template<typename Vector>
691+
NBL_PARTIAL_REQ_TOP(is_vector_v<Vector>)
692+
struct max_helper<Vector NBL_PARTIAL_REQ_BOT(is_vector_v<Vector>) >
693+
{
694+
static Vector __call(NBL_CONST_REF_ARG(Vector) a, NBL_CONST_REF_ARG(Vector) b)
695+
{
696+
using traits = hlsl::vector_traits<Vector>;
697+
array_get<Vector, typename traits::scalar_type> getter;
698+
array_set<Vector, typename traits::scalar_type> setter;
699+
700+
Vector output;
701+
for (uint32_t i = 0; i < traits::Dimension; ++i)
702+
setter(output, i, max_helper<typename traits::scalar_type>::__call(getter(a, i), getter(b, i)));
703+
704+
return output;
705+
}
706+
};
707+
515708
}
516709
}
517710
}

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

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@ FloatingPointVector cross(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_
3131
return cpp_compat_intrinsics_impl::cross_helper<FloatingPointVector>::__call(lhs, rhs);
3232
}
3333

34-
template<typename T>
35-
T clamp(NBL_CONST_REF_ARG(T) val, NBL_CONST_REF_ARG(T) min, NBL_CONST_REF_ARG(T) max)
34+
template<typename Scalar>
35+
enable_if_t<!is_vector_v<Scalar>, Scalar> clamp(NBL_CONST_REF_ARG(Scalar) val, NBL_CONST_REF_ARG(Scalar) min, NBL_CONST_REF_ARG(Scalar) max)
3636
{
37-
#ifdef __HLSL_VERSION
38-
return clamp(val, min, max);
39-
#else
40-
return glm::clamp(val, min, max);
41-
#endif
37+
return cpp_compat_intrinsics_impl::clamp_helper<Scalar>::__call(val, min, max);
38+
}
39+
40+
// TODO: is_vector_v<T> will be false for custom vector types, fix
41+
template<typename Vector>
42+
enable_if_t<is_vector_v<Vector>, Vector> clamp(NBL_CONST_REF_ARG(Vector) val, NBL_CONST_REF_ARG(typename vector_traits<Vector>::scalar_type) min, NBL_CONST_REF_ARG(typename vector_traits<Vector>::scalar_type) max)
43+
{
44+
return cpp_compat_intrinsics_impl::clamp_helper<Vector>::__call(val, min, max);
4245
}
4346

4447
template<typename Vector>
@@ -113,21 +116,13 @@ mul_output_t<LhsT, RhsT> mul(LhsT mat, RhsT vec)
113116
template<typename T>
114117
inline T min(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b)
115118
{
116-
#ifdef __HLSL_VERSION
117-
min(a, b);
118-
#else
119-
return glm::min(a, b);
120-
#endif
119+
return cpp_compat_intrinsics_impl::min_helper<T>::__call(a, b);
121120
}
122121

123122
template<typename T>
124123
inline T max(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b)
125124
{
126-
#ifdef __HLSL_VERSION
127-
max(a, b);
128-
#else
129-
return glm::max(a, b);
130-
#endif
125+
return cpp_compat_intrinsics_impl::max_helper<T>::__call(a, b);
131126
}
132127

133128
template<typename FloatingPoint>

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,37 @@ template<typename FloatingPointVector>
9999
[[vk::ext_instruction(GLSLstd450Normalize, "GLSL.std.450")]]
100100
enable_if_t<is_floating_point_v<FloatingPointVector> && is_vector_v<FloatingPointVector>, FloatingPointVector> normalize(FloatingPointVector vec);
101101

102+
// TODO: will not work for vectors, fix
103+
template<typename FloatingPoint>
104+
[[vk::ext_instruction(GLSLstd450FClamp, "GLSL.std.450")]]
105+
enable_if_t<is_floating_point_v<FloatingPoint>, FloatingPoint> fClamp(FloatingPoint val, FloatingPoint min, FloatingPoint max);
106+
template<typename UnsignedInteger>
107+
[[vk::ext_instruction(GLSLstd450UClamp, "GLSL.std.450")]]
108+
enable_if_t<is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>, UnsignedInteger> uClamp(UnsignedInteger val, UnsignedInteger min, UnsignedInteger max);
109+
template<typename Integer>
110+
[[vk::ext_instruction(GLSLstd450SClamp, "GLSL.std.450")]]
111+
enable_if_t<is_integral_v<Integer> && is_signed_v<Integer>, Integer> sClamp(Integer val, Integer min, Ingeger max);
112+
113+
template<typename FloatingPoint>
114+
[[vk::ext_instruction(GLSLstd450FMin, "GLSL.std.450")]]
115+
enable_if_t<is_floating_point_v<FloatingPoint>, FloatingPoint> fMin(FloatingPoint val);
116+
template<typename UnsignedInteger>
117+
[[vk::ext_instruction(GLSLstd450UMin, "GLSL.std.450")]]
118+
enable_if_t<is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>, UnsignedInteger> uMin(UnsignedInteger val);
119+
template<typename Integer>
120+
[[vk::ext_instruction(GLSLstd450SMin, "GLSL.std.450")]]
121+
enable_if_t<is_integral_v<Integer>&& is_signed_v<Integer>, Integer> sMin(Integer val);
122+
123+
template<typename FloatingPoint>
124+
[[vk::ext_instruction(GLSLstd450FMax, "GLSL.std.450")]]
125+
enable_if_t<is_floating_point_v<FloatingPoint>, FloatingPoint> fMax(FloatingPoint val);
126+
template<typename UnsignedInteger>
127+
[[vk::ext_instruction(GLSLstd450UMax, "GLSL.std.450")]]
128+
enable_if_t<is_integral_v<UnsignedInteger> && !is_signed_v<UnsignedInteger>, UnsignedInteger> uMax(UnsignedInteger val);
129+
template<typename Integer>
130+
[[vk::ext_instruction(GLSLstd450SMax, "GLSL.std.450")]]
131+
enable_if_t<is_integral_v<Integer>&& is_signed_v<Integer>, Integer> sMax(Integer val);
132+
102133
}
103134
}
104135
}

0 commit comments

Comments
 (0)