OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkHalf_DEFINED | 8 #ifndef SkHalf_DEFINED |
9 #define SkHalf_DEFINED | 9 #define SkHalf_DEFINED |
10 | 10 |
11 #include "SkCpu.h" | |
12 #include "SkNx.h" | 11 #include "SkNx.h" |
13 #include "SkTypes.h" | 12 #include "SkTypes.h" |
14 | 13 |
15 // 16-bit floating point value | 14 // 16-bit floating point value |
16 // format is 1 bit sign, 5 bits exponent, 10 bits mantissa | 15 // format is 1 bit sign, 5 bits exponent, 10 bits mantissa |
17 // only used for storage | 16 // only used for storage |
18 typedef uint16_t SkHalf; | 17 typedef uint16_t SkHalf; |
19 | 18 |
20 #define SK_HalfMin 0x0400 // 2^-24 (minimum positive normal value) | 19 #define SK_HalfMin 0x0400 // 2^-24 (minimum positive normal value) |
21 #define SK_HalfMax 0x7bff // 65504 | 20 #define SK_HalfMax 0x7bff // 65504 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 } | 115 } |
117 r = (uint64_t)hs[3] << 48 | 116 r = (uint64_t)hs[3] << 48 |
118 | (uint64_t)hs[2] << 32 | 117 | (uint64_t)hs[2] << 32 |
119 | (uint64_t)hs[1] << 16 | 118 | (uint64_t)hs[1] << 16 |
120 | (uint64_t)hs[0] << 0; | 119 | (uint64_t)hs[0] << 0; |
121 #endif | 120 #endif |
122 return r; | 121 return r; |
123 } | 122 } |
124 | 123 |
125 #endif | 124 #endif |
126 | |
127 static inline Sk4f SkHalfToFloat_01(const uint64_t* hs) { | |
128 #if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 | |
129 if (SkCpu::Supports(SkCpu::F16C)) { | |
130 __m128 fs; | |
131 #if defined(__GNUC__) || defined(__clang__) | |
132 asm("vcvtph2ps %[hs], %[fs]" : [fs]"=x"(fs) : [hs]"m"(*hs)); | |
133 #else | |
134 fs = _mm_cvtph_ps(_mm_loadl_epi64((const __m128i*)hs)); | |
135 #endif | |
136 return fs; | |
137 } | |
138 #endif | |
139 return SkHalfToFloat_01(*hs); | |
140 } | |
141 | |
142 static inline void SkFloatToHalf_01(const Sk4f& fs, uint64_t* hs) { | |
143 #if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 | |
144 if (SkCpu::Supports(SkCpu::F16C)) { | |
145 #if defined(__GNUC__) || defined(__clang__) | |
146 asm("vcvtps2ph $0, %[fs], %[hs]" : [hs]"=m"(*hs) : [fs]"x"(fs.fVec)); | |
147 #else | |
148 _mm_storel_epi64((__m128i*)hs, _mm_cvtps_ph(fs.fVec, 0)); | |
149 #endif | |
150 return; | |
151 } | |
152 #endif | |
153 *hs = SkFloatToHalf_01(fs); | |
154 } | |
OLD | NEW |