[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