[Mesa-dev] [PATCH 08/10] i965/fs: Calculate the (un)spill block size correctly.

Jason Ekstrand jason at jlekstrand.net
Tue May 17 17:17:11 UTC 2016


On Mon, May 16, 2016 at 9:23 PM, Francisco Jerez <currojerez at riseup.net>
wrote:

> Currently the spilling code attempts to guess the scratch message
> block size from the dispatch width of the shader, which is plain wrong
> for SIMD-lowered instructions (frequently but not exclusively
> encountered in SIMD32 shaders) or for instructions with register
> region data types of size other than 32 bit.
>
> Instead try to use the SIMD component size of the instruction which in
> some cases will allow the dataport to apply the correct channel mask
> to the scratch data read or written.  In the spill case the block size
> needs to be clamped to the number of MRF registers reserved for
> spilling.  In the unspill case I didn't even bother because we
> currently have no 100% accurate way to determine whether a source
> region is per-channel or whether it contains things like headers that
> don't respect channel boundaries -- That's fine, because the unspill
> is marked force_writemask_all we can just use the largest allowable
> scratch message size.
> ---
>  src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp | 20
> +++++++++++++++++---
>  1 file changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
> b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
> index 5cb2013..ff40c42 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
> @@ -942,8 +942,14 @@ fs_visitor::spill_reg(int spill_reg)
>              inst->src[i].nr = unspill_dst.nr;
>              inst->src[i].reg_offset = 0;
>
> +            /* We read the largest power-of-two divisor of the register
> count
> +             * (because only POT scratch read blocks are allowed by the
> +             * hardware) up to the maximum supported block size.
> +             * XXX - Bump the limit when the generator code is ready for
> +             *       32-wide spills.
> +             */
>              const unsigned width =
> -               dispatch_width == 16 && regs_read % 2 == 0 ? 16 : 8;
> +               MIN2(16, 1u << (ffs(MAX2(1, regs_read) * 8) - 1));
>

Can regs_read ever be zero?  Seems kind of odd.


>
>              /* Set exec_all() on unspill messages under the (rather
>               * pessimistic) assumption that there is no one-to-one
> @@ -974,8 +980,16 @@ fs_visitor::spill_reg(int spill_reg)
>           inst->no_dd_clear = false;
>           inst->no_dd_check = false;
>
> -         const unsigned width =
> -            dispatch_width == 16 && inst->regs_written % 2 == 0 ? 16 : 8;
> +         /* Calculate the execution width of the scratch messages (which
> work
> +          * in terms of 32 bit components so we have a fixed number of
> eight
> +          * channels per spilled register).  We attempt to write one
> +          * exec_size-wide component of the variable at a time without
> +          * exceeding the maximum number of (fake) MRF registers reserved
> for
> +          * spills.
> +          */
> +         const unsigned width = 8 * MIN2(
> +            DIV_ROUND_UP(inst->dst.component_size(inst->exec_size),
> REG_SIZE),
> +            spill_max_size(this));
>
>           /* Spills should only write data initialized by the instruction
> for
>            * whichever channels are enabled in the excution mask.  If
> that's
> --
> 2.7.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/20160517/630044e8/attachment.html>


More information about the mesa-dev mailing list