Commit ac160bd3 by Ben Clayton

System/Types: Add support for vec3

Non-power of two vector types were previously not supported as they would be misaligned. Use a `constexpr` function to ensure the `alignas` is rounded to the next POT. While the memory layout for vec3 will be identical to a vec4, this allows us to specialize templates to distinguish between `vec3` and `vec4`. This is used by the debugger to display `vec3` locals without showing an undefined `w` component. Bug: b/145351270 Change-Id: I61f61e42e69d367b1a625c262be970994b287433 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/48708Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com>
parent b61d9d76
...@@ -49,6 +49,19 @@ typedef unsigned __int64 uint64_t; ...@@ -49,6 +49,19 @@ typedef unsigned __int64 uint64_t;
namespace sw { namespace sw {
// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
constexpr inline uint32_t bit_ceil(uint32_t i)
{
i--;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i++;
return i;
}
typedef ALIGN(1, uint8_t) byte; typedef ALIGN(1, uint8_t) byte;
typedef ALIGN(2, uint16_t) word; typedef ALIGN(2, uint16_t) word;
typedef ALIGN(4, uint32_t) dword; typedef ALIGN(4, uint32_t) dword;
...@@ -56,7 +69,7 @@ typedef ALIGN(8, uint64_t) qword; ...@@ -56,7 +69,7 @@ typedef ALIGN(8, uint64_t) qword;
typedef ALIGN(1, int8_t) sbyte; typedef ALIGN(1, int8_t) sbyte;
template<typename T, int N> template<typename T, int N>
struct alignas(sizeof(T) * N) vec struct alignas(sizeof(T) * bit_ceil(N)) vec
{ {
vec() = default; vec() = default;
...@@ -161,6 +174,8 @@ bool operator!=(const vec<T, N> &a, const vec<T, N> &b) ...@@ -161,6 +174,8 @@ bool operator!=(const vec<T, N> &a, const vec<T, N> &b)
template<typename T> template<typename T>
using vec2 = vec<T, 2>; using vec2 = vec<T, 2>;
template<typename T> template<typename T>
using vec3 = vec<T, 3>; // aligned to 4 elements
template<typename T>
using vec4 = vec<T, 4>; using vec4 = vec<T, 4>;
template<typename T> template<typename T>
using vec8 = vec<T, 8>; using vec8 = vec<T, 8>;
...@@ -173,6 +188,13 @@ using float2 = vec2<float>; ...@@ -173,6 +188,13 @@ using float2 = vec2<float>;
using dword2 = vec2<dword>; using dword2 = vec2<dword>;
using qword2 = vec2<qword>; using qword2 = vec2<qword>;
// Note: These vec3<T> types all use 4-element alignment - i.e. they have
// identical memory layout to vec4<T>, except they do not have a 4th component.
using int3 = vec3<int>;
using uint3 = vec3<unsigned int>;
using float3 = vec3<float>;
using dword3 = vec3<dword>;
using int4 = vec4<int>; using int4 = vec4<int>;
using uint4 = vec4<unsigned int>; using uint4 = vec4<unsigned int>;
using float4 = vec4<float>; using float4 = vec4<float>;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment