[Mesa-dev] [PATCHv2 13/25] i965/fs: Skip SIMD lowering destination zipping if possible.
Jason Ekstrand
jason at jlekstrand.net
Thu Jun 2 04:54:30 UTC 2016
Looks good. R-B
On Wed, Jun 1, 2016 at 5:21 PM, Francisco Jerez <currojerez at riseup.net>
wrote:
> Skipping the temporary allocation and copy instructions is easy (just
> return dst), but the conditions used to find out whether the copy can
> be optimized out safely without breaking the program are rather
> complex: The destination must be exactly one component of at most the
> execution width of the lowered instruction, and all source regions of
> the instruction must be either fully disjoint from the destination or
> be aligned with it group by group.
>
> v2: Don't handle partial source-destination overlap for simplicity
> (Jason). No instruction count regressions with respect to v1 in
> either shader-db or the few FP64 shader_runner test-cases with
> partial overlap I've checked manually.
> ---
> src/mesa/drivers/dri/i965/brw_fs.cpp | 55
> ++++++++++++++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp
> b/src/mesa/drivers/dri/i965/brw_fs.cpp
> index 00d937e..bfae1d7 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
> @@ -5078,6 +5078,52 @@ emit_unzip(const fs_builder &lbld, bblock_t *block,
> fs_inst *inst,
> }
>
> /**
> + * Return true if splitting out the group of channels of instruction \p
> inst
> + * given by lbld.group() requires allocating a temporary for the
> destination
> + * of the lowered instruction and copying the data back to the original
> + * destination region.
> + */
> +static inline bool
> +needs_dst_copy(const fs_builder &lbld, const fs_inst *inst)
> +{
> + /* If the instruction writes more than one component we'll have to
> shuffle
> + * the results of multiple lowered instructions in order to make sure
> that
> + * they end up arranged correctly in the original destination region.
> + */
> + if (inst->regs_written * REG_SIZE >
> + inst->dst.component_size(inst->exec_size))
> + return true;
> +
> + /* If the lowered execution size is larger than the original the
> result of
> + * the instruction won't fit in the original destination, so we'll
> have to
> + * allocate a temporary in any case.
> + */
> + if (lbld.dispatch_width() > inst->exec_size)
> + return true;
> +
> + for (unsigned i = 0; i < inst->sources; i++) {
> + /* If we already made a copy of the source for other reasons there
> won't
> + * be any overlap with the destination.
> + */
> + if (needs_src_copy(lbld, inst, i))
> + continue;
> +
> + /* In order to keep the logic simple we emit a copy whenever the
> + * destination region doesn't exactly match an overlapping source,
> which
> + * may point at the source and destination not being aligned group
> by
> + * group which could cause one of the lowered instructions to
> overwrite
> + * the data read from the same source by other lowered instructions.
> + */
> + if (regions_overlap(inst->dst, inst->regs_written * REG_SIZE,
> + inst->src[i], inst->regs_read(i) * REG_SIZE) &&
> + !inst->dst.equals(inst->src[i]))
> + return true;
> + }
> +
> + return false;
> +}
> +
> +/**
> * Insert data from a packed temporary into the channel group given by
> * lbld.group() of the destination region of instruction \p inst and
> return
> * the temporary as result. If any copy instructions are required they
> will
> @@ -5097,6 +5143,8 @@ emit_zip(const fs_builder &lbld, bblock_t *block,
> fs_inst *inst)
> const fs_reg dst = horiz_offset(inst->dst, lbld.group());
> const unsigned dst_size = inst->regs_written * REG_SIZE /
> inst->dst.component_size(inst->exec_size);
> +
> + if (needs_dst_copy(lbld, inst)) {
> const fs_reg tmp = lbld.vgrf(inst->dst.type, dst_size);
>
> if (inst->predicate) {
> @@ -5114,6 +5162,13 @@ emit_zip(const fs_builder &lbld, bblock_t *block,
> fs_inst *inst)
> .MOV(offset(dst, inst->exec_size, k), offset(tmp, lbld, k));
>
> return tmp;
> +
> + } else {
> + /* No need to allocate a temporary for the lowered instruction, just
> + * take the right group of channels from the original region.
> + */
> + return dst;
> + }
> }
>
> bool
> --
> 2.7.3
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160601/c9c79c65/attachment.html>
More information about the mesa-dev
mailing list