~mir-team/mir/in-process-egl+input-conglomeration

« back to all changes in this revision

Viewing changes to 3rd_party/glm/glm/core/type_half.inl

Merged trunk and fixed issues

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
///////////////////////////////////////////////////////////////////////////////////
2
 
/// OpenGL Mathematics (glm.g-truc.net)
3
 
///
4
 
/// Copyright (c) 2005 - 2012 G-Truc Creation (www.g-truc.net)
5
 
/// Permission is hereby granted, free of charge, to any person obtaining a copy
6
 
/// of this software and associated documentation files (the "Software"), to deal
7
 
/// in the Software without restriction, including without limitation the rights
8
 
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 
/// copies of the Software, and to permit persons to whom the Software is
10
 
/// furnished to do so, subject to the following conditions:
11
 
/// 
12
 
/// The above copyright notice and this permission notice shall be included in
13
 
/// all copies or substantial portions of the Software.
14
 
/// 
15
 
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
 
/// THE SOFTWARE.
22
 
///
23
 
/// @ref core
24
 
/// @file glm/core/type_half.inl
25
 
/// @date 2008-08-17 / 2011-06-15
26
 
/// @author Christophe Riccio
27
 
///
28
 
/// Copyright:
29
 
/// This half implementation is based on OpenEXR which is Copyright (c) 2002, 
30
 
/// Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
31
 
///////////////////////////////////////////////////////////////////////////////////
32
 
 
33
 
#include "_detail.hpp"
34
 
 
35
 
