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_Half_hpp |
16 | #define sw_Half_hpp |
17 | |
18 | namespace sw |
19 | { |
20 | class half |
21 | { |
22 | public: |
23 | half() = default; |
24 | explicit half(float f); |
25 | |
26 | operator float() const; |
27 | |
28 | half &operator=(half h); |
29 | half &operator=(float f); |
30 | |
31 | private: |
32 | unsigned short fp16i; |
33 | }; |
34 | |
35 | inline half shortAsHalf(short s) |
36 | { |
37 | union |
38 | { |
39 | half h; |
40 | short s; |
41 | } hs; |
42 | |
43 | hs.s = s; |
44 | |
45 | return hs.h; |
46 | } |
47 | |
48 | class RGB9E5 |
49 | { |
50 | unsigned int R : 9; |
51 | unsigned int G : 9; |
52 | unsigned int B : 9; |
53 | unsigned int E : 5; |
54 | |
55 | public: |
56 | void toRGB16F(half rgb[3]) const |
57 | { |
58 | constexpr int offset = 24; // Exponent bias (15) + number of mantissa bits per component (9) = 24 |
59 | |
60 | const float factor = (1u << E) * (1.0f / (1 << offset)); |
61 | rgb[0] = half(R * factor); |
62 | rgb[1] = half(G * factor); |
63 | rgb[2] = half(B * factor); |
64 | } |
65 | }; |
66 | |
67 | class R11G11B10F |
68 | { |
69 | unsigned int R : 11; |
70 | unsigned int G : 11; |
71 | unsigned int B : 10; |
72 | |
73 | static inline half float11ToFloat16(unsigned short fp11) |
74 | { |
75 | return shortAsHalf(fp11 << 4); // Sign bit 0 |
76 | } |
77 | |
78 | static inline half float10ToFloat16(unsigned short fp10) |
79 | { |
80 | return shortAsHalf(fp10 << 5); // Sign bit 0 |
81 | } |
82 | |
83 | public: |
84 | void toRGB16F(half rgb[3]) const |
85 | { |
86 | rgb[0] = float11ToFloat16(R); |
87 | rgb[1] = float11ToFloat16(G); |
88 | rgb[2] = float10ToFloat16(B); |
89 | } |
90 | }; |
91 | } |
92 | |
93 | #endif // sw_Half_hpp |
94 | |