[Mesa-dev] [PATCH 31/59] i965/fs: optimize pack double

Connor Abbott cwabbott0 at gmail.com
Mon May 2 19:11:50 UTC 2016


On Fri, Apr 29, 2016 at 7:29 AM, Samuel Iglesias Gonsálvez
<siglesias at igalia.com> wrote:
> From: Iago Toral Quiroga <itoral at igalia.com>
>
> When we are actually creating a double using values obtained from a
> previous unpack operation we can bypass the unpack and source from
> the original double value directly.
> ---
>  src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> index ca1f24f..4332575 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> @@ -1091,6 +1091,29 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
>        break;
>
>     case nir_op_pack_double_2x32_split:
> +      /* Optimize the common case where we are re-packing a double with
> +       * the result of a previous double unpack. In this case we can take the
> +       * 32-bit value to use in the re-pack from the original double and bypass
> +       * the unpack operation.
> +       */
> +      for (int i = 0; i < 2; i++) {
> +         if (instr->src[i].src.is_ssa) {
> +            nir_instr *parent_instr = instr->src[i].src.ssa->parent_instr;
> +            if (parent_instr->type == nir_instr_type_alu) {
> +               nir_alu_instr *alu_parent = nir_instr_as_alu(parent_instr);
> +               if (alu_parent->op == nir_op_unpack_double_2x32_split_x ||
> +                   alu_parent->op == nir_op_unpack_double_2x32_split_y) {
> +                  op[i] = get_nir_src(alu_parent->src[0].src);

The source could be a register here (say, if it was part of a phi web
that got collapsed) in which case we should bail since something else
might've overwritten it in the meantime. Implementing Topi's
suggestion to use early exits instead will prevent this from getting
even more unwieldy when fixing this up.

> +                  op[i] = offset(retype(op[i], BRW_REGISTER_TYPE_DF), bld,
> +                                 alu_parent->src[0].swizzle[channel]);
> +                  op[i] = retype(op[i], BRW_REGISTER_TYPE_UD);
> +                  if (alu_parent->op == nir_op_unpack_double_2x32_split_y)
> +                     op[i] = horiz_offset(op[i], 1);
> +                  op[i] = stride(op[i], 2);
> +               }
> +            }
> +         }
> +      }
>        bld.emit(FS_OPCODE_PACK, result, op[0], op[1]);
>        break;
>
> --
> 2.5.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list