mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 00:38:48 +02:00
nir: fix nir_round_int_to_float for fp16
fp16 has quite the limited value range and with bigger integers
nir_round_int_to_float might return Inf where it shouldn't depending on
the rounding mode.
Fixes conversions half_rt[npz]_(u)?(int|long) CL CTS tests.
Cc: mesa-stable
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Reviewed-by: Rob Clark <rob.clark@oss.qualcomm.com>
(cherry picked from commit e1ed7de274)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40359>
This commit is contained in:
parent
3d8ff40d58
commit
d29063d4f2
3 changed files with 26 additions and 1 deletions
|
|
@ -3444,7 +3444,7 @@
|
|||
"description": "nir: fix nir_round_int_to_float for fp16",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null,
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#ifndef NIR_CONVERSION_BUILDER_H
|
||||
#define NIR_CONVERSION_BUILDER_H
|
||||
|
||||
#include "util/half_float.h"
|
||||
#include "util/u_math.h"
|
||||
#include "nir_builder.h"
|
||||
#include "nir_builtin_builder.h"
|
||||
|
|
@ -162,6 +163,29 @@ nir_round_int_to_float(nir_builder *b, nir_def *src,
|
|||
}
|
||||
UNREACHABLE("unexpected rounding mode");
|
||||
} else {
|
||||
/* For conversions to FP16 we need to clamp the input against the fp16
|
||||
* max value when rounding towards zero or down. The reason for that is
|
||||
* that for integer values outside of FP16 finite value range we could
|
||||
* get Infinity, which would be incorrect rounding in those cases.
|
||||
*
|
||||
* Furthermore, we only need to do the clamping for integers bigger than
|
||||
* 32 bits, because the lowering below will already clamp 16 bit integers
|
||||
* correctly.
|
||||
*
|
||||
* This isn't a problem for FP32 or FP64 floats as integers can't exceed
|
||||
* the finite value ranges.
|
||||
*/
|
||||
if (dest_bit_size == 16 && src->bit_size >= 32) {
|
||||
switch (round) {
|
||||
case nir_rounding_mode_rtz:
|
||||
case nir_rounding_mode_rd:
|
||||
src = nir_umin_imm(b, src, FP16_MAX_F);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nir_def *mantissa_bit_size = nir_imm_int(b, mantissa_bits);
|
||||
nir_def *msb = nir_imax(b, nir_ufind_msb(b, src), mantissa_bit_size);
|
||||
nir_def *bits_to_lose = nir_isub(b, msb, mantissa_bit_size);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ extern "C" {
|
|||
|
||||
#define FP16_ONE ((uint16_t) 0x3c00)
|
||||
#define FP16_ZERO ((uint16_t) 0)
|
||||
#define FP16_MAX_F 65504.0
|
||||
|
||||
uint16_t _mesa_float_to_half_slow(float val);
|
||||
float _mesa_half_to_float_slow(uint16_t val);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue