<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Mar 8, 2018 at 8:07 AM, Neil Roberts <span dir="ltr"><<a href="mailto:nroberts@igalia.com" target="_blank">nroberts@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The implementation is inspired by<br>
lower_instructions_visitor::<wbr>dfrexp_sig_to_arith.<br>
<br>
This has been tested against the arb_gpu_shader_fp64/fs-frexp-<wbr>dvec4<br>
test using the ARB_gl_spirv branch.<br>
---<br>
<br>
Please also see this related patch which I probably should have<br>
bundled in this series:<br>
<br>
<a href="https://patchwork.freedesktop.org/patch/208702/" rel="noreferrer" target="_blank">https://patchwork.freedesktop.<wbr>org/patch/208702/</a><br>
<br>
src/compiler/spirv/vtn_<wbr>glsl450.c | 60 ++++++++++++++++++++++++++++++<wbr>+++++++---<br>
1 file changed, 56 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/src/compiler/spirv/vtn_<wbr>glsl450.c b/src/compiler/spirv/vtn_<wbr>glsl450.c<br>
index 46ef40f5e3f..51c4cd271bc 100644<br>
--- a/src/compiler/spirv/vtn_<wbr>glsl450.c<br>
+++ b/src/compiler/spirv/vtn_<wbr>glsl450.c<br>
@@ -380,7 +380,7 @@ build_atan2(nir_builder *b, nir_ssa_def *y, nir_ssa_def *x)<br>
}<br>
<br>
static nir_ssa_def *<br>
-build_frexp(nir_builder *b, nir_ssa_def *x, nir_ssa_def **exponent)<br>
+build_frexp32(nir_builder *b, nir_ssa_def *x, nir_ssa_def **exponent)<br>
{<br>
nir_ssa_def *abs_x = nir_fabs(b, x);<br>
nir_ssa_def *zero = nir_imm_float(b, 0.0f);<br>
@@ -412,6 +412,51 @@ build_frexp(nir_builder *b, nir_ssa_def *x, nir_ssa_def **exponent)<br>
nir_bcsel(b, is_not_zero, exponent_value, zero));<br>
}<br>
<br>
+static nir_ssa_def *<br>
+build_frexp64(nir_builder *b, nir_ssa_def *x, nir_ssa_def **exponent)<br>
+{<br>
+ nir_ssa_def *abs_x = nir_fabs(b, x);<br>
+ nir_ssa_def *zero = nir_imm_double(b, 0.0);<br>
+ nir_ssa_def *zero32 = nir_imm_float(b, 0.0f);<br>
+<br>
+ /* Double-precision floating-point values are stored as<br>
+ * 1 sign bit;<br>
+ * 11 exponent bits;<br>
+ * 52 mantissa bits.<br>
+ *<br>
+ * We only need to deal with the exponent so first we extract the upper 32<br>
+ * bits using nir_unpack_64_2x32_split_y.<br>
+ */<br>
+ nir_ssa_def *upper_x = nir_unpack_64_2x32_split_y(b, x);<br></blockquote><div><br></div><div>It'd be nice to have a lower_x as well<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ nir_ssa_def *abs_upper_x = nir_unpack_64_2x32_split_y(b, abs_x);<br>
+<br>
+ /* An exponent shift of 20 will shift the remaining mantissa bits out,<br>
+ * leaving only the exponent and sign bit (which itself may be zero, if the<br>
+ * absolute value was taken before the bitcast and shift.<br>
+ */<br>
+ nir_ssa_def *exponent_shift = nir_imm_int(b, 20);<br>
+ nir_ssa_def *exponent_bias = nir_imm_int(b, -1022);<br>
+<br>
+ nir_ssa_def *sign_mantissa_mask = nir_imm_int(b, 0x800fffffu);<br>
+<br>
+ /* Exponent of floating-point values in the range [0.5, 1.0). */<br>
+ nir_ssa_def *exponent_value = nir_imm_int(b, 0x3fe00000u);<br>
+<br>
+ nir_ssa_def *is_not_zero = nir_fne(b, abs_x, zero);<br>
+<br>
+ *exponent =<br>
+ nir_iadd(b, nir_ushr(b, abs_upper_x, exponent_shift),<br>
+ nir_bcsel(b, is_not_zero, exponent_bias, zero32));<br>
+<br>
+ nir_ssa_def *new_upper =<br>
+ nir_ior(b, nir_iand(b, upper_x, sign_mantissa_mask),<br>
+ nir_bcsel(b, is_not_zero, exponent_value, zero32));<br>
+<br>
+ return nir_pack_64_2x32_split(b,<br>
+ nir_unpack_64_2x32_split_x(b, x),<br></blockquote><div><br></div><div>It would make this more clear. With that,<br><br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br><br></div><div>We'll need to add a 16-bit version as well but we have no way to test that right now.<br><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ new_upper);<br>
+}<br>
+<br>
static nir_op<br>
vtn_nir_alu_op_for_spirv_glsl_<wbr>opcode(struct vtn_builder *b,<br>
enum GLSLstd450 opcode)<br>
@@ -685,15 +730,22 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,<br>
<br>
case GLSLstd450Frexp: {<br>
nir_ssa_def *exponent;<br>
- val->ssa->def = build_frexp(nb, src[0], &exponent);<br>
+ if (src[0]->bit_size == 64)<br>
+ val->ssa->def = build_frexp64(nb, src[0], &exponent);<br>
+ else<br>
+ val->ssa->def = build_frexp32(nb, src[0], &exponent);<br>
nir_store_deref_var(nb, vtn_nir_deref(b, w[6]), exponent, 0xf);<br>
return;<br>
}<br>
<br>
case GLSLstd450FrexpStruct: {<br>
vtn_assert(glsl_type_is_<wbr>struct(val->ssa->type));<br>
- val->ssa->elems[0]->def = build_frexp(nb, src[0],<br>
- &val->ssa->elems[1]->def);<br>
+ if (src[0]->bit_size == 64)<br>
+ val->ssa->elems[0]->def = build_frexp64(nb, src[0],<br>
+ &val->ssa->elems[1]->def);<br>
+ else<br>
+ val->ssa->elems[0]->def = build_frexp32(nb, src[0],<br>
+ &val->ssa->elems[1]->def);<br>
return;<br>
}<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>