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 
shortAsHalf(short s)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:
toRGB16F(half rgb[3]) const56 		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 
float11ToFloat16(unsigned short fp11)73 		static inline half float11ToFloat16(unsigned short fp11)
74 		{
75 			return shortAsHalf(fp11 << 4);   // Sign bit 0
76 		}
77 
float10ToFloat16(unsigned short fp10)78 		static inline half float10ToFloat16(unsigned short fp10)
79 		{
80 			return shortAsHalf(fp10 << 5);   // Sign bit 0
81 		}
82 
83 	public:
toRGB16F(half rgb[3]) const84 		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