|
@@ -461,3 +461,337 @@ namespace detail
|
|
|
}//namespace glm
|
|
}//namespace glm
|
|
|
|
|
|
|
|
#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
|
|
#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
|
|
|
|
|
+
|
|
|
|
|
+#if GLM_ARCH & GLM_ARCH_NEON_BIT
|
|
|
|
|
+namespace glm {
|
|
|
|
|
+namespace detail {
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_add<float, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static
|
|
|
|
|
+ vec<4, float, Q>
|
|
|
|
|
+ call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, float, Q> Result;
|
|
|
|
|
+ Result.data = vaddq_f32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_add<uint, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static
|
|
|
|
|
+ vec<4, uint, Q>
|
|
|
|
|
+ call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, uint, Q> Result;
|
|
|
|
|
+ Result.data = vaddq_u32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_add<int, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static
|
|
|
|
|
+ vec<4, int, Q>
|
|
|
|
|
+ call(vec<4, int, Q> const& a, vec<4, int, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, uint, Q> Result;
|
|
|
|
|
+ Result.data = vaddq_s32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_sub<float, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, float, Q> Result;
|
|
|
|
|
+ Result.data = vsubq_f32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_sub<uint, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, uint, Q> Result;
|
|
|
|
|
+ Result.data = vsubq_u32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_sub<int, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, int, Q> Result;
|
|
|
|
|
+ Result.data = vsubq_s32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_mul<float, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, float, Q> Result;
|
|
|
|
|
+ Result.data = vmulq_f32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_mul<uint, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, uint, Q> Result;
|
|
|
|
|
+ Result.data = vmulq_u32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_mul<int, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, int, Q> Result;
|
|
|
|
|
+ Result.data = vmulq_s32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_div<float, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, float, Q> Result;
|
|
|
|
|
+ Result.data = vdivq_f32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_div<uint, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, uint, Q> Result;
|
|
|
|
|
+ Result.data = vdivq_u32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_div<int, Q, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static vec<4, int, Q> call(vec<4, float, Q> const& a, vec<4, int, Q> const& b)
|
|
|
|
|
+ {
|
|
|
|
|
+ vec<4, int, Q> Result;
|
|
|
|
|
+ Result.data = vdivq_s32(a.data, b.data);
|
|
|
|
|
+ return Result;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_equal<float, Q, false, 32, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
|
|
|
|
|
+ {
|
|
|
|
|
+ uint32x4_t cmp = vceqq_f32(v1.data, v2.data);
|
|
|
|
|
+#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
|
|
|
|
|
+ cmp = vpminq_u32(cmp, cmp);
|
|
|
|
|
+ cmp = vpminq_u32(cmp, cmp);
|
|
|
|
|
+ uint32_t r = cmp[0];
|
|
|
|
|
+#else
|
|
|
|
|
+ uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp));
|
|
|
|
|
+ cmpx2 = vpmin_u32(cmpx2, cmpx2);
|
|
|
|
|
+ uint32_t r = cmpx2[0];
|
|
|
|
|
+#endif
|
|
|
|
|
+ return r == ~0u;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_equal<uint, Q, false, 32, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2)
|
|
|
|
|
+ {
|
|
|
|
|
+ uint32x4_t cmp = vceqq_u32(v1.data, v2.data);
|
|
|
|
|
+#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
|
|
|
|
|
+ cmp = vpminq_u32(cmp, cmp);
|
|
|
|
|
+ cmp = vpminq_u32(cmp, cmp);
|
|
|
|
|
+ uint32_t r = cmp[0];
|
|
|
|
|
+#else
|
|
|
|
|
+ uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp));
|
|
|
|
|
+ cmpx2 = vpmin_u32(cmpx2, cmpx2);
|
|
|
|
|
+ uint32_t r = cmpx2[0];
|
|
|
|
|
+#endif
|
|
|
|
|
+ return r == ~0u;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_equal<int, Q, false, 32, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
|
|
|
|
|
+ {
|
|
|
|
|
+ uint32x4_t cmp = vceqq_s32(v1.data, v2.data);
|
|
|
|
|
+#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
|
|
|
|
|
+ cmp = vpminq_u32(cmp, cmp);
|
|
|
|
|
+ cmp = vpminq_u32(cmp, cmp);
|
|
|
|
|
+ uint32_t r = cmp[0];
|
|
|
|
|
+#else
|
|
|
|
|
+ uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp));
|
|
|
|
|
+ cmpx2 = vpmin_u32(cmpx2, cmpx2);
|
|
|
|
|
+ uint32_t r = cmpx2[0];
|
|
|
|
|
+#endif
|
|
|
|
|
+ return r == ~0u;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_nequal<float, Q, false, 32, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
|
|
|
|
|
+ {
|
|
|
|
|
+ return !compute_vec4_equal<float, Q, false, 32, true>::call(v1, v2);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_nequal<uint, Q, false, 32, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2)
|
|
|
|
|
+ {
|
|
|
|
|
+ return !compute_vec4_equal<uint, Q, false, 32, true>::call(v1, v2);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<qualifier Q>
|
|
|
|
|
+ struct compute_vec4_nequal<int, Q, false, 32, true>
|
|
|
|
|
+ {
|
|
|
|
|
+ static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
|
|
|
|
|
+ {
|
|
|
|
|
+ return !compute_vec4_equal<int, Q, false, 32, true>::call(v1, v2);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+}//namespace detail
|
|
|
|
|
+
|
|
|
|
|
+#if !GLM_CONFIG_XYZW_ONLY
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) :
|
|
|
|
|
+ data(vdupq_n_f32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) :
|
|
|
|
|
+ data(vdupq_n_f32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) :
|
|
|
|
|
+ data(vdupq_n_f32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) :
|
|
|
|
|
+ data(vdupq_n_s32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) :
|
|
|
|
|
+ data(vdupq_n_s32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) :
|
|
|
|
|
+ data(vdupq_n_s32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_lowp>::vec(uint _s) :
|
|
|
|
|
+ data(vdupq_n_u32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_mediump>::vec(uint _s) :
|
|
|
|
|
+ data(vdupq_n_u32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_highp>::vec(uint _s) :
|
|
|
|
|
+ data(vdupq_n_u32(_s))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, aligned_highp>& rhs) :
|
|
|
|
|
+ data(rhs.data)
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, int, aligned_highp>& rhs) :
|
|
|
|
|
+ data(vcvtq_f32_s32(rhs.data))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, uint, aligned_highp>& rhs) :
|
|
|
|
|
+ data(vcvtq_f32_u32(rhs.data))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) :
|
|
|
|
|
+ data(vcvtq_f32_s32(vec<4, int, aligned_lowp>(_x, _y, _z, _w).data))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) :
|
|
|
|
|
+ data(vcvtq_f32_s32(vec<4, int, aligned_mediump>(_x, _y, _z, _w).data))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) :
|
|
|
|
|
+ data(vcvtq_f32_s32(vec<4, int, aligned_highp>(_x, _y, _z, _w).data))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(uint _x, uint _y, uint _z, uint _w) :
|
|
|
|
|
+ data(vcvtq_f32_u32(vec<4, uint, aligned_lowp>(_x, _y, _z, _w).data))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(uint _x, uint _y, uint _z, uint _w) :
|
|
|
|
|
+ data(vcvtq_f32_u32(vec<4, uint, aligned_mediump>(_x, _y, _z, _w).data))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ template<>
|
|
|
|
|
+ template<>
|
|
|
|
|
+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(uint _x, uint _y, uint _z, uint _w) :
|
|
|
|
|
+ data(vcvtq_f32_u32(vec<4, uint, aligned_highp>(_x, _y, _z, _w).data))
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+#endif
|
|
|
|
|
+}//namespace glm
|
|
|
|
|
+
|
|
|
|
|
+#endif
|