coord/store: enforce 16 byte alignment for arity 4

This commit is contained in:
Danny Robson 2016-03-14 22:31:50 +11:00
parent 12b526dff7
commit 039113b661

View File

@ -25,7 +25,7 @@
namespace util { namespace coord { namespace util { namespace coord {
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Disable GCC warnings about validity of anonyous structures in // Disable GCC warnings about validity of anonymous structures in
// unions. Push comes to shove I'll manually redsign everything to // unions. Push comes to shove I'll manually redsign everything to
// keep this syntax anyway. // keep this syntax anyway.
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -37,8 +37,21 @@ namespace util { namespace coord {
#endif #endif
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename...> // Coordinate storage class.
struct store { //
// Types of arity multiples of 4 with payloads of at least 16 bytes
// (T >= uint16_t) are guaranteed to be aligned appropriately for SSE (see
// specialisations below).
template <
size_t S,
typename T,
typename...
>
struct
alignas (
sizeof (T) * S % 16 == 0 && sizeof (T) * S >= 16 ? 16 : alignof (T)
)
store {
T data[S]; T data[S];
}; };
@ -53,8 +66,18 @@ namespace util { namespace coord {
}; };
}; };
// Align on 16 bytes if the data is at least 16 bytes long. Prevents tiny
// types like colour4u requiring massive alignments, reduces internal
// fragmentation.
//
// TODO: expand this for other instruction sets. maybe switch on type.
template <typename T> template <typename T>
struct store<4,T,rgba,hsv> { struct
alignas (
sizeof (T) * 4u >= 16 ? 16 : alignof (T)
)
store<4,T,rgba,hsv> {
union { union {
T data[4]; T data[4];
struct { T r,g,b,a; }; struct { T r,g,b,a; };
@ -82,8 +105,17 @@ namespace util { namespace coord {
}; };
// Align on 16 bytes if the data is at least 16 bytes long. Prevents tiny
// types like colour4u requiring massive alignments, reduces internal
// fragmentation.
//
// TODO: expand this for other instruction sets. maybe switch on type.
template <typename T> template <typename T>
struct store<4,T,xyzw> { struct
alignas (
sizeof (T) * 4u >= 16 ? 16 : alignof (T)
)
store<4,T,xyzw> {
union { union {
T data[4]; T data[4];
struct { T x,y,z,w; }; struct { T x,y,z,w; };
@ -112,8 +144,17 @@ namespace util { namespace coord {
}; };
// Align on 16 bytes if the data is at least 16 bytes long. Prevents tiny
// types like colour4u requiring massive alignments, reduces internal
// fragmentation.
//
// TODO: expand this for other instruction sets. maybe switch on type.
template <typename T> template <typename T>
struct store<4,T,xyzw,stpq> { struct
alignas (
sizeof (T) * 4u >= 16 ? 16 : alignof (T)
)
store<4,T,xyzw,stpq> {
union { union {
T data[4]; T data[4];
struct { T x,y,z,w; }; struct { T x,y,z,w; };