namespace glm{
36
 
namespace detail
37
 
{
38
 
        GLM_FUNC_QUALIFIER float overflow()
39
 
        {
40
 
                volatile float f = 1e10;
41
 
 
42
 
                for(int i = 0; i < 10; ++i)     
43
 
                        f *= f;             // this will overflow before
44
 
                                                                // the for�loop terminates
45
 
                return f;
46
 
        }
47
 
 
48
 
        GLM_FUNC_QUALIFIER float toFloat32(hdata value)
49
 
        {
50
 
                int s = (value >> 15) & 0x00000001;
51
 
                int e = (value >> 10) & 0x0000001f;
52
 
                int m =  value        & 0x000003ff;
53
 
 
54
 
                if(e == 0)
55
 
                {
56
 
                        if(m == 0)
57
 
                        {
58
 
                                //
59
 
                                // Plus or minus zero
60
 
                                //
61
 
 
62
 
                                detail::uif result;
63
 
                                result.i = (unsigned int)(s << 31);
64
 
                                return result.f;
65
 
                        }
66
 
                        else
67
 
                        {
68
 
                                //
69
 
                                // Denormalized number -- renormalize it
70
 
                                //
71
 
 
72
 
                                while(!(m & 0x00000400))
73
 
                                {
74
 
                                        m <<= 1;
75
 
                                        e -=  1;
76
 
                                }
77
 
 
78
 
                                e += 1;
79
 
                                m &= ~0x00000400;
80
 
                        }
81
 
                }
82
 
                else if(e == 31)
83
 
                {
84
 
                        if(m == 0)
85
 
                        {
86
 
                                //
87
 
                                // Positive or negative infinity
88
 
                                //
89
 
 
90
 
                                uif result;
91
 
                                result.i = (unsigned int)((s << 31) | 0x7f800000);
92
 
                                return result.f;
93
 
                        }
94
 
                        else
95
 
                        {
96
 
                                //
97
 
                                // Nan -- preserve sign and significand bits
98
 
                                //
99
 
 
100
 
                                uif result;
101
 
                                result.i = (unsigned int)((s << 31) | 0x7f800000 | (m << 13));
102
 
                                return result.f;
103
 
                        }
104
 
                }
105
 
 
106
 
                //
107
 
                // Normalized number
108
 
                //
109
 
 
110
 
                e = e + (127 - 15);
111
 
                m = m << 13;
112
 
 
113
 
                //
114
 
                // Assemble s, e and m.
115
 
                //
116
 
 
117
 
                uif Result;
118
 
                Result.i = (unsigned int)((s << 31) | (e << 23) | m);
119
 
                return Result.f;
120
 
        }
121
 
 
122
 
        GLM_FUNC_QUALIFIER hdata toFloat16(float const & f)
123
 
        {
124
 
                uif Entry;
125
 
                Entry.f = f;
126
 
                int i = (int)Entry.i;
127
 
 
128
 
                //
129
 
                // Our floating point number, f, is represented by the bit
130
 
                // pattern in integer i.  Disassemble that bit pattern into
131
 
                // the sign, s, the exponent, e, and the significand, m.
132
 
                // Shift s into the position where it will go in in the
133
 
                // resulting half number.
134
 
                // Adjust e, accounting for the different exponent bias
135
 
                // of float and half (127 versus 15).
136
 
                //
137
 
 
138
 
                register int s =  (i >> 16) & 0x00008000;
139
 
                register int e = ((i >> 23) & 0x000000ff) - (127 - 15);
140
 
                register int m =   i        & 0x007fffff;
141
 
 
142
 
                //
143
 
                // Now reassemble s, e and m into a half:
144
 
                //
145
 
 
146
 
                if(e <= 0)
147
 
                {
148
 
                        if(e < -10)
149
 
                        {
150
 
                                //
151
 
                                // E is less than -10.  The absolute value of f is
152
 
                                // less than half_MIN (f may be a small normalized
153
 
                                // float, a denormalized float or a zero).
154
 
                                //
155
 
                                // We convert f to a _halfGTX zero.
156
 
                                //
157
 
 
158
 
                                return 0;
159
 
                        }
160
 
 
161
 
                        //
162
 
                        // E is between -10 and 0.  F is a normalized float,
163
 
                        // whose magnitude is less than __half_NRM_MIN.
164
 
                        //
165
 
                        // We convert f to a denormalized _halfGTX.
166
 
                        // 
167
 
 
168
 
                        m = (m | 0x00800000) >> (1 - e);
169
 
 
170
 
                        //
171
 
                        // Round to nearest, round "0.5" up.
172
 
                        //
173
 
                        // Rounding may cause the significand to overflow and make
174
 
                        // our number normalized.  Because of the way a half's bits
175
 
                        // are laid out, we don't have to treat this case separately;
176
 
                        // the code below will handle it correctly.
177
 
                        // 
178
 
 
179
 
                        if(m & 0x00001000) 
180
 
                                m += 0x00002000;
181
 
 
182
 
                        //
183
 
                        // Assemble the _halfGTX from s, e (zero) and m.
184
 
                        //
185
 
 
186
 
                        return hdata(s | (m >> 13));
187
 
                }
188
 
                else if(e == 0xff - (127 - 15))
189
 
                {
190
 
                        if(m == 0)
191
 
                        {
192
 
                                //
193
 
                                // F is an infinity; convert f to a half
194
 
                                // infinity with the same sign as f.
195
 
                                //
196
 
 
197
 
                                return hdata(s | 0x7c00);
198
 
                        }
199
 
                        else
200
 
                        {
201
 
                                //
202
 
                                // F is a NAN; we produce a half NAN that preserves
203
 
                                // the sign bit and the 10 leftmost bits of the
204
 
                                // significand of f, with one exception: If the 10
205
 
                                // leftmost bits are all zero, the NAN would turn 
206
 
                                // into an infinity, so we have to set at least one
207
 
                                // bit in the significand.
208
 
                                //
209
 
 
210
 
                                m >>= 13;
211
 
 
212
 
                                return hdata(s | 0x7c00 | m | (m == 0));
213
 
                        }
214
 
                }
215
 
                else
216
 
                {
217
 
                        //
218
 
                        // E is greater than zero.  F is a normalized float.
219
 
                        // We try to convert f to a normalized half.
220
 
                        //
221
 
 
222
 
                        //
223
 
                        // Round to nearest, round "0.5" up
224
 
                        //
225
 
 
226
 
                        if(m &  0x00001000)
227
 
                        {
228
 
                                m += 0x00002000;
229
 
 
230
 
                                if(m & 0x00800000)
231
 
                                {
232
 
                                        m =  0;     // overflow in significand,
233
 
                                        e += 1;     // adjust exponent
234
 
                                }
235
 
                        }
236
 
 
237
 
                        //
238
 
                        // Handle exponent overflow
239
 
                        //
240
 
 
241
 
                        if (e > 30)
242
 
                        {
243
 
                                overflow();        // Cause a hardware floating point overflow;
244
 
 
245
 
                                return hdata(s | 0x7c00);
246
 
                                // if this returns, the half becomes an
247
 
                        }   // infinity with the same sign as f.
248
 
 
249
 
                        //
250
 
                        // Assemble the half from s, e and m.
251
 
                        //
252
 
 
253
 
                        return hdata(s | (e << 10) | (m >> 13));
254
 
                }
255
 
        }
256
 
 
257
 
        GLM_FUNC_QUALIFIER half::half() :
258
 
                data(0)
259
 
        {}
260
 
 
261
 
        GLM_FUNC_QUALIFIER half::half(half const & s) :
262
 
                data(s.data)
263
 
        {}
264
 
 
265
 
        template <typename U>
266
 
        GLM_FUNC_QUALIFIER half::half(U const & s) :
267
 
                data(toFloat16(float(s)))
268
 
        {}
269
 
 
270
 
        template <typename U>
271
 
        GLM_FUNC_QUALIFIER half::operator U() const
272
 
        {
273
 
                return static_cast<U>(toFloat32(this->data));
274
 
        }
275
 
 
276
 
        // Unary updatable operators
277
 
        GLM_FUNC_QUALIFIER half& half::operator= (half const & s)
278
 
        {
279
 
                data = s.data;
280
 
                return *this;
281
 
        }
282
 
 
283
 
        GLM_FUNC_QUALIFIER half& half::operator+=(half const & s)
284
 
        {
285
 
                data = toFloat16(toFloat32(data) + toFloat32(s.data));
286
 
                return *this;
287
 
        }
288
 
 
289
 
        GLM_FUNC_QUALIFIER half& half::operator-=(half const & s)
290
 
        {
291
 
                data = toFloat16(toFloat32(data) - toFloat32(s.data));
292
 
                return *this;
293
 
        }
294
 
 
295
 
        GLM_FUNC_QUALIFIER half& half::operator*=(half const & s)
296
 
        {
297
 
                data = toFloat16(toFloat32(data) * toFloat32(s.data));          
298
 
                return *this;
299
 
        }
300
 
 
301
 
        GLM_FUNC_QUALIFIER half& half::operator/=(half const & s)
302
 
        {
303
 
                data = toFloat16(toFloat32(data) / toFloat32(s.data));
304
 
                return *this;
305
 
        }
306
 
 
307
 
        GLM_FUNC_QUALIFIER half& half::operator++()
308
 
        {
309
 
                float Casted = toFloat32(data);
310
 
                this->data = toFloat16(++Casted);
311
 
                return *this;
312
 
        }
313
 
 
314
 
        GLM_FUNC_QUALIFIER half& half::operator--()
315
 
        {
316
 
                float Casted = toFloat32(data);
317
 
                this->data = toFloat16(--Casted);
318
 
                return *this;
319
 
        }
320
 
 
321
 
        //////////////////////////////////////
322
 
        // Binary arithmetic operators
323
 
 
324
 
        GLM_FUNC_QUALIFIER detail::half operator+ (detail::half const & s1, detail::half const & s2)
325
 
        {
326
 
                return detail::half(float(s1) + float(s2));
327
 
        }
328
 
 
329
 
        GLM_FUNC_QUALIFIER detail::half operator- (detail::half const & s1, detail::half const & s2)
330
 
        {
331
 
                return detail::half(float(s1) - float(s2));
332
 
        }
333
 
 
334
 
        GLM_FUNC_QUALIFIER detail::half operator* (detail::half const & s1, detail::half const & s2)
335
 
        {
336
 
                return detail::half(float(s1) * float(s2));
337
 
        }
338
 
 
339
 
        GLM_FUNC_QUALIFIER detail::half operator/ (detail::half const & s1, detail::half const & s2)
340
 
        {
341
 
                return detail::half(float(s1) / float(s2));
342
 
        }
343
 
 
344
 
        // Unary constant operators
345
 
        GLM_FUNC_QUALIFIER detail::half operator- (detail::half const & s)
346
 
        {
347
 
                return detail::half(-float(s));
348
 
        }
349
 
 
350
 
        GLM_FUNC_QUALIFIER detail::half operator-- (detail::half const & s, int)
351
 
        {
352
 
                return detail::half(float(s) - 1.0f);
353
 
        }
354
 
 
355
 
        GLM_FUNC_QUALIFIER detail::half operator++ (detail::half const & s, int)
356
 
        {
357
 
                return detail::half(float(s) + 1.0f);
358
 
        }
359
 
 
360
 
        GLM_FUNC_QUALIFIER bool operator==
361
 
        (
362
 
                detail::half const & x, 
363
 
                detail::half const & y
364
 
        )
365
 
        {
366
 
                return x._data() == y._data();
367
 
        }
368
 
 
369
 
        GLM_FUNC_QUALIFIER bool operator!=
370
 
        (
371
 
                detail::half const & x, 
372
 
                detail::half const & y
373
 
        )
374
 
        {
375
 
                return x._data() != y._data();
376
 
        }
377
 
 
378
 
        GLM_FUNC_QUALIFIER bool operator<
379
 
        (
380
 
                detail::half const & x, 
381
 
                detail::half const & y
382
 
        )
383
 
        {
384
 
                return float(x) < float(y);
385
 
        }
386
 
 
387
 
        GLM_FUNC_QUALIFIER bool operator<=
388
 
        (
389
 
                detail::half const & x, 
390
 
                detail::half const & y
391
 
        )
392
 
        {
393
 
                return float(x) <= float(y);
394
 
        }
395
 
 
396
 
        GLM_FUNC_QUALIFIER bool operator>
397
 
        (
398
 
                detail::half const & x, 
399
 
                detail::half const & y
400
 
        )
401
 
        {
402
 
                return float(x) > float(y);
403
 
        }
404
 
 
405
 
        GLM_FUNC_QUALIFIER bool operator>=
406
 
        (
407
 
                detail::half const & x, 
408
 
                detail::half const & y
409
 
        )
410
 
        {
411
 
                return float(x) >= float(y);
412
 
        }
413
 
 
414
 
}//namespace detail
415
 
}//namespace glm