coord/store: abstract SIMD alignment tests
This commit is contained in:
parent
353cf839d4
commit
abedda1e5d
@ -22,24 +22,49 @@
|
|||||||
#include "../platform.hpp"
|
#include "../platform.hpp"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
// Calculate a reasonable alignment for the given type and arity given what we
|
||||||
|
// know about the platform. Only intended to be used with alignas specifiers.
|
||||||
|
namespace util::coord::detail {
|
||||||
|
template <typename T>
|
||||||
|
constexpr
|
||||||
|
size_t
|
||||||
|
alignment (size_t S)
|
||||||
|
{
|
||||||
|
#if defined(__SSE_MATH__)
|
||||||
|
// Align to 16 if we have 4x floats on SSE/NEON. There are other
|
||||||
|
// possiblities, but we don't care about them right at this point.
|
||||||
|
if (!std::is_same<T,float>::value)
|
||||||
|
return alignof (T);
|
||||||
|
|
||||||
|
if (S % 4 == 0)
|
||||||
|
return 16;
|
||||||
|
#elif defined (__ARM_NEON__)
|
||||||
|
// TODO: deal with alignment issues before adding alignas specifiers
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return alignof (T);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SIMD_ALIGN(S,T) alignas (util::coord::detail::alignment<T> (S))
|
||||||
|
|
||||||
|
|
||||||
namespace util::coord {
|
namespace util::coord {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Coordinate storage class.
|
// Coordinate storage class.
|
||||||
//
|
//
|
||||||
// Types of arity multiples of 4 with payloads of at least 16 bytes
|
// Types with trivially suitable arity are aligned appropriately to take
|
||||||
// (T >= uint16_t) are guaranteed to be aligned appropriately for SSE (see
|
// advantage of native platform SIMD. eg, 4f types are aligned to 16 bytes
|
||||||
// specialisations below).
|
// on SSE platforms.
|
||||||
template <
|
template <
|
||||||
size_t S,
|
size_t S,
|
||||||
typename T,
|
typename T,
|
||||||
typename...
|
typename...
|
||||||
>
|
>
|
||||||
struct
|
struct
|
||||||
alignas (
|
SIMD_ALIGN(S,T)
|
||||||
sizeof (T) * S % 16 == 0 && sizeof (T) * S >= 16 ? 16 : alignof (T)
|
|
||||||
)
|
|
||||||
store {
|
store {
|
||||||
T data[S];
|
T data[S];
|
||||||
};
|
};
|
||||||
@ -63,9 +88,7 @@ namespace util::coord {
|
|||||||
// TODO: expand this for other instruction sets. maybe switch on type.
|
// TODO: expand this for other instruction sets. maybe switch on type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct
|
struct
|
||||||
alignas (
|
SIMD_ALIGN(4,T)
|
||||||
sizeof (T) * 4u >= 16 ? 16 : alignof (T)
|
|
||||||
)
|
|
||||||
store<4,T,rgba,hsv> {
|
store<4,T,rgba,hsv> {
|
||||||
union {
|
union {
|
||||||
T data[4];
|
T data[4];
|
||||||
@ -101,9 +124,7 @@ namespace util::coord {
|
|||||||
// TODO: expand this for other instruction sets. maybe switch on type.
|
// TODO: expand this for other instruction sets. maybe switch on type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct
|
struct
|
||||||
alignas (
|
SIMD_ALIGN(4,T)
|
||||||
sizeof (T) * 4u >= 16 ? 16 : alignof (T)
|
|
||||||
)
|
|
||||||
store<4,T,xyzw> {
|
store<4,T,xyzw> {
|
||||||
union {
|
union {
|
||||||
T data[4];
|
T data[4];
|
||||||
@ -140,9 +161,7 @@ namespace util::coord {
|
|||||||
// TODO: expand this for other instruction sets. maybe switch on type.
|
// TODO: expand this for other instruction sets. maybe switch on type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct
|
struct
|
||||||
alignas (
|
SIMD_ALIGN(4,T)
|
||||||
sizeof (T) * 4u >= 16 ? 16 : alignof (T)
|
|
||||||
)
|
|
||||||
store<4,T,xyzw,stpq> {
|
store<4,T,xyzw,stpq> {
|
||||||
union {
|
union {
|
||||||
T data[4];
|
T data[4];
|
||||||
@ -173,7 +192,9 @@ namespace util::coord {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct store<4,T,wxyz,abcd> {
|
struct
|
||||||
|
SIMD_ALIGN(4,T)
|
||||||
|
store<4,T,wxyz,abcd> {
|
||||||
union {
|
union {
|
||||||
T data[4];
|
T data[4];
|
||||||
struct { T w,x,y,z; };
|
struct { T w,x,y,z; };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user