[Mesa-dev] [PATCH 3/4] i965: Attempt to blit for larger textures
Jason Ekstrand
jason at jlekstrand.net
Wed Jan 14 10:42:01 PST 2015
On Tue, Jan 13, 2015 at 11:37 PM, Ben Widawsky <benjamin.widawsky at intel.com>
wrote:
> The blit engine is limited to 32Kx32K transfer. In cases where we have to
> fall
> back to the blitter, and when trying to blit a slice of a 2d texture
> array, or
> face of a cube map, we don't need to transfer the entire texture.
>
> I doubt this patch will get exercised at this point since we'll always
> allocate
> a linear BO for huge buffers. The next patch changes that.
>
> v2: Fix NDEBUG warning
>
> Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
> ---
> src/mesa/drivers/dri/i965/intel_blit.c | 107
> ++++++++++++++++++++++++++++++++-
> 1 file changed, 105 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/intel_blit.c
> b/src/mesa/drivers/dri/i965/intel_blit.c
> index 9500bd7..a56e394 100644
> --- a/src/mesa/drivers/dri/i965/intel_blit.c
> +++ b/src/mesa/drivers/dri/i965/intel_blit.c
> @@ -130,6 +130,104 @@ set_blitter_tiling(struct brw_context *brw,
> ADVANCE_BATCH(); \
> } while (0)
>
> +
> +/* Returns the height of the tiling format. This would be measured in
> scanlines
> + * (of pitch bytes) */
> +static int
> +tile_height(uint32_t tiling)
> +{
> + const long PAGE_SIZE = sysconf(_SC_PAGE_SIZE);
> + switch (tiling) {
> + case I915_TILING_X:
> + return PAGE_SIZE / 512;
> + case I915_TILING_Y:
> + return PAGE_SIZE / 128;
> + case I915_TILING_NONE:
> + default:
> + unreachable("Helper function is only used for tiled surfaces\n");
> + }
> +}
> +
> +/* This function returns the offset to be used by the blit operation. It
> may
> + * modify the y if the texture would otherwise fail to be able to perform
> a
> + * blit. The x offset will not need to change based on the computations
> made by
> + * this function.
> + *
> + * By the time we get to this function, the miptree creation code should
> have
> + * already determined it's possible to blit the texture, so there should
> never
> + * be a case where this function fails.
> + */
> +static GLuint
> +intel_miptree_get_adjusted_y_offset(struct intel_mipmap_tree *mt, int
> slice,
> + uint32_t *y)
> +{
> + GLuint offset = mt->offset;
> +
> + /* Convert an input number of rows: y into 2 values: an offset (page
> aligned
> + * in byte units), and the remaining rows of y. The resulting 2 values
> will
> + * be used as parameters for a blit operation [using the HW blit
> engine].
> + * They will therefore conform to whatever restrictions are needed.
> + *
> + * XXX: This code assumes that LOD0 is always guaranteed to be properly
> + * aligned for the blit operation. The round down only mutates y if
> the LOD
> + * being adjusted isn't tile aligned. In other words, if input y is
> pointing
> + * to LOD0 of a slice, the adjusted y should always be 0. Similarly if
> input
> + * y is pointing to another LOD, and the offset happens to be tile
> aligned, y
> + * will again be 0.
> + *
> + * The following diagram shows how the blit parameters are modified.
> In the
> + * example, is is trying to blit with LOD1 from slice[x] as a surface,
> and
> + * LOD1 is not properly tile aligned. "TA" means tile aligned. The
> rectangle
> + * is the BO that contains the mipmaps. There may be an offset from
> the start
> + * of the BO to the first slice.
> + *
> + * INPUT OUTPUT
> + * 0 +---------------------------+
> + * | |
> +---------------------------+
> + * offset | slice[0]...slice[x-2] | offset | +----------+
> |
> + * | | | | lod0 |
> slice[x] |
> + * TA | +----------+ | | | |
> |
> + * | | lod0 | slice[x-1] | | +----------+
> |
> + * | | | | y---> | +---+ +-+
> |
> + * | +----------+ | | | | +-+
> |
> + * | +---+ +-+ | | +---+ *
> |
> + * | | | +-+ | |
> |
> + * | +---+ * | | slice[x+1]...
> |
> + * | |
> +---------------------------+
> + * | // qpitch padding |
> + * | |
> + * TA | +----------+ |
> + * | | lod0 | slice[x] |
> + * | | | |
> + * | +----------+ |
> + * y---> | +---+ +-+ |
> + * | | | +-+ |
> + * | +---+ * |
> + * | |
> + * | slice[x+1]... |
> + * +---------------------------+
> + */
> + if (slice > 0 && *y >= 32768) {
>
Why are we going through all these hoops to avoid the adjustment? Does
setting an offset cost us something we want to avoid? Also, I think the
check above needs to check y2 not y1 because y2 is larger and will actually
be the determining factor on whether or not we can blit.
--Jason
> + const long PAGE_MASK = sysconf(_SC_PAGE_SIZE) - 1;
> + (void) PAGE_MASK;
> +
> + /* Since we need to output a page aligned offset, the original
> offset must
> + * also be page aligned. For tiled buffers, it always should be. */
> + assert((offset & PAGE_MASK) == 0);
> +
> + /* Adjust the y value to pick the nearest tile aligned mipmap row */
> + unsigned tile_aligned_row = ROUND_DOWN_TO(*y,
> tile_height(mt->tiling));
> + *y -= tile_aligned_row;
> +
> + /* Convert tiled aligned row to a byte offset for use by the
> blitter */
> + tile_aligned_row *= mt->pitch;
> + assert((tile_aligned_row & PAGE_MASK) == 0);
> + offset += tile_aligned_row;
> + }
> +
> + return offset;
> +}
> +
> /**
> * Implements a rectangular block transfer (blit) of pixels between two
> * miptrees.
> @@ -236,6 +334,11 @@ intel_miptree_blit(struct brw_context *brw,
> dst_x += dst_image_x;
> dst_y += dst_image_y;
>
> + GLuint src_offset = intel_miptree_get_adjusted_y_offset(src_mt,
> src_slice,
> + &src_y);
> + GLuint dst_offset = intel_miptree_get_adjusted_y_offset(dst_mt,
> dst_slice,
> + &dst_y);
> +
> /* The blitter interprets the 16-bit destination x/y as a signed 16-bit
> * value. The values we're working with are unsigned, so make sure we
> don't
> * overflow.
> @@ -249,10 +352,10 @@ intel_miptree_blit(struct brw_context *brw,
> if (!intelEmitCopyBlit(brw,
> src_mt->cpp,
> src_pitch,
> - src_mt->bo, src_mt->offset,
> + src_mt->bo, src_offset,
> src_mt->tiling,
> dst_mt->pitch,
> - dst_mt->bo, dst_mt->offset,
> + dst_mt->bo, dst_offset,
> dst_mt->tiling,
> src_x, src_y,
> dst_x, dst_y,
> --
> 2.2.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150114/50d2bd24/attachment-0001.html>
More information about the mesa-dev
mailing list