7
7
#include < string>
8
8
#include < vector>
9
9
10
+ // A helper struct because C++ bools are 1 byte and HLSL bools are 4 bytes.
11
+ // Take int32_t as a constuctor argument and convert it to bool when needed.
12
+ // Comparisons cast to a bool because we only care if the bool representation is
13
+ // true or false.
14
+ struct HLSLBool_t {
15
+ HLSLBool_t () : Val(0 ) {}
16
+ HLSLBool_t (int32_t Val) : Val(Val) {}
17
+ HLSLBool_t (bool Val) : Val(Val) {}
18
+ HLSLBool_t (const HLSLBool_t &Other) : Val(Other.Val) {}
19
+
20
+ bool operator ==(const HLSLBool_t &Other) const {
21
+ return static_cast <bool >(Val) == static_cast <bool >(Other.Val );
22
+ }
23
+
24
+ bool operator !=(const HLSLBool_t &Other) const {
25
+ return static_cast <bool >(Val) != static_cast <bool >(Other.Val );
26
+ }
27
+
28
+ bool operator <(const HLSLBool_t &Other) const { return Val < Other.Val ; }
29
+
30
+ bool operator >(const HLSLBool_t &Other) const { return Val > Other.Val ; }
31
+
32
+ bool operator <=(const HLSLBool_t &Other) const { return Val <= Other.Val ; }
33
+
34
+ bool operator >=(const HLSLBool_t &Other) const { return Val >= Other.Val ; }
35
+
36
+ HLSLBool_t operator *(const HLSLBool_t &Other) const {
37
+ return HLSLBool_t (Val * Other.Val );
38
+ }
39
+
40
+ HLSLBool_t operator +(const HLSLBool_t &Other) const {
41
+ return HLSLBool_t (Val + Other.Val );
42
+ }
43
+
44
+ HLSLBool_t operator -(const HLSLBool_t &Other) const {
45
+ return HLSLBool_t (Val - Other.Val );
46
+ }
47
+
48
+ HLSLBool_t operator /(const HLSLBool_t &Other) const {
49
+ return HLSLBool_t (Val / Other.Val );
50
+ }
51
+
52
+ HLSLBool_t operator %(const HLSLBool_t &Other) const {
53
+ return HLSLBool_t (Val % Other.Val );
54
+ }
55
+
56
+ // So we can construct std::wstrings using std::wostream
57
+ friend std::wostream &operator <<(std::wostream &Os, const HLSLBool_t &Obj) {
58
+ Os << static_cast <bool >(Obj.Val );
59
+ return Os;
60
+ }
61
+
62
+ // So we can construct std::strings using std::ostream
63
+ friend std::ostream &operator <<(std::ostream &Os, const HLSLBool_t &Obj) {
64
+ Os << static_cast <bool >(Obj.Val );
65
+ return Os;
66
+ }
67
+
68
+ int32_t Val = 0 ;
69
+ };
70
+
71
+ // No native float16 type in C++ until C++23 . So we use uint16_t to represent
72
+ // it. Simple little wrapping struct to help handle the right behavior.
73
+ struct HLSLHalf_t {
74
+ HLSLHalf_t () : Val(0 ) {}
75
+ HLSLHalf_t (DirectX::PackedVector::HALF Val) : Val(Val) {}
76
+ HLSLHalf_t (const HLSLHalf_t &Other) : Val(Other.Val) {}
77
+ HLSLHalf_t (const float F) {
78
+ Val = DirectX::PackedVector::XMConvertFloatToHalf (F);
79
+ }
80
+ HLSLHalf_t (const double D) {
81
+ float F = 0 .0f ;
82
+ // We wrap '::max' in () to prevent it from being expanded as a
83
+ // macro by the Windows SDK.
84
+ if (D >= (std::numeric_limits<double >::max)())
85
+ F = (std::numeric_limits<float >::max)();
86
+ else if (D <= std::numeric_limits<double >::lowest ())
87
+ F = std::numeric_limits<float >::lowest ();
88
+ else
89
+ F = static_cast <float >(D);
90
+
91
+ Val = DirectX::PackedVector::XMConvertFloatToHalf (F);
92
+ }
93
+ HLSLHalf_t (const int I) {
94
+ VERIFY_IS_TRUE (I == 0 , L" HLSLHalf_t constructor with int override only "
95
+ L" meant for cases when initializing to 0." );
96
+ const float F = static_cast <float >(I);
97
+ Val = DirectX::PackedVector::XMConvertFloatToHalf (F);
98
+ }
99
+
100
+ // Implicit conversion to float for use with things like std::acos, std::tan,
101
+ // etc
102
+ operator float () const {
103
+ return DirectX::PackedVector::XMConvertHalfToFloat (Val);
104
+ }
105
+
106
+ bool operator ==(const HLSLHalf_t &Other) const {
107
+ // Convert to floats to properly handle the '0 == -0' case which must
108
+ // compare to true but have different uint16_t values.
109
+ // That is, 0 == -0 is true. We store Val as a uint16_t.
110
+ const float A = DirectX::PackedVector::XMConvertHalfToFloat (Val);
111
+ const float B = DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
112
+ return A == B;
113
+ }
114
+
115
+ bool operator <(const HLSLHalf_t &Other) const {
116
+ return DirectX::PackedVector::XMConvertHalfToFloat (Val) <
117
+ DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
118
+ }
119
+
120
+ bool operator >(const HLSLHalf_t &Other) const {
121
+ return DirectX::PackedVector::XMConvertHalfToFloat (Val) >
122
+ DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
123
+ }
124
+
125
+ // Used by tolerance checks in the tests.
126
+ bool operator >(float F) const {
127
+ const float A = DirectX::PackedVector::XMConvertHalfToFloat (Val);
128
+ return A > F;
129
+ }
130
+
131
+ bool operator <(float F) const {
132
+ const float A = DirectX::PackedVector::XMConvertHalfToFloat (Val);
133
+ return A < F;
134
+ }
135
+
136
+ bool operator <=(const HLSLHalf_t &Other) const {
137
+ return DirectX::PackedVector::XMConvertHalfToFloat (Val) <=
138
+ DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
139
+ }
140
+
141
+ bool operator >=(const HLSLHalf_t &Other) const {
142
+ return DirectX::PackedVector::XMConvertHalfToFloat (Val) >=
143
+ DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
144
+ }
145
+
146
+ bool operator !=(const HLSLHalf_t &Other) const { return Val != Other.Val ; }
147
+
148
+ HLSLHalf_t operator *(const HLSLHalf_t &Other) const {
149
+ const float A = DirectX::PackedVector::XMConvertHalfToFloat (Val);
150
+ const float B = DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
151
+ return HLSLHalf_t (DirectX::PackedVector::XMConvertFloatToHalf (A * B));
152
+ }
153
+
154
+ HLSLHalf_t operator +(const HLSLHalf_t &Other) const {
155
+ const float A = DirectX::PackedVector::XMConvertHalfToFloat (Val);
156
+ const float B = DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
157
+ return HLSLHalf_t (DirectX::PackedVector::XMConvertFloatToHalf (A + B));
158
+ }
159
+
160
+ HLSLHalf_t operator -(const HLSLHalf_t &Other) const {
161
+ const float A = DirectX::PackedVector::XMConvertHalfToFloat (Val);
162
+ const float B = DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
163
+ return HLSLHalf_t (DirectX::PackedVector::XMConvertFloatToHalf (A - B));
164
+ }
165
+
166
+ HLSLHalf_t operator /(const HLSLHalf_t &Other) const {
167
+ const float A = DirectX::PackedVector::XMConvertHalfToFloat (Val);
168
+ const float B = DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
169
+ return HLSLHalf_t (DirectX::PackedVector::XMConvertFloatToHalf (A / B));
170
+ }
171
+
172
+ HLSLHalf_t operator %(const HLSLHalf_t &Other) const {
173
+ const float A = DirectX::PackedVector::XMConvertHalfToFloat (Val);
174
+ const float B = DirectX::PackedVector::XMConvertHalfToFloat (Other.Val );
175
+ const float C = std::fmod (A, B);
176
+ return HLSLHalf_t (DirectX::PackedVector::XMConvertFloatToHalf (C));
177
+ }
178
+
179
+ // So we can construct std::wstrings using std::wostream
180
+ friend std::wostream &operator <<(std::wostream &Os, const HLSLHalf_t &Obj) {
181
+ Os << DirectX::PackedVector::XMConvertHalfToFloat (Obj.Val );
182
+ return Os;
183
+ }
184
+
185
+ // So we can construct std::wstrings using std::wostream
186
+ friend std::ostream &operator <<(std::ostream &Os, const HLSLHalf_t &Obj) {
187
+ Os << DirectX::PackedVector::XMConvertHalfToFloat (Obj.Val );
188
+ return Os;
189
+ }
190
+
191
+ // HALF is an alias to uint16_t
192
+ DirectX::PackedVector::HALF Val = 0 ;
193
+ };
194
+
10
195
template <typename T> struct LongVectorTestData {
11
196
static const std::map<std::wstring, std::vector<T>> Data;
12
197
};
13
198
199
+ template <> struct LongVectorTestData <HLSLBool_t> {
200
+ inline static const std::map<std::wstring, std::vector<HLSLBool_t>> Data = {
201
+ {L" DefaultInputValueSet1" ,
202
+ {false , true , false , false , false , false , true , true , true , true }},
203
+ {L" DefaultInputValueSet2" ,
204
+ {true , false , false , false , false , true , true , true , false , false }},
205
+ };
206
+ };
207
+
14
208
template <> struct LongVectorTestData <int16_t > {
15
209
inline static const std::map<std::wstring, std::vector<int16_t >> Data = {
16
210
{L" DefaultInputValueSet1" , {-6 , 1 , 7 , 3 , 8 , 4 , -3 , 8 , 8 , -2 }},
@@ -53,12 +247,36 @@ template <> struct LongVectorTestData<uint64_t> {
53
247
};
54
248
};
55
249
250
+ template <> struct LongVectorTestData <HLSLHalf_t> {
251
+ inline static const std::map<std::wstring, std::vector<HLSLHalf_t>> Data = {
252
+ {L" DefaultInputValueSet1" ,
253
+ {-1.0 , -1.0 , 1.0 , -0.01 , 1.0 , -0.01 , 1.0 , -0.01 , 1.0 , -0.01 }},
254
+ {L" DefaultInputValueSet2" ,
255
+ {1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 }},
256
+ {L" DefaultClampArgs" , {-1.0 , 1.0 }}, // Min, Max values for clamp
257
+ // Range [ -pi/2, pi/2]
258
+ {L" TrigonometricInputValueSet_RangeHalfPi" ,
259
+ {-1.073 , 0.044 , -1.047 , 0.313 , 1.447 , -0.865 , 1.364 , -0.715 , -0.800 ,
260
+ 0.541 }},
261
+ {L" TrigonometricInputValueSet_RangeOne" ,
262
+ {0.331 , 0.727 , -0.957 , 0.677 , -0.025 , 0.495 , 0.855 , -0.673 , -0.678 ,
263
+ -0.905 }},
264
+ };
265
+ };
266
+
56
267
template <> struct LongVectorTestData <float > {
57
268
inline static const std::map<std::wstring, std::vector<float >> Data = {
58
269
{L" DefaultInputValueSet1" ,
59
270
{1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 }},
60
271
{L" DefaultInputValueSet2" ,
61
272
{1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 }},
273
+ // Range [ -pi/2, pi/2]
274
+ {L" TrigonometricInputValueSet_RangeHalfPi" ,
275
+ {0 .315f , -0 .316f , 1 .409f , -0 .09f , -1 .569f , 1 .302f , -0 .326f , 0 .781f ,
276
+ -1 .235f , 0 .623f }},
277
+ {L" TrigonometricInputValueSet_RangeOne" ,
278
+ {0 .727f , 0 .331f , -0 .957f , 0 .677f , -0 .025f , 0 .495f , 0 .855f , -0 .673f ,
279
+ -0 .678f , -0 .905f }},
62
280
};
63
281
};
64
282
@@ -68,7 +286,13 @@ template <> struct LongVectorTestData<double> {
68
286
{1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 }},
69
287
{L" DefaultInputValueSet2" ,
70
288
{1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0 }},
71
- };
289
+ // Range [ -pi/2, pi/2]
290
+ {L" TrigonometricInputValueSet_RangeHalfPi" ,
291
+ {0.807 , 0.605 , 1.317 , 0.188 , 1.566 , -1.507 , 0.67 , -1.553 , 0.194 ,
292
+ -0.883 }},
293
+ {L" TrigonometricInputValueSet_RangeOne" ,
294
+ {0.331 , 0.277 , -0.957 , 0.677 , -0.025 , 0.495 , 0.855 , -0.673 , -0.678 ,
295
+ -0.905 }}};
72
296
};
73
297
74
298
#endif // LONGVECTORTESTDATA_H
0 commit comments