Mesa (master): lima: don't reload and redraw tiles that were not updated

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Jan 5 08:49:42 UTC 2020


Module: Mesa
Branch: master
Commit: 4f5bfe2a5e252f1f7ae047949d645918f374e07c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4f5bfe2a5e252f1f7ae047949d645918f374e07c

Author: Vasily Khoruzhick <anarsoul at gmail.com>
Date:   Wed Oct  9 19:23:54 2019 -0700

lima: don't reload and redraw tiles that were not updated

We don't need to reload and redraw some tiles if framebuffer was not
cleared and scissor test was enabled for some of draws. This simple
optimization fixes cursor lag in X11

Reviewed-by: Qiang Yu <yuq825 at gmail.com>
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>

---

 src/gallium/drivers/lima/lima_context.c |  3 ++
 src/gallium/drivers/lima/lima_context.h |  1 +
 src/gallium/drivers/lima/lima_draw.c    | 70 +++++++++++++++++++++++++++++----
 3 files changed, 67 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/lima/lima_context.c b/src/gallium/drivers/lima/lima_context.c
index 44f627ac1da..e2d48d155a3 100644
--- a/src/gallium/drivers/lima/lima_context.c
+++ b/src/gallium/drivers/lima/lima_context.c
@@ -212,6 +212,9 @@ lima_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    ctx->base.stream_uploader = ctx->uploader;
    ctx->base.const_uploader = ctx->uploader;
 
+   ctx->damage_rect.minx = ctx->damage_rect.miny = 0xffff;
+   ctx->damage_rect.maxx = ctx->damage_rect.maxy = 0;
+
    util_dynarray_init(&ctx->vs_cmd_array, ctx);
    util_dynarray_init(&ctx->plbu_cmd_array, ctx);
 
