Skip to content

Commit

Permalink
feat: misc additions (#221)
Browse files Browse the repository at this point in the history
  • Loading branch information
nfrechette authored Sep 7, 2024
2 parents 14416d4 + 38fca19 commit 4466148
Show file tree
Hide file tree
Showing 12 changed files with 514 additions and 0 deletions.
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

0 comments on commit 4466148

Please sign in to comment.