* @brief Convert float to 16-bit LNS. */
| 556 | * @brief Convert float to 16-bit LNS. |
| 557 | */ |
| 558 | static ASTCENC_SIMD_INLINE vfloat4 float_to_lns(vfloat4 a) |
| 559 | { |
| 560 | vint4 exp; |
| 561 | vfloat4 mant = frexp(a, exp); |
| 562 | |
| 563 | // Do these early before we start messing about ... |
| 564 | vmask4 mask_underflow_nan = ~(a > vfloat4(1.0f / 67108864.0f)); |
| 565 | vmask4 mask_infinity = a >= vfloat4(65536.0f); |
| 566 | |
| 567 | // If input is smaller than 2^-14, multiply by 2^25 and don't bias. |
| 568 | vmask4 exp_lt_m13 = exp < vint4(-13); |
| 569 | |
| 570 | vfloat4 a1a = a * 33554432.0f; |
| 571 | vint4 expa = vint4::zero(); |
| 572 | |
| 573 | vfloat4 a1b = (mant - 0.5f) * 4096; |
| 574 | vint4 expb = exp + 14; |
| 575 | |
| 576 | a = select(a1b, a1a, exp_lt_m13); |
| 577 | exp = select(expb, expa, exp_lt_m13); |
| 578 | |
| 579 | vmask4 a_lt_384 = a < vfloat4(384.0f); |
| 580 | vmask4 a_lt_1408 = a <= vfloat4(1408.0f); |
| 581 | |
| 582 | vfloat4 a2a = a * (4.0f / 3.0f); |
| 583 | vfloat4 a2b = a + 128.0f; |
| 584 | vfloat4 a2c = (a + 512.0f) * (4.0f / 5.0f); |
| 585 | |
| 586 | a = a2c; |
| 587 | a = select(a, a2b, a_lt_1408); |
| 588 | a = select(a, a2a, a_lt_384); |
| 589 | |
| 590 | a = a + (int_to_float(exp) * 2048.0f) + 1.0f; |
| 591 | |
| 592 | a = select(a, vfloat4(65535.0f), mask_infinity); |
| 593 | a = select(a, vfloat4::zero(), mask_underflow_nan); |
| 594 | |
| 595 | return a; |
| 596 | } |
| 597 | |
| 598 | namespace astc |
| 599 | { |
no test coverage detected