OpenVDB 13.2.0
Loading...
Searching...
No Matches
HalfLite.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3//
4// The functions HalfToFloat and FloatToHalf are derived from Imath's
5// imath_half_to_float / imath_float_to_half (Imath/half.h):
6// Copyright Contributors to the OpenEXR Project
7// SPDX-License-Identifier: BSD-3-Clause
8// Primary original authors: Florian Kainz, Rod Bogart
9
10#ifndef NANOVDB_MATH_HALF_LITE_HAS_BEEN_INCLUDED
11#define NANOVDB_MATH_HALF_LITE_HAS_BEEN_INCLUDED
12
13#include <nanovdb/util/Util.h>// for __hostdev__ and lots of other utility functions
14
15namespace nanovdb {// =================================================================
16
17namespace math {// =============================================================
18
19// Standalone scalar conversions extracted from Half.h. Assumes IEEE 754
20// binary32 floats and binary16 half bits; uses no intrinsics or lookup tables.
22{
23 uint32_t i;
24 float f;
25};
26
27inline __hostdev__ float HalfToFloat(uint16_t h_raw)
28{
29 HalfUnion v;
30 uint32_t hexpmant = ((uint32_t)(h_raw) << 17) >> 4;
31 v.i = ((uint32_t)(h_raw >> 15)) << 31;
32
33 if (hexpmant >= 0x00800000)
34 {
35 v.i |= hexpmant;
36 if (hexpmant < 0x0f800000)
37 v.i += 0x38000000;
38 else
39 v.i |= 0x7f800000;
40 }
41 else if (hexpmant != 0)
42 {
43 // Normalize a subnormal using a portable count-leading-zeros loop.
44 uint32_t lc = 0;
45 while (0 == ((hexpmant << lc) & 0x80000000))
46 ++lc;
47 lc -= 8;
48 v.i |= 0x38800000;
49 v.i |= (hexpmant << lc);
50 v.i -= (lc << 23);
51 }
52 return v.f;
53}
54
55// Round to nearest, with ties to even. Overflow produces signed infinity.
56inline __hostdev__ uint16_t FloatToHalf(float f)
57{
58 HalfUnion v;
59 uint16_t h_raw;
60 uint32_t e, m, ui, r, shift;
61
62 v.f = f;
63 ui = (v.i & ~0x80000000);
64 h_raw = ((v.i >> 16) & 0x8000);
65
66 if (ui >= 0x38800000)
67 {
68 // Infinity or NaN: preserve the sign and available payload bits.
69 if (ui >= 0x7f800000)
70 {
71 h_raw |= 0x7c00;
72 if (ui == 0x7f800000)
73 return h_raw;
74 m = (ui & 0x7fffff) >> 13;
75 return h_raw | (uint16_t)m | (uint16_t)(m == 0);
76 }
77
78 if (ui > 0x477fefff)
79 return h_raw | 0x7c00;
80
81 ui -= 0x38000000;
82 ui = ((ui + 0x00000fff + ((ui >> 13) & 1)) >> 13);
83 return h_raw | (uint16_t)ui;
84 }
85
86 // Zero or a value that rounds to zero.
87 if (ui < 0x33000001)
88 return h_raw;
89
90 // Produce a subnormal half.
91 e = (ui >> 23);
92 shift = 0x7e - e;
93 m = 0x800000 | (ui & 0x7fffff);
94 r = m << (32 - shift);
95 h_raw |= (m >> shift);
96 if (r > 0x80000000 || (r == 0x80000000 && (h_raw & 0x1) != 0))
97 ++h_raw;
98 return h_raw;
99}
100
101} // namespace math ===============================================================
102
103} // namespace nanovdb ===================================================================
104
105#endif // NANOVDB_MATH_HALF_LITE_HAS_BEEN_INCLUDED
#define __hostdev__
Definition SampleFromVoxels.h:29
Definition DitherLUT.h:19
__hostdev__ uint16_t FloatToHalf(float f)
Definition HalfLite.h:56
__hostdev__ float HalfToFloat(uint16_t h_raw)
Definition HalfLite.h:27
Defines a simple memory pool used to call cub functions that use dynamic temporary storage.
Definition GridHandle.h:32
Utility functions.
Definition HalfLite.h:22
uint32_t i
Definition HalfLite.h:23
float f
Definition HalfLite.h:24