1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef sw_Types_hpp
16 #define sw_Types_hpp
17
18 #include <limits>
19 #include <type_traits>
20
21 // GCC warns against bitfields not fitting the entire range of an enum with a fixed underlying type of unsigned int, which gets promoted to an error with -Werror and cannot be suppressed.
22 // However, GCC already defaults to using unsigned int as the underlying type of an unscoped enum without a fixed underlying type. So we can just omit it.
23 #if defined(__GNUC__) && !defined(__clang__)
24 namespace {
25 enum E
26 {
27 };
28 static_assert(!std::numeric_limits<std::underlying_type<E>::type>::is_signed, "expected unscoped enum whose underlying type is not fixed to be unsigned");
29 } // namespace
30 # define ENUM_UNDERLYING_TYPE_UNSIGNED_INT
31 #else
32 # define ENUM_UNDERLYING_TYPE_UNSIGNED_INT : unsigned int
33 #endif
34
35 #if defined(_MSC_VER)
36 typedef signed __int8 int8_t;
37 typedef signed __int16 int16_t;
38 typedef signed __int32 int32_t;
39 typedef signed __int64 int64_t;
40 typedef unsigned __int8 uint8_t;
41 typedef unsigned __int16 uint16_t;
42 typedef unsigned __int32 uint32_t;
43 typedef unsigned __int64 uint64_t;
44 # define ALIGN(bytes, type) __declspec(align(bytes)) type
45 #else
46 # include <stdint.h>
47 # define ALIGN(bytes, type) type __attribute__((aligned(bytes)))
48 #endif
49
50 namespace sw {
51
52 typedef ALIGN(1, uint8_t) byte;
53 typedef ALIGN(2, uint16_t) word;
54 typedef ALIGN(4, uint32_t) dword;
55 typedef ALIGN(8, uint64_t) qword;
56 typedef ALIGN(1, int8_t) sbyte;
57
58 template<typename T, int N>
59 struct alignas(sizeof(T) * N) vec
60 {
61 vec() = default;
62
vecsw::vec63 constexpr explicit vec(T replicate)
64 {
65 for(int i = 0; i < N; i++)
66 {
67 v[i] = replicate;
68 }
69 }
70
71 template<typename... ARGS>
vecsw::vec72 constexpr vec(T arg0, ARGS... args)
73 : v{ arg0, args... }
74 {
75 }
76
77 // Require explicit use of replicate constructor.
78 vec &operator=(T) = delete;
79
operator []sw::vec80 T &operator[](int i)
81 {
82 return v[i];
83 }
84
operator []sw::vec85 const T &operator[](int i) const
86 {
87 return v[i];
88 }
89
90 T v[N];
91 };
92
93 template<typename T>
94 struct alignas(sizeof(T) * 4) vec<T, 4>
95 {
96 vec() = default;
97
vecsw::vec98 constexpr explicit vec(T replicate)
99 : x(replicate)
100 , y(replicate)
101 , z(replicate)
102 , w(replicate)
103 {
104 }
105
vecsw::vec106 constexpr vec(T x, T y, T z, T w)
107 : x(x)
108 , y(y)
109 , z(z)
110 , w(w)
111 {
112 }
113
114 // Require explicit use of replicate constructor.
115 vec &operator=(T) = delete;
116
operator []sw::vec117 T &operator[](int i)
118 {
119 return v[i];
120 }
121
operator []sw::vec122 const T &operator[](int i) const
123 {
124 return v[i];
125 }
126
127 union
128 {
129 T v[4];
130
131 struct
132 {
133 T x;
134 T y;
135 T z;
136 T w;
137 };
138 };
139 };
140
141 template<typename T, int N>
operator ==(const vec<T,N> & a,const vec<T,N> & b)142 bool operator==(const vec<T, N> &a, const vec<T, N> &b)
143 {
144 for(int i = 0; i < N; i++)
145 {
146 if(a.v[i] != b.v[i])
147 {
148 return false;
149 }
150 }
151
152 return true;
153 }
154
155 template<typename T, int N>
operator !=(const vec<T,N> & a,const vec<T,N> & b)156 bool operator!=(const vec<T, N> &a, const vec<T, N> &b)
157 {
158 return !(a == b);
159 }
160
161 template<typename T>
162 using vec2 = vec<T, 2>;
163 template<typename T>
164 using vec4 = vec<T, 4>;
165 template<typename T>
166 using vec8 = vec<T, 8>;
167 template<typename T>
168 using vec16 = vec<T, 16>;
169
170 using int2 = vec2<int>;
171 using uint2 = vec2<unsigned int>;
172 using float2 = vec2<float>;
173 using dword2 = vec2<dword>;
174 using qword2 = vec2<qword>;
175
176 using int4 = vec4<int>;
177 using uint4 = vec4<unsigned int>;
178 using float4 = vec4<float>;
179 using byte4 = vec4<byte>;
180 using sbyte4 = vec4<sbyte>;
181 using short4 = vec4<short>;
182 using ushort4 = vec4<unsigned short>;
183 using word4 = vec4<word>;
184 using dword4 = vec4<dword>;
185
186 using byte8 = vec8<byte>;
187 using sbyte8 = vec8<sbyte>;
188 using short8 = vec8<short>;
189 using ushort8 = vec8<unsigned short>;
190
191 using byte16 = vec16<byte>;
192 using sbyte16 = vec16<sbyte>;
193
vector(float x,float y,float z,float w)194 inline constexpr float4 vector(float x, float y, float z, float w)
195 {
196 return float4{ x, y, z, w };
197 }
198
replicate(float f)199 inline constexpr float4 replicate(float f)
200 {
201 return vector(f, f, f, f);
202 }
203
204 #define OFFSET(s, m) (int)(size_t) & reinterpret_cast<const volatile char &>((((s *)0)->m))
205
206 } // namespace sw
207
208 #endif // sw_Types_hpp
209