Skip to content

Conversation

@Fletterio
Copy link
Contributor

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

Comment on lines 238 to 266
#ifndef __HLSL_VERSION
template<typename F1, typename F2 > requires(is_same_v<std::invoke_result_t<F1>, std::invoke_result_t<F2>()> )
struct ternary_operator
{
using type_t = T;

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);
}
using type_t = std::invoke_result_t<F1>;

constexpr inline type_t operator()(const bool condition, const F1& lhs, const F2& rhs)
{
if (condition)
return std::invoke(lhs);
else
return std::invoke(rhs);
}
};
#else
template<typename F1, typename F2 NBL_PRIMARY_REQUIRES(is_same_v<decltype(experimental::declval<F1>()()),decltype(experimental::declval<F2>()())> )
struct ternary_operator
{
using type_t = decltype(experimental::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();
}
};
#endif

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see no reason to have two separate implementations, the HLSL one should work everywhere.

Also provide 4 overloads which takes lhs and rhs as NBL_REF_ARG instead of CONST_REF_ARG (so the calls can be stateful but mutable0

{
NBL_CONSTEXPR_STATIC T __call(NBL_CONST_REF_ARG(B) condition, NBL_CONST_REF_ARG(T) object1, NBL_CONST_REF_ARG(T) object2)
{
return condition ? object1 : object2;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ifdef __HLSL_VERSION then use spirv::select instead of ternary ? op (so DXC codegens OpSelect and not a branch

Comment on lines +682 to +699
template<typename B, typename T>
NBL_PARTIAL_REQ_TOP(concepts::Boolean<B>&& concepts::Vector<B>&& concepts::Vector<T> && (extent_v<B> == extent_v<T>))
struct select_helper<B, T NBL_PARTIAL_REQ_BOT(concepts::Boolean<B>&& concepts::Vector<B>&& concepts::Vector<T> && (extent_v<B> == extent_v<T>)) >
{
NBL_CONSTEXPR_STATIC T __call(NBL_CONST_REF_ARG(B) condition, NBL_CONST_REF_ARG(T) object1, NBL_CONST_REF_ARG(T) object2)
{
using traits = hlsl::vector_traits<T>;
array_get<B, bool> conditionGetter;
array_get<T, typename traits::scalar_type> objectGetter;
array_set<T, typename traits::scalar_type> setter;

T selected;
for (uint32_t i = 0; i < traits::Dimension; ++i)
setter(selected, i, conditionGetter(condition, i) ? objectGetter(object1, i) : objectGetter(object2, i));

return selected;
}
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the code in this specialization should be reserved for non-native vectors (either the boolean vector is non-native or the T vector)

The vector<bool,N> and vector<T,N> specialization should use spirv::select but only exists for HLSL, see how it was done for mix_helper

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants