mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-05 10:10:30 +01:00
agx: set lower_fminmax_signed_zero
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30075>
This commit is contained in:
parent
d238d766c6
commit
6ac289dade
2 changed files with 6 additions and 17 deletions
|
|
@ -1670,29 +1670,16 @@ static agx_instr *
|
|||
agx_fminmax_to(agx_builder *b, agx_index dst, agx_index s0, agx_index s1,
|
||||
nir_alu_instr *alu)
|
||||
{
|
||||
/* The hardware gtn/ltn modes are unfortunately incorrect for signed zeros */
|
||||
assert(!nir_alu_instr_is_signed_zero_preserve(alu) &&
|
||||
"should've been lowered");
|
||||
|
||||
bool fmax = alu->op == nir_op_fmax;
|
||||
enum agx_fcond fcond = fmax ? AGX_FCOND_GTN : AGX_FCOND_LTN;
|
||||
enum agx_icond icond = fmax ? AGX_ICOND_SGT : AGX_ICOND_SLT;
|
||||
|
||||
/* Calculate min/max with the appropriate hardware instruction */
|
||||
agx_index tmp = agx_fcmpsel(b, s0, s1, s0, s1, fcond);
|
||||
|
||||
/* The hardware ltn/gtn modes implement IEEE 754 NaN rules. Unfortunately,
|
||||
* they do not respect signed zeros, causing conformance fails. To
|
||||
* workaround, when both operands are zero, we instead use integer min/max to
|
||||
* get the appropriate sign on the result. We detect that case by checking
|
||||
* for float equality of the inputs: signed zero is the only case where the
|
||||
* floats are equal but the integer values are not, so this works for all
|
||||
* cases. It's annoying that we need 3 SCIB instructions instead of 1, but
|
||||
* hopefully apps don't ask for signed zero preserve if they don't need it.
|
||||
*/
|
||||
if (nir_is_float_control_signed_zero_preserve(alu->fp_fast_math,
|
||||
alu->def.bit_size)) {
|
||||
|
||||
agx_index iminmax = agx_icmpsel(b, s0, s1, s0, s1, icond);
|
||||
tmp = agx_fcmpsel(b, s0, s1, iminmax, tmp, AGX_FCOND_EQ);
|
||||
}
|
||||
|
||||
/* Flush denorms, as cmpsel will not. */
|
||||
return agx_fadd_to(b, dst, tmp, agx_negzero());
|
||||
}
|
||||
|
|
@ -3306,6 +3293,7 @@ agx_preprocess_nir(nir_shader *nir, const nir_shader *libagx)
|
|||
|
||||
NIR_PASS(_, nir, nir_lower_idiv, &idiv_options);
|
||||
NIR_PASS(_, nir, nir_lower_frexp);
|
||||
NIR_PASS(_, nir, nir_lower_alu);
|
||||
NIR_PASS(_, nir, nir_lower_alu_to_scalar, NULL, NULL);
|
||||
NIR_PASS(_, nir, nir_lower_load_const_to_scalar);
|
||||
NIR_PASS(_, nir, nir_lower_flrp, 16 | 32 | 64, false);
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ static const nir_shader_compiler_options agx_nir_options = {
|
|||
.lower_isign = true,
|
||||
.lower_fsign = true,
|
||||
.lower_iabs = true,
|
||||
.lower_fminmax_signed_zero = true,
|
||||
.lower_fdph = true,
|
||||
.lower_ffract = true,
|
||||
.lower_ldexp = true,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue