nir/lower_double_ops: lower floor()
At least i965 hardware does not have native support for floor on doubles. v2 (Sam): - Improve the lowering pass to remove one bcsel (Jason) Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:

committed by
Samuel Iglesias Gonsálvez

parent
5fab3d178b
commit
29541ec531
@@ -2418,6 +2418,7 @@ typedef enum {
|
||||
nir_lower_dsqrt = (1 << 1),
|
||||
nir_lower_drsq = (1 << 2),
|
||||
nir_lower_dtrunc = (1 << 3),
|
||||
nir_lower_dfloor = (1 << 4),
|
||||
} nir_lower_doubles_options;
|
||||
|
||||
void nir_lower_doubles(nir_shader *shader, nir_lower_doubles_options options);
|
||||
|
@@ -351,6 +351,23 @@ lower_trunc(nir_builder *b, nir_ssa_def *src)
|
||||
nir_iand(b, mask_hi, src_hi))));
|
||||
}
|
||||
|
||||
static nir_ssa_def *
|
||||
lower_floor(nir_builder *b, nir_ssa_def *src)
|
||||
{
|
||||
/*
|
||||
* For x >= 0, floor(x) = trunc(x)
|
||||
* For x < 0,
|
||||
* - if x is integer, floor(x) = x
|
||||
* - otherwise, floor(x) = trunc(x) - 1
|
||||
*/
|
||||
nir_ssa_def *tr = nir_ftrunc(b, src);
|
||||
nir_ssa_def *positive = nir_fge(b, src, nir_imm_double(b, 0.0));
|
||||
return nir_bcsel(b,
|
||||
nir_ior(b, positive, nir_feq(b, src, tr)),
|
||||
tr,
|
||||
nir_fsub(b, tr, nir_imm_double(b, 1.0)));
|
||||
}
|
||||
|
||||
static void
|
||||
lower_doubles_instr(nir_alu_instr *instr, nir_lower_doubles_options options)
|
||||
{
|
||||
@@ -379,6 +396,11 @@ lower_doubles_instr(nir_alu_instr *instr, nir_lower_doubles_options options)
|
||||
return;
|
||||
break;
|
||||
|
||||
case nir_op_ffloor:
|
||||
if (!(options & nir_lower_dfloor))
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -405,6 +427,9 @@ lower_doubles_instr(nir_alu_instr *instr, nir_lower_doubles_options options)
|
||||
case nir_op_ftrunc:
|
||||
result = lower_trunc(&bld, src);
|
||||
break;
|
||||
case nir_op_ffloor:
|
||||
result = lower_floor(&bld, src);
|
||||
break;
|
||||
default:
|
||||
unreachable("unhandled opcode");
|
||||
}
|
||||
|
Reference in New Issue
Block a user