Skip to content
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

feat: misc additions #221

Merged
merged 4 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions includes/rtm/impl/mask_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,22 @@ namespace rtm
return rtm_impl::mask4_uint64_set{ x, y, z, w };
}

//////////////////////////////////////////////////////////////////////////
// Creates a mask4 with all 4 components set to true.
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE constexpr rtm_impl::mask4_bool_set RTM_SIMD_CALL mask_true() RTM_NO_EXCEPT
{
return rtm_impl::mask4_bool_set{ true, true, true, true };
}

//////////////////////////////////////////////////////////////////////////
// Creates a mask4 with all 4 components set to false.
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE constexpr rtm_impl::mask4_bool_set RTM_SIMD_CALL mask_false() RTM_NO_EXCEPT
{
return rtm_impl::mask4_bool_set{ false, false, false, false };
}

RTM_IMPL_VERSION_NAMESPACE_END
}

Expand Down
28 changes: 28 additions & 0 deletions includes/rtm/mask4d.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,34 @@ namespace rtm
#endif
}

//////////////////////////////////////////////////////////////////////////
// Per component logical NOT of the input: ~input
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE mask4d RTM_SIMD_CALL mask_not(mask4d_arg0 input) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
const __m128i true_mask = _mm_set_epi64x(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL);
__m128d xy = _mm_andnot_pd(input.xy, _mm_castsi128_pd(true_mask));
__m128d zw = _mm_andnot_pd(input.zw, _mm_castsi128_pd(true_mask));
return mask4d{ xy, zw };
#else
const uint64_t* input_ = rtm_impl::bit_cast<const uint64_t*>(&input);

union
{
mask4d vector;
uint64_t scalar[4];
} result;

result.scalar[0] = ~input_[0];
result.scalar[1] = ~input_[1];
result.scalar[2] = ~input_[2];
result.scalar[3] = ~input_[3];

return result.vector;
#endif
}

RTM_IMPL_VERSION_NAMESPACE_END
}

Expand Down
28 changes: 28 additions & 0 deletions includes/rtm/mask4f.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,34 @@ namespace rtm
#endif
}

//////////////////////////////////////////////////////////////////////////
// Per component logical NOT of the input: ~input
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE mask4f RTM_SIMD_CALL mask_not(mask4f_arg0 input) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
const __m128i true_mask = _mm_set_epi32(0xFFFFFFFFULL, 0xFFFFFFFFULL, 0xFFFFFFFFULL, 0xFFFFFFFFULL);
return _mm_andnot_ps(input, _mm_castsi128_ps(true_mask));
#elif defined(RTM_NEON_INTRINSICS)
return vmvnq_u32(input);
#else
const uint32_t* input_ = rtm_impl::bit_cast<const uint32_t*>(&input);

union
{
mask4f vector;
uint32_t scalar[4];
} result;

result.scalar[0] = ~input_[0];
result.scalar[1] = ~input_[1];
result.scalar[2] = ~input_[2];
result.scalar[3] = ~input_[3];

return result.vector;
#endif
}

RTM_IMPL_VERSION_NAMESPACE_END
}

Expand Down
15 changes: 15 additions & 0 deletions includes/rtm/mask4i.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,21 @@ namespace rtm
#endif
}

//////////////////////////////////////////////////////////////////////////
// Per component logical NOT of the input: ~input
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE mask4i RTM_SIMD_CALL mask_not(mask4i_arg0 input) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
const __m128i true_mask = _mm_set_epi32(0xFFFFFFFFULL, 0xFFFFFFFFULL, 0xFFFFFFFFULL, 0xFFFFFFFFULL);
return _mm_andnot_si128(input, true_mask);
#elif defined(RTM_NEON_INTRINSICS)
return RTM_IMPL_MASK4i_SET(vmvnq_u32(RTM_IMPL_MASK4i_GET(input)));
#else
return mask4i{ ~input.x, ~input.y, ~input.z, ~input.w };
#endif
}

RTM_IMPL_VERSION_NAMESPACE_END
}

Expand Down
28 changes: 28 additions & 0 deletions includes/rtm/mask4q.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,34 @@ namespace rtm
#endif
}

//////////////////////////////////////////////////////////////////////////
// Per component logical NOT of the input: ~input
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE mask4q RTM_SIMD_CALL mask_not(mask4q_arg0 input) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
const __m128i true_mask = _mm_set_epi64x(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL);
__m128i xy = _mm_andnot_si128(input.xy, true_mask);
__m128i zw = _mm_andnot_si128(input.zw, true_mask);
return mask4q{ xy, zw };
#else
const uint64_t* input_ = rtm_impl::bit_cast<const uint64_t*>(&input);

union
{
mask4q vector;
uint64_t scalar[4];
} result;

result.scalar[0] = ~input_[0];
result.scalar[1] = ~input_[1];
result.scalar[2] = ~input_[2];
result.scalar[3] = ~input_[3];

return result.vector;
#endif
}

RTM_IMPL_VERSION_NAMESPACE_END
}

Expand Down
16 changes: 16 additions & 0 deletions includes/rtm/quatd.h
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,22 @@ namespace rtm
return positive_w_angle <= threshold_angle;
}

//////////////////////////////////////////////////////////////////////////
// Per component selection depending on the mask: mask != 0 ? if_true : if_false
// Note that if the mask lanes are not all identical, the resulting quaternion
// may not be normalized.
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE quatd RTM_SIMD_CALL quat_select(mask4d_arg0 mask, quatd_arg1 if_true, quatd_arg2 if_false) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
__m128d xy = RTM_VECTOR2D_SELECT(mask.xy, if_true.xy, if_false.xy);
__m128d zw = RTM_VECTOR2D_SELECT(mask.zw, if_true.zw, if_false.zw);
return quatd{ xy, zw };
#else
return quatd{ rtm_impl::select(mask.x, if_true.x, if_false.x), rtm_impl::select(mask.y, if_true.y, if_false.y), rtm_impl::select(mask.z, if_true.z, if_false.z), rtm_impl::select(mask.w, if_true.w, if_false.w) };
#endif
}

RTM_IMPL_VERSION_NAMESPACE_END
}

Expand Down
14 changes: 14 additions & 0 deletions includes/rtm/quatf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,20 @@ namespace rtm
return positive_w_angle <= threshold_angle;
}

//////////////////////////////////////////////////////////////////////////
// Per component selection depending on the mask: mask != 0 ? if_true : if_false
// Note that if the mask lanes are not all identical, the resulting quaternion
// may not be normalized.
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE quatf RTM_SIMD_CALL quat_select(mask4f_arg0 mask, quatf_arg1 if_true, quatf_arg2 if_false) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS) || defined(RTM_NEON_INTRINSICS)
return RTM_VECTOR4F_SELECT(mask, if_true, if_false);
#else
return quatf{ rtm_impl::select(mask.x, if_true.x, if_false.x), rtm_impl::select(mask.y, if_true.y, if_false.y), rtm_impl::select(mask.z, if_true.z, if_false.z), rtm_impl::select(mask.w, if_true.w, if_false.w) };
#endif
}

RTM_IMPL_VERSION_NAMESPACE_END
}

