mirror of https://gitlab.freedesktop.org/mesa/mesa
spirv: preserve signed zero in modf
fsign's result can be +0.0 or -0.0 for -0.0. We already calculate the signed zero, it's even faster to replace the fmul(fsign(x), ...) with ior. Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28938>
This commit is contained in:
parent
c2053c5363
commit
6ab4b2d7a0
|
@ -343,7 +343,7 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
|
|||
nir_def *sign_bit =
|
||||
nir_imm_intN_t(&b->nb, (uint64_t)1 << (src[0]->bit_size - 1),
|
||||
src[0]->bit_size);
|
||||
nir_def *sign = nir_fsign(nb, src[0]);
|
||||
nir_def *signed_zero = nir_iand(nb, src[0], sign_bit);
|
||||
nir_def *abs = nir_fabs(nb, src[0]);
|
||||
|
||||
/* NaN input should produce a NaN results, and ±Inf input should provide
|
||||
|
@ -353,12 +353,12 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
|
|||
*/
|
||||
dest->def = nir_bcsel(nb,
|
||||
nir_ieq(nb, abs, inf),
|
||||
nir_iand(nb, src[0], sign_bit),
|
||||
nir_fmul(nb, sign, nir_ffract(nb, abs)));
|
||||
signed_zero,
|
||||
nir_ior(nb, signed_zero, nir_ffract(nb, abs)));
|
||||
|
||||
struct vtn_pointer *i_ptr = vtn_value(b, w[6], vtn_value_type_pointer)->pointer;
|
||||
struct vtn_ssa_value *whole = vtn_create_ssa_value(b, i_ptr->type->type);
|
||||
whole->def = nir_fmul(nb, sign, nir_ffloor(nb, abs));
|
||||
whole->def = nir_ior(nb, signed_zero, nir_ffloor(nb, abs));
|
||||
vtn_variable_store(b, whole, i_ptr, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -368,16 +368,16 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
|
|||
nir_def *sign_bit =
|
||||
nir_imm_intN_t(&b->nb, (uint64_t)1 << (src[0]->bit_size - 1),
|
||||
src[0]->bit_size);
|
||||
nir_def *sign = nir_fsign(nb, src[0]);
|
||||
nir_def *signed_zero = nir_iand(nb, src[0], sign_bit);
|
||||
nir_def *abs = nir_fabs(nb, src[0]);
|
||||
vtn_assert(glsl_type_is_struct_or_ifc(dest_type));
|
||||
|
||||
/* See GLSLstd450Modf for explanation of the Inf and NaN handling. */
|
||||
dest->elems[0]->def = nir_bcsel(nb,
|
||||
nir_ieq(nb, abs, inf),
|
||||
nir_iand(nb, src[0], sign_bit),
|
||||
nir_fmul(nb, sign, nir_ffract(nb, abs)));
|
||||
dest->elems[1]->def = nir_fmul(nb, sign, nir_ffloor(nb, abs));
|
||||
signed_zero,
|
||||
nir_ior(nb, signed_zero, nir_ffract(nb, abs)));
|
||||
dest->elems[1]->def = nir_ior(nb, signed_zero, nir_ffloor(nb, abs));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue