-
Notifications
You must be signed in to change notification settings - Fork 67
New morton class with arithmetic and comparison operators #860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
… on HLSL side by specializing , a bunch of morton operators
…or both cpp and hlsl
include/nbl/builtin/hlsl/morton.hlsl
Outdated
| */ | ||
| template<typename I> | ||
| NBL_CONSTEXPR_STATIC_FUNC enable_if_t<is_integral_v<I> && is_scalar_v<I> && (is_signed_v<I> == Signed), this_t> | ||
| NBL_CONSTEXPR_STATIC_FUNC enable_if_t<is_integral_v<I> && is_scalar_v<I> && (is_signed_v<I> == Signed) && (8 * sizeof(I) >= Bits), this_t> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to check && (8 * sizeof(I) >= Bits) calling into impl::Transcoder should already check this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
include/nbl/builtin/hlsl/morton.hlsl
Outdated
|
|
||
| template<typename I> | ||
| explicit code(NBL_CONST_REF_ARG(vector<I, D>) cartesian) | ||
| template<typename I NBL_FUNC_REQUIRES(8 * sizeof(I) >= Bits) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to check the bitcount stuff, see https://github.com/Devsh-Graphics-Programming/Nabla/pull/860/files/ea8cd43756146225058dcfbc1ddf4d254b0fd579..2d0ffbadf914f84e4f7d5bfc8fec3b860121f655#r2572041634
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
include/nbl/builtin/hlsl/morton.hlsl
Outdated
| // I must be of same signedness as the morton code, and be wide enough to hold each component | ||
| template<typename I, uint16_t Bits, uint16_t D, typename _uint64_t> NBL_PARTIAL_REQ_TOP(concepts::IntegralScalar<I> && 8 * sizeof(I) >= Bits) | ||
| struct static_cast_helper<vector<I, D>, morton::code<is_signed_v<I>, Bits, D, _uint64_t> NBL_PARTIAL_REQ_BOT(concepts::IntegralScalar<I> && 8 * sizeof(I) >= Bits) > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the bitcount >= the transcoder will already check for you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
include/nbl/builtin/hlsl/morton.hlsl
Outdated
| // Specialize the `static_cast_helper` | ||
| namespace impl | ||
| template <bool Signed, uint16_t Bits, uint16_t D, typename _uint64_t NBL_PRIMARY_REQUIRES(morton::impl::Dimension<D>&& D* Bits <= 64) | ||
| template <typename I NBL_FUNC_REQUIRES(8 * sizeof(I) >= Bits && is_signed_v<I> == Signed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again, its a bit cumbersome to check bitcount here and in other places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| NBL_CONSTEXPR_STATIC_INLINE bool value = FloatingPointScalar<T>; | ||
| }; | ||
|
|
||
| template<typename T> | ||
| struct is_emulating_integral_scalar | ||
| { | ||
| NBL_CONSTEXPR_STATIC_INLINE bool value = IntegralScalar<T>; | ||
| }; | ||
| } | ||
|
|
||
| //! Floating point types are native floating point types or types that imitate native floating point types (for example emulated_float64_t) | ||
| template<typename T> | ||
| NBL_BOOL_CONCEPT FloatingPointLikeScalar = impl::is_emulating_floating_point_scalar<T>::value; | ||
|
|
||
| //! Integral-like types are native integral types or types that imitate native integral types (for example emulated_uint64_t) | ||
| template<typename T> | ||
| NBL_BOOL_CONCEPT IntegralLikeScalar = impl::is_emulating_integral_scalar<T>::value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aren;t these specs backward? as in returning false for emulated float
It should be FloatingPointLikeScalar = FloatingPointScalar || impl::is_emulating_floating_point_scalar
https://godbolt.devsh.eu/z/dbjvfj
The default spec of is_emulating_floating_point_scalar should be false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thats actually a bug ever since @Przemog1's PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It behave as how it is described in the comment. is_emulating_floating_point_scalar return true both for float64_t and emulated_float64_t. It is specialized here for emulated_float64_t
| struct is_emulating_floating_point_scalar<emulated_float64_t<FastMath, FlushDenormToZero> > |
Should we change it so that only emulated_float64_t return true for is_emulating_floating_point_scalar and false for everything else, and keep FloatingPointLikeScalar like how it is?
|
|
||
| NBL_CONSTEXPR_FUNC T operator()(NBL_CONST_REF_ARG(T) operand) | ||
| { | ||
| return -operand; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't it need to be operand.operator-() because of HLSL?
or maybe you want to do a partial spec with requires Fundamental<T> and requires !Fundamental<T> where you do operator-() call ?
|
|
||
| struct emulated_int64_t | ||
| { | ||
| using storage_t = vector<uint32_t, 2>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be moved to "int64_common_member_inc.hlsl"
| template<> | ||
| struct is_emulating_integral_scalar<emulated_uint64_t> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where's the primary template declaration?
btw you could actually replace impl::is_emulating_integral_scalar with just ImitationIntegral64Scalar concept
| return *this; | ||
| } | ||
| template <typename T> | ||
| NBL_BOOL_CONCEPT ImitationIntegral64Scalar = same_as<T, emulated_uint64_t> || same_as<T, emulated_int64_t>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename Imitation to Emulated
|
|
||
| template<typename Scalar, typename U> | ||
| struct Promote<vector <Scalar, 2>, U> | ||
| // TODO(kevinyu): Should we enable truncation from uint64_t to emulated_vector<emulated_uint64_t, N>? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
promotion yes, allow it
| } | ||
| }; | ||
|
|
||
| // The default version above only works for fundamental scalars, vectors and matrices. This is because you can't call `~x` unless `x` is one of the former. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then constrain the version above to only do FundamentalType
the thing which you have as a specialization you should have as the general case, and the general you should have as a specialization
| template<typename T NBL_STRUCT_CONSTRAINABLE > | ||
| struct ternary_operator | ||
| { | ||
| using type_t = T; | ||
|
|
||
| T operator()(bool condition, NBL_CONST_REF_ARG(T) lhs, NBL_CONST_REF_ARG(T) rhs) | ||
| NBL_CONSTEXPR_FUNC T operator()(NBL_CONST_REF_ARG(bool) condition, NBL_CONST_REF_ARG(T) lhs, NBL_CONST_REF_ARG(T) rhs) | ||
| { | ||
| return select<bool, T>(condition, lhs, rhs); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm actually I noticed something, in C++ and HLSL the ? shortcircuits (whereas select shouldn't)
This means that ternary_operator can only be defined as
template<typename F1, typename F2> requires is_same_v<decltype(std::declval<F1>()()),decltype(std::declval<F2>()())>
struct ternary_operator
{
using type_t = decltype(std::declval<F1>().operator());
NBL_CONSTEXPR_FUNC type_t operator()(const bool condition, NBL_CONST_REF_ARG(F1) lhs, NBL_CONST_REF_ARG(F2) rhs)
{
if (condition)
return lhs();
else
return rhs();
}
};simply to take lambdas and short-circuit (not call/evaluate the branch that is false)
so sorry about telling you to reimplement ternary_operator in terms of select
(but most ccrrent uses of ternary_operator should be replaced with select)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Nabla itself there should only be this, which needs to change to select_helper partial spec
Nabla/include/nbl/builtin/hlsl/complex.hlsl
Line 440 in 407051c
| struct ternary_operator< complex_t<Scalar> > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the example the ternary should be replaced with select
https://github.com/search?q=repo%3ADevsh-Graphics-Programming%2FNabla-Examples-and-Tests%20ternary_operator%20&type=code
| return leftShift(interleaved, truncate<vector<uint16_t, Dim> >(vector<uint16_t, 4>(0, 1, 2, 3))); | ||
| } | ||
|
|
||
| template<typename decode_t = conditional_t<(Bits > 16), vector<uint32_t, Dim>, vector<uint16_t, Dim> > > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if would be better to make the default value a constraint instead which checks that is_same_v<conditional<...>,decode_t>
cause right now I can slam any type I want in and override the default
Description
Adds a new class for 2,3 and 4-dimensional morton codes, with arithmetic and comparison operators
Testing
TODO
TODO list:
Need to make sure all operators work properly before merging