Expand Down
96 changes: 96 additions & 0 deletions includes/rtm/vector4d.h
Original file line number Diff line number Diff line change
Expand Up @@ -2088,6 +2088,20 @@ namespace rtm
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns per component ~0 if not equal, otherwise 0: lhs != rhs ? ~0 : 0
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE mask4d RTM_SIMD_CALL vector_not_equal(vector4d_arg0 lhs, vector4d_arg1 rhs) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
__m128d xy_lt_pd = _mm_cmpneq_pd(lhs.xy, rhs.xy);
__m128d zw_lt_pd = _mm_cmpneq_pd(lhs.zw, rhs.zw);
return mask4d{ xy_lt_pd, zw_lt_pd };
#else
return mask4d{ rtm_impl::get_mask_value(lhs.x != rhs.x), rtm_impl::get_mask_value(lhs.y != rhs.y), rtm_impl::get_mask_value(lhs.z != rhs.z), rtm_impl::get_mask_value(lhs.w != rhs.w) };
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns per component ~0 if less than, otherwise 0: lhs < rhs ? ~0 : 0
//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2554,6 +2568,88 @@ namespace rtm
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns true if all [xyzw] components are not equal, otherwise false: all(lhs.xyzw != rhs.xyzw)
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE bool RTM_SIMD_CALL vector_all_not_equal(vector4d_arg0 lhs, vector4d_arg1 rhs) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
__m128d xy_eq_pd = _mm_cmpneq_pd(lhs.xy, rhs.xy);
__m128d zw_eq_pd = _mm_cmpneq_pd(lhs.zw, rhs.zw);
return (_mm_movemask_pd(xy_eq_pd) & _mm_movemask_pd(zw_eq_pd)) == 3;
#else
return lhs.x != rhs.x && lhs.y != rhs.y && lhs.z != rhs.z && lhs.w != rhs.w;
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns true if all [xy] components are not equal, otherwise false: all(lhs.xy != rhs.xy)
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE bool RTM_SIMD_CALL vector_all_not_equal2(vector4d_arg0 lhs, vector4d_arg1 rhs) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
__m128d xy_eq_pd = _mm_cmpneq_pd(lhs.xy, rhs.xy);
return _mm_movemask_pd(xy_eq_pd) == 3;
#else
return lhs.x != rhs.x && lhs.y != rhs.y;
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns true if all [xyz] components are not equal, otherwise false: all(lhs.xyz != rhs.xyz)
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE bool RTM_SIMD_CALL vector_all_not_equal3(vector4d_arg0 lhs, vector4d_arg1 rhs) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
__m128d xy_eq_pd = _mm_cmpneq_pd(lhs.xy, rhs.xy);
__m128d zw_eq_pd = _mm_cmpneq_pd(lhs.zw, rhs.zw);
return _mm_movemask_pd(xy_eq_pd) == 3 && (_mm_movemask_pd(zw_eq_pd) & 1) != 0;
#else
return lhs.x != rhs.x && lhs.y != rhs.y && lhs.z != rhs.z;
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns true if any [xyzw] components are not equal, otherwise false: any(lhs.xyzw != rhs.xyzw)
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE bool RTM_SIMD_CALL vector_any_not_equal(vector4d_arg0 lhs, vector4d_arg1 rhs) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
__m128d xy_eq_pd = _mm_cmpneq_pd(lhs.xy, rhs.xy);
__m128d zw_eq_pd = _mm_cmpneq_pd(lhs.zw, rhs.zw);
return (_mm_movemask_pd(xy_eq_pd) | _mm_movemask_pd(zw_eq_pd)) != 0;
#else
return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z || lhs.w != rhs.w;
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns true if any [xy] components are not equal, otherwise false: any(lhs.xy != rhs.xy)
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE bool RTM_SIMD_CALL vector_any_not_equal2(vector4d_arg0 lhs, vector4d_arg1 rhs) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
__m128d xy_eq_pd = _mm_cmpneq_pd(lhs.xy, rhs.xy);
return _mm_movemask_pd(xy_eq_pd) != 0;
#else
return lhs.x != rhs.x || lhs.y != rhs.y;
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns true if any [xyz] components are not equal, otherwise false: any(lhs.xyz != rhs.xyz)
//////////////////////////////////////////////////////////////////////////
RTM_DISABLE_SECURITY_COOKIE_CHECK RTM_FORCE_INLINE bool RTM_SIMD_CALL vector_any_not_equal3(vector4d_arg0 lhs, vector4d_arg1 rhs) RTM_NO_EXCEPT
{
#if defined(RTM_SSE2_INTRINSICS)
__m128d xy_eq_pd = _mm_cmpneq_pd(lhs.xy, rhs.xy);
__m128d zw_eq_pd = _mm_cmpneq_pd(lhs.zw, rhs.zw);
return _mm_movemask_pd(xy_eq_pd) != 0 || (_mm_movemask_pd(zw_eq_pd) & 1) != 0;
#else
return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z;
#endif
}

//////////////////////////////////////////////////////////////////////////
// Returns true if all 4 components are near equal, otherwise false: all(abs(lhs - rhs).xyzw <= threshold)
//////////////////////////////////////////////////////////////////////////
Expand Down
Loading
Loading