* @brief Convert float to 16-bit LNS. */
| 580 | * @brief Convert float to 16-bit LNS. |
| 581 | */ |
| 582 | static ASTCENC_SIMD_INLINE vfloat4 float_to_lns(vfloat4 a) |
| 583 | { |
| 584 | vint4 exp; |
| 585 | vfloat4 mant = frexp(a, exp); |
| 586 | |
| 587 | // Do these early before we start messing about ... |
| 588 | vmask4 mask_underflow_nan = ~(a > vfloat4(1.0f / 67108864.0f)); |
| 589 | vmask4 mask_infinity = a >= vfloat4(65536.0f); |
| 590 | |
| 591 | // If input is smaller than 2^-14, multiply by 2^25 and don't bias. |
| 592 | vmask4 exp_lt_m13 = exp < vint4(-13); |
| 593 | |
| 594 | vfloat4 a1a = a * 33554432.0f; |
| 595 | vint4 expa = vint4::zero(); |
| 596 | |
| 597 | vfloat4 a1b = (mant - 0.5f) * 4096; |
| 598 | vint4 expb = exp + 14; |
| 599 | |
| 600 | a = select(a1b, a1a, exp_lt_m13); |
| 601 | exp = select(expb, expa, exp_lt_m13); |
| 602 | |
| 603 | vmask4 a_lt_384 = a < vfloat4(384.0f); |
| 604 | vmask4 a_lt_1408 = a <= vfloat4(1408.0f); |
| 605 | |
| 606 | vfloat4 a2a = a * (4.0f / 3.0f); |
| 607 | vfloat4 a2b = a + 128.0f; |
| 608 | vfloat4 a2c = (a + 512.0f) * (4.0f / 5.0f); |
| 609 | |
| 610 | a = a2c; |
| 611 | a = select(a, a2b, a_lt_1408); |
| 612 | a = select(a, a2a, a_lt_384); |
| 613 | |
| 614 | a = a + (int_to_float(exp) * 2048.0f) + 1.0f; |
| 615 | |
| 616 | a = select(a, vfloat4(65535.0f), mask_infinity); |
| 617 | a = select(a, vfloat4::zero(), mask_underflow_nan); |
| 618 | |
| 619 | return a; |
| 620 | } |
| 621 | |
| 622 | namespace astc |
| 623 | { |
no test coverage detected