Module: Mesa Branch: master Commit: a42c846d246dc58f4f81bcfed026ea93e951c519 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=a42c846d246dc58f4f81bcfed026ea93e951c519
Author: Boris Brezillon <[email protected]> Date: Thu Jul 16 15:37:41 2020 +0200 nir: Fix nextafter() for hardware that don't support denorms We need to make sure we never return a denorm float, either by flushing the denorm to 0 or by adjusting the minimum non-zero value. v2 (Rhys): Use shader float controls execution mode instead of a dedicated option Signed-off-by: Boris Brezillon <[email protected]> Reviewed-by: Erik Faye-Lund <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7565> --- src/compiler/nir/nir_builtin_builder.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/compiler/nir/nir_builtin_builder.c b/src/compiler/nir/nir_builtin_builder.c index f78eae7c0bf..2301191bbc4 100644 --- a/src/compiler/nir/nir_builtin_builder.c +++ b/src/compiler/nir/nir_builtin_builder.c @@ -76,15 +76,37 @@ nir_nextafter(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y) nir_ssa_def *conddir = nir_flt(b, x, y); nir_ssa_def *condzero = nir_feq(b, x, zero); + uint64_t sign_mask = 1 << (x->bit_size - 1); + uint64_t min_abs = 1; + + if (nir_is_denorm_flush_to_zero(b->shader->info.float_controls_execution_mode, x->bit_size)) { + switch (x->bit_size) { + case 16: + min_abs = 1 << 10; + break; + case 32: + min_abs = 1 << 23; + break; + case 64: + min_abs = 1ULL << 52; + break; + } + + /* Flush denorm to zero to avoid returning a denorm when condeq is true. */ + x = nir_fmul(b, x, nir_imm_floatN_t(b, 1.0, x->bit_size)); + } + /* beware of: +/-0.0 - 1 == NaN */ nir_ssa_def *xn = nir_bcsel(b, condzero, - nir_imm_intN_t(b, (1 << (x->bit_size - 1)) + 1, x->bit_size), + nir_imm_intN_t(b, sign_mask | min_abs, x->bit_size), nir_isub(b, x, one)); /* beware of -0.0 + 1 == -0x1p-149 */ - nir_ssa_def *xp = nir_bcsel(b, condzero, one, nir_iadd(b, x, one)); + nir_ssa_def *xp = nir_bcsel(b, condzero, + nir_imm_intN_t(b, min_abs, x->bit_size), + nir_iadd(b, x, one)); /* nextafter can be implemented by just +/- 1 on the int value */ nir_ssa_def *res = _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
