[Mesa-dev] [RFC PATCH 2/2] etnaviv: try to use CPU to tile/untile when the region is small enough
Boris Brezillon
boris.brezillon at collabora.com
Wed Feb 20 17:01:37 UTC 2019
Using the GPU has a cost, it implies preparing the RS/BLT request and
then possibly requires extra GPU -> CPU syncs, so let's only use
GPU-based tiling/untiling for rather big regions.
While at it, move the "should we use the GPU to tile/untile" logic to
its own function to make things more readable.
Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
---
.../drivers/etnaviv/etnaviv_transfer.c | 67 +++++++++++++++++--
1 file changed, 61 insertions(+), 6 deletions(-)
diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c b/src/gallium/drivers/etnaviv/etnaviv_transfer.c
index 38648564b701..a3013e624ead 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c
@@ -132,6 +132,66 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
slab_free(&ctx->transfer_pool, trans);
}
+#define GPU_TILING_MIN_SURFACE_SIZE 1024
+#define GPU_TILING_MIN_UNALIGNED_SURFACE_SIZE 8192
+
+static bool
+etna_transfer_use_gpu(struct etna_context *ctx, struct etna_resource *rsc,
+ const struct pipe_box *box)
+{
+ unsigned w_align, h_align;
+
+ /* Always use the GPU to tile/untile when the resource has a Tile Status
+ * buffer attached. */
+ if (rsc->ts_bo)
+ return true;
+
+ /* Nothing to tile/untile if the resource is using a linear format. */
+ if (rsc->layout == ETNA_LAYOUT_LINEAR)
+ return false;
+
+ /* Do not use the GPU when the resource is using a 1byte/pixel format. */
+ if (util_format_get_blocksize(rsc->base.format) == 1)
+ return false;
+
+ /* HALIGN 4 resources are incompatible with the resolve engine, so fall back
+ * to using software to detile this resource. */
+ if (rsc->halign == TEXTURE_HALIGN_FOUR)
+ return false;
+
+ /* Using the GPU has a cost, it implies preparing the RS/BLT request and
+ * then possibly requires extra GPU -> CPU syncs, so let's only use
+ * GPU-based tiling for rather big regions. Right now the minimum surface
+ * surface size is arbitrarily set to 1024 pixels. */
+ if (box->width * box->height < GPU_TILING_MIN_SURFACE_SIZE)
+ return false;
+
+ /* No alignment constraints when using BLT. */
+ if (ctx->specs.use_blt)
+ return true;
+
+ if (rsc->layout & ETNA_LAYOUT_BIT_SUPER) {
+ w_align = h_align = 64;
+ } else {
+ w_align = ETNA_RS_WIDTH_MASK + 1;
+ h_align = ETNA_RS_HEIGHT_MASK + 1;
+ }
+ h_align *= ctx->screen->specs.pixel_pipes;
+
+ /* Everything is properly aligned, let's use the RS engine to
+ * tile/untile. */
+ if (!((box->x | box->width) & (w_align - 1)) &&
+ !((box->y | box->height) & (h_align - 1)))
+ return true;
+
+ /* We want the minimum surface size to be even bigger for unaligned
+ * requests. */
+ if (box->width * box->height < GPU_TILING_MIN_UNALIGNED_SURFACE_SIZE)
+ return false;
+
+ return true;
+}
+
static void *
etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc,
unsigned level,
@@ -179,12 +239,7 @@ etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc,
* render resource. Use the texture resource, which avoids bouncing
* pixels between the two resources, and we can de-tile it in s/w. */
rsc = etna_resource(rsc->texture);
- } else if (rsc->ts_bo ||
- (rsc->layout != ETNA_LAYOUT_LINEAR &&
- util_format_get_blocksize(format) > 1 &&
- /* HALIGN 4 resources are incompatible with the resolve engine,
- * so fall back to using software to detile this resource. */
- rsc->halign != TEXTURE_HALIGN_FOUR)) {
+ } else if (etna_transfer_use_gpu(ctx, rsc, box)) {
/* If the surface has tile status, we need to resolve it first.
* The strategy we implement here is to use the RS to copy the
* depth buffer, filling in the "holes" where the tile status
--
2.20.1
More information about the mesa-dev
mailing list