diff --git a/src/gallium/drivers/lima/lima_context.h b/src/gallium/drivers/lima/lima_context.h
index b2fa8d1d483..e62630b7a6d 100644
--- a/src/gallium/drivers/lima/lima_context.h
+++ b/src/gallium/drivers/lima/lima_context.h
@@ -195,6 +195,7 @@ struct lima_context {
    struct lima_context_framebuffer framebuffer;
    struct lima_context_viewport_state viewport;
    struct pipe_scissor_state scissor;
+   struct pipe_scissor_state damage_rect;
    struct lima_context_clear clear;
    struct lima_vs_shader_state *vs;
    struct lima_fs_shader_state *fs;
diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c
index 4fb2e12cd12..72cd3f6cb35 100644
--- a/src/gallium/drivers/lima/lima_draw.c
+++ b/src/gallium/drivers/lima/lima_draw.c
@@ -475,11 +475,19 @@ lima_generate_pp_stream(struct lima_context *ctx, int off_x, int off_y,
     * close enough which should result close workload
     */
    int max = MAX2(tiled_w, tiled_h);
-   int dim = util_logbase2_ceil(max);
-   int count = 1 << (dim + dim);
    int index = 0;
    uint32_t *stream[4];
    int si[4] = {0};
+   int dim = 0;
+   int count = 0;
+
+   /* Don't update count if we get zero rect. We'll just generate
+    * PP stream with just terminators in it.
+    */
+   if ((tiled_w * tiled_h) != 0) {
+      dim = util_logbase2_ceil(max);
+      count = 1 << (dim + dim);
+   }
 
    for (i = 0; i < num_pp; i++)
       stream[i] = ps->bo->map + ps->bo_offset + ps->offset[i];
@@ -522,10 +530,31 @@ static void
 lima_update_damage_pp_stream(struct lima_context *ctx)
 {
    struct lima_damage_region *ds = lima_ctx_get_damage(ctx);
-   struct pipe_scissor_state *bound = &ds->bound;
+   struct lima_context_framebuffer *fb = &ctx->framebuffer;
+   struct pipe_scissor_state bound;
+
+   if (ds && ds->region) {
+      struct pipe_scissor_state *dbound = &ds->bound;
+      bound.minx = MAX2(dbound->minx, ctx->damage_rect.minx >> 4);
+      bound.miny = MAX2(dbound->miny, ctx->damage_rect.miny >> 4);
+      bound.maxx = MIN2(dbound->maxx, (ctx->damage_rect.maxx + 0xf) >> 4);
+      bound.maxy = MIN2(dbound->maxy, (ctx->damage_rect.maxy + 0xf) >> 4);
+   } else {
+      bound.minx = ctx->damage_rect.minx >> 4;
+      bound.miny = ctx->damage_rect.miny >> 4;
+      bound.maxx = (ctx->damage_rect.maxx + 0xf) >> 4;
+      bound.maxy = (ctx->damage_rect.maxy + 0xf) >> 4;
+   }
+
+   /* Clamp to FB size */
+   bound.minx = MIN2(bound.minx, fb->tiled_w);
+   bound.miny = MIN2(bound.miny, fb->tiled_h);
+   bound.maxx = MIN2(bound.maxx, fb->tiled_w);
+   bound.maxy = MIN2(bound.maxy, fb->tiled_h);
+
+   int tiled_w = bound.maxx - bound.minx;
+   int tiled_h = bound.maxy - bound.miny;
 
-   int tiled_w = bound->maxx - bound->minx;
-   int tiled_h = bound->maxy - bound->miny;
    struct lima_screen *screen = lima_screen(ctx->base.screen);
    int size = lima_get_pp_stream_size(
       screen->num_pp, tiled_w, tiled_h, ctx->pp_stream.offset);
@@ -539,7 +568,7 @@ lima_update_damage_pp_stream(struct lima_context *ctx)
    ctx->pp_stream.bo = res->bo;
    ctx->pp_stream.bo_offset = offset;
 
-   lima_generate_pp_stream(ctx, bound->minx, bound->miny, tiled_w, tiled_h);
+   lima_generate_pp_stream(ctx, bound.minx, bound.miny, tiled_w, tiled_h);
 
    lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_READ);
    pipe_resource_reference(&pres, NULL);
@@ -581,11 +610,20 @@ lima_update_full_pp_stream(struct lima_context *ctx)
    lima_submit_add_bo(ctx->pp_submit, s->bo, LIMA_SUBMIT_BO_READ);
 }
 
+static bool
+lima_damage_fullscreen(struct lima_context *ctx)
+{
+   return ctx->damage_rect.minx == 0 &&
+          ctx->damage_rect.miny == 0 &&
+          ctx->damage_rect.maxx == ctx->framebuffer.base.width &&
+          ctx->damage_rect.maxy == ctx->framebuffer.base.height;
+}
+
 static void
 lima_update_pp_stream(struct lima_context *ctx)
 {
    struct lima_damage_region *damage = lima_ctx_get_damage(ctx);
-   if (damage && damage->region)
+   if ((damage && damage->region) || !lima_damage_fullscreen(ctx))
       lima_update_damage_pp_stream(ctx);
    else if (ctx->plb_pp_stream)
       lima_update_full_pp_stream(ctx);
@@ -622,6 +660,15 @@ lima_update_submit_bo(struct lima_context *ctx)
    lima_submit_add_bo(ctx->pp_submit, screen->pp_buffer, LIMA_SUBMIT_BO_READ);
 }
 
+static void
+lima_damage_rect_union(struct lima_context *ctx, unsigned minx, unsigned maxx, unsigned miny, unsigned maxy)
+{
+   ctx->damage_rect.minx = MIN2(ctx->damage_rect.minx, minx);
+   ctx->damage_rect.miny = MIN2(ctx->damage_rect.miny, miny);
+   ctx->damage_rect.maxx = MAX2(ctx->damage_rect.maxx, maxx);
+   ctx->damage_rect.maxy = MAX2(ctx->damage_rect.maxy, maxy);
+}
+
 static void
 lima_clear(struct pipe_context *pctx, unsigned buffers,
            const union pipe_color_union *color, double depth, unsigned stencil)
@@ -664,6 +711,9 @@ lima_clear(struct pipe_context *pctx, unsigned buffers,
    lima_pack_head_plbu_cmd(ctx);
 
    ctx->dirty |= LIMA_CONTEXT_DIRTY_CLEAR;
+
+   lima_damage_rect_union(ctx, 0, ctx->framebuffer.base.width,
+                               0, ctx->framebuffer.base.height);
 }
 
 enum lima_attrib_type {
@@ -819,8 +869,11 @@ lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
    if (ctx->rasterizer->base.scissor) {
       struct pipe_scissor_state *scissor = &ctx->scissor;
       PLBU_CMD_SCISSORS(scissor->minx, scissor->maxx, scissor->miny, scissor->maxy);
+      lima_damage_rect_union(ctx, scissor->minx, scissor->maxx,
+                                  scissor->miny, scissor->maxy);
    } else {
       PLBU_CMD_SCISSORS(0, fb->base.width, 0, fb->base.height);
+      lima_damage_rect_union(ctx, 0, fb->base.width, 0, fb->base.height);
    }
 
    PLBU_CMD_UNKNOWN1();
@@ -1718,6 +1771,9 @@ _lima_flush(struct lima_context *ctx, bool end_of_frame)
 
    ctx->pp_max_stack_size = 0;
 
+   ctx->damage_rect.minx = ctx->damage_rect.miny = 0xffff;
+   ctx->damage_rect.maxx = ctx->damage_rect.maxy = 0;
+
    lima_dump_file_next();
 }
 




More information about the mesa-commit mailing list