summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorVasily Khoruzhick <[email protected]>2019-10-09 19:23:54 -0700
committerVasily Khoruzhick <[email protected]>2020-01-05 00:16:36 -0800
commit4f5bfe2a5e252f1f7ae047949d645918f374e07c (patch)
tree5457c5a029d2dad6b0cec58959c8e996941996d9 /src/gallium
parent83abdf8e4518a40dc0c74f7c85d7e9a6d76ce7a5 (diff)
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 <[email protected]> Signed-off-by: Vasily Khoruzhick <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/lima/lima_context.c3
-rw-r--r--src/gallium/drivers/lima/lima_context.h1
-rw-r--r--src/gallium/drivers/lima/lima_draw.c70
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);
@@ -623,6 +661,15 @@ lima_update_submit_bo(struct lima_context *ctx)
}
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();
}