[Mesa-dev] [PATCH v2 3/7] intel/blorp_blit: Adjust blorp surface parameters for split blits
Jason Ekstrand
jason at jlekstrand.net
Fri Dec 2 00:19:49 UTC 2016
On Wed, Nov 30, 2016 at 8:12 PM, Jordan Justen <jordan.l.justen at intel.com>
wrote:
> If try_blorp_blit() previously returned that a blit was too large,
> shrink_surface_params() will be used to update the surface parameters
> for the smaller blit so the blit operation can proceed.
>
> v2:
> * Use double instead of float. (Jason)
>
> Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
> ---
> src/intel/blorp/blorp_blit.c | 108 ++++++++++++++++++++++++++++++
> +++++++++++--
> 1 file changed, 105 insertions(+), 3 deletions(-)
>
> diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
> index b12a4ec..5ca3190 100644
> --- a/src/intel/blorp/blorp_blit.c
> +++ b/src/intel/blorp/blorp_blit.c
> @@ -1486,6 +1486,12 @@ surf_retile_w_to_y(const struct isl_device *isl_dev,
> info->tile_y_sa /= 2;
> }
>
> +static bool
> +can_shrink_surfaces(const struct blorp_params *params)
> +{
> + return false;
> +}
> +
> struct blt_axis {
> double src0, src1, dst0, dst1;
> bool mirror;
> @@ -1732,12 +1738,98 @@ adjust_split_coords(const struct blt_axis *orig,
> split_coords->src1 = orig->src1 + (scale >= 0.0 ? delta1 : delta0);
> }
>
> +static const struct isl_extent2d
> +get_px_size_sa(const struct isl_surf *surf)
> +{
> + static const struct isl_extent2d one_to_one = { .w = 1, .h = 1 };
> +
> + if (surf->msaa_layout != ISL_MSAA_LAYOUT_INTERLEAVED)
> + return one_to_one;
> + else
> + return isl_get_interleaved_msaa_px_size_sa(surf->samples);
> +}
> +
> +static void
> +shrink_surface_params(const struct isl_device *dev,
> + struct brw_blorp_surface_info *info,
> + double *x0, double *x1, double *y0, double *y1)
> +{
> + uint32_t byte_offset, x_offset_sa, y_offset_sa, size;
> + struct isl_extent2d px_size_sa;
> + int adjust;
> +
> + surf_convert_to_single_slice(dev, info);
> +
> + px_size_sa = get_px_size_sa(&info->surf);
> +
> + x_offset_sa = (uint32_t)*x0 * px_size_sa.w + info->tile_x_sa;
> + y_offset_sa = (uint32_t)*y0 * px_size_sa.h + info->tile_y_sa;
> + isl_tiling_get_intratile_offset_sa(dev, info->surf.tiling,
> + info->surf.format,
> info->surf.row_pitch,
> + x_offset_sa, y_offset_sa,
> + &byte_offset,
> + &info->tile_x_sa, &info->tile_y_sa);
>
If we're going to do things this early, we should just make our own
temporary variables for tile_x/y instead of trying to re-use the ones from
info
> +
> + info->addr.offset += byte_offset;
> +
> + adjust = (int)info->tile_x_sa / px_size_sa.w - (int)*x0;
> + *x0 += adjust;
> + *x1 += adjust;
> + info->tile_x_sa = 0;
>
That way we don't have to reset them to 0.
> +
> + adjust = (int)info->tile_y_sa / px_size_sa.h - (int)*y0;
> + *y0 += adjust;
> + *y1 += adjust;
> + info->tile_y_sa = 0;
>
+
> + size = MIN2((uint32_t)ceilf(*x1), info->surf.logical_level0_px.width);
> + double phys_scale =
> + info->surf.phys_level0_sa.width / info->surf.logical_level0_px.w
> idth;
> + info->surf.logical_level0_px.width = size;
> + info->surf.phys_level0_sa.width =
> + (uint32_t)ceilf(phys_scale * size);
>
Why not juts set logical_level0_px and then multiply by px_size_sa to get
the physical size? That seems more reliable by using a double to help with
integer calculations.
> +
> + size = MIN2((uint32_t)ceilf(*y1), info->surf.logical_level0_px.h
> eight);
> + phys_scale =
> + info->surf.phys_level0_sa.height / info->surf.logical_level0_px.h
> eight;
> + info->surf.logical_level0_px.height = (uint32_t)ceilf(size);
> + info->surf.phys_level0_sa.height =
> + (uint32_t)ceilf(phys_scale * size);
> +}
> +
> +static void
> +shrink_surfaces(const struct isl_device *dev,
> + struct blorp_params *params,
> + struct brw_blorp_blit_prog_key *wm_prog_key,
> + struct blt_coords *coords)
> +{
> + /* Shrink source surface */
> + shrink_surface_params(dev,
> + ¶ms->src,
> + &coords->x.src0,
> + &coords->x.src1,
> + &coords->y.src0,
> + &coords->y.src1);
> + wm_prog_key->need_src_offset = false;
> +
> + /* Shrink destination surface */
> + shrink_surface_params(dev,
> + ¶ms->dst,
> + &coords->x.dst0,
> + &coords->x.dst1,
> + &coords->y.dst0,
> + &coords->y.dst1);
>
I commented in our meeting that we probably want to support splitting only
one of the surfaces. Let's merge it first and plan to fix it as a
follow-up.
> + wm_prog_key->need_dst_offset = wm_prog_key->dst_rgb;
> +}
> +
> static void
> do_blorp_blit(struct blorp_batch *batch,
> - struct blorp_params *params,
> + const struct blorp_params *orig_params,
> struct brw_blorp_blit_prog_key *wm_prog_key,
> const struct blt_coords *orig)
> {
> + struct blorp_params params;
> + struct blt_coords blit_coords;
> struct blt_coords split_coords = *orig;
> double w = orig->x.dst1 - orig->x.dst0;
> double h = orig->y.dst1 - orig->y.dst0;
> @@ -1749,9 +1841,16 @@ do_blorp_blit(struct blorp_batch *batch,
> y_scale = -y_scale;
>
> bool x_done, y_done;
> + bool shrink = false;
> do {
> + params = *orig_params;
> + blit_coords = split_coords;
> + if (shrink) {
> + shrink_surfaces(batch->blorp->isl_dev, ¶ms, wm_prog_key,
> + &blit_coords);
> + }
> unsigned result =
> - try_blorp_blit(batch, params, wm_prog_key, &split_coords);
> + try_blorp_blit(batch, ¶ms, wm_prog_key, &blit_coords);
>
> if (result & BLIT_WIDTH_TOO_LARGE) {
> w /= 2.0;
> @@ -1766,8 +1865,11 @@ do_blorp_blit(struct blorp_batch *batch,
> adjust_split_coords(&orig->y, &split_coords.y, y_scale);
> }
>
> - if (result != 0)
> + if (result != 0) {
> + assert(can_shrink_surfaces(orig_params));
> + shrink = true;
> continue;
> + }
>
> y_done = (orig->y.dst1 - split_coords.y.dst1 < 0.5);
> x_done = y_done && (orig->x.dst1 - split_coords.x.dst1 < 0.5);
> --
> 2.10.2
>
> _______________________________________________
> 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/20161201/63a470d2/attachment-0001.html>
More information about the mesa-dev
mailing list