[Mesa-dev] [PATCH 2/2] spirv: Add a 64-bit implementation of Frexp
Jason Ekstrand
jason at jlekstrand.net
Wed Mar 21 17:04:14 UTC 2018
On Thu, Mar 8, 2018 at 8:07 AM, Neil Roberts <nroberts at igalia.com> wrote:
> The implementation is inspired by
> lower_instructions_visitor::dfrexp_sig_to_arith.
>
> This has been tested against the arb_gpu_shader_fp64/fs-frexp-dvec4
> test using the ARB_gl_spirv branch.
> ---
>
> Please also see this related patch which I probably should have
> bundled in this series:
>
> https://patchwork.freedesktop.org/patch/208702/
>
> src/compiler/spirv/vtn_glsl450.c | 60 ++++++++++++++++++++++++++++++
> +++++++---
> 1 file changed, 56 insertions(+), 4 deletions(-)
>
> diff --git a/src/compiler/spirv/vtn_glsl450.c b/src/compiler/spirv/vtn_
> glsl450.c
> index 46ef40f5e3f..51c4cd271bc 100644
> --- a/src/compiler/spirv/vtn_glsl450.c
> +++ b/src/compiler/spirv/vtn_glsl450.c
> @@ -380,7 +380,7 @@ build_atan2(nir_builder *b, nir_ssa_def *y,
> nir_ssa_def *x)
> }
>
> static nir_ssa_def *
> -build_frexp(nir_builder *b, nir_ssa_def *x, nir_ssa_def **exponent)
> +build_frexp32(nir_builder *b, nir_ssa_def *x, nir_ssa_def **exponent)
> {
> nir_ssa_def *abs_x = nir_fabs(b, x);
> nir_ssa_def *zero = nir_imm_float(b, 0.0f);
> @@ -412,6 +412,51 @@ build_frexp(nir_builder *b, nir_ssa_def *x,
> nir_ssa_def **exponent)
> nir_bcsel(b, is_not_zero, exponent_value, zero));
> }
>
> +static nir_ssa_def *
> +build_frexp64(nir_builder *b, nir_ssa_def *x, nir_ssa_def **exponent)
> +{
> + nir_ssa_def *abs_x = nir_fabs(b, x);
> + nir_ssa_def *zero = nir_imm_double(b, 0.0);
> + nir_ssa_def *zero32 = nir_imm_float(b, 0.0f);
> +
> + /* Double-precision floating-point values are stored as
> + * 1 sign bit;
> + * 11 exponent bits;
> + * 52 mantissa bits.
> + *
> + * We only need to deal with the exponent so first we extract the
> upper 32
> + * bits using nir_unpack_64_2x32_split_y.
> + */
> + nir_ssa_def *upper_x = nir_unpack_64_2x32_split_y(b, x);
>
It'd be nice to have a lower_x as well
> + nir_ssa_def *abs_upper_x = nir_unpack_64_2x32_split_y(b, abs_x);
> +
> + /* An exponent shift of 20 will shift the remaining mantissa bits out,
> + * leaving only the exponent and sign bit (which itself may be zero,
> if the
> + * absolute value was taken before the bitcast and shift.
> + */
> + nir_ssa_def *exponent_shift = nir_imm_int(b, 20);
> + nir_ssa_def *exponent_bias = nir_imm_int(b, -1022);
> +
> + nir_ssa_def *sign_mantissa_mask = nir_imm_int(b, 0x800fffffu);
> +
> + /* Exponent of floating-point values in the range [0.5, 1.0). */
> + nir_ssa_def *exponent_value = nir_imm_int(b, 0x3fe00000u);
> +
> + nir_ssa_def *is_not_zero = nir_fne(b, abs_x, zero);
> +
> + *exponent =
> + nir_iadd(b, nir_ushr(b, abs_upper_x, exponent_shift),
> + nir_bcsel(b, is_not_zero, exponent_bias, zero32));
> +
> + nir_ssa_def *new_upper =
> + nir_ior(b, nir_iand(b, upper_x, sign_mantissa_mask),
> + nir_bcsel(b, is_not_zero, exponent_value, zero32));
> +
> + return nir_pack_64_2x32_split(b,
> + nir_unpack_64_2x32_split_x(b, x),
>
It would make this more clear. With that,
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
We'll need to add a 16-bit version as well but we have no way to test that
right now.
--Jason
> + new_upper);
> +}
> +
> static nir_op
> vtn_nir_alu_op_for_spirv_glsl_opcode(struct vtn_builder *b,
> enum GLSLstd450 opcode)
> @@ -685,15 +730,22 @@ handle_glsl450_alu(struct vtn_builder *b, enum
> GLSLstd450 entrypoint,
>
> case GLSLstd450Frexp: {
> nir_ssa_def *exponent;
> - val->ssa->def = build_frexp(nb, src[0], &exponent);
> + if (src[0]->bit_size == 64)
> + val->ssa->def = build_frexp64(nb, src[0], &exponent);
> + else
> + val->ssa->def = build_frexp32(nb, src[0], &exponent);
> nir_store_deref_var(nb, vtn_nir_deref(b, w[6]), exponent, 0xf);
> return;
> }
>
> case GLSLstd450FrexpStruct: {
> vtn_assert(glsl_type_is_struct(val->ssa->type));
> - val->ssa->elems[0]->def = build_frexp(nb, src[0],
> - &val->ssa->elems[1]->def);
> + if (src[0]->bit_size == 64)
> + val->ssa->elems[0]->def = build_frexp64(nb, src[0],
> +
> &val->ssa->elems[1]->def);
> + else
> + val->ssa->elems[0]->def = build_frexp32(nb, src[0],
> +
> &val->ssa->elems[1]->def);
> return;
> }
>
> --
> 2.14.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180321/5e494415/attachment-0001.html>
More information about the mesa-dev
mailing list