lima_update_damage_pp_stream(struct lima_context *ctx)
{
struct lima_damage_region *ds = lima_ctx_get_damage(ctx);
- struct pipe_scissor_state max = ds->region[0];
+ struct pipe_scissor_state *bound = &ds->bound;
- /* find a max region to cover all the damage region */
- for (int i = 1; i < ds->num_region; i++) {
- struct pipe_scissor_state *ss = ds->region + i;
- max.minx = MIN2(max.minx, ss->minx);
- max.miny = MIN2(max.miny, ss->miny);
- max.maxx = MAX2(max.maxx, ss->maxx);
- max.maxy = MAX2(max.maxy, ss->maxy);
- }
-
- int tiled_w = max.maxx - max.minx;
- int tiled_h = max.maxy - max.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);
ctx->pp_stream.bo = res->bo;
ctx->pp_stream.bo_offset = offset;
- lima_update_pp_stream(ctx, max.minx, max.miny, tiled_w, tiled_h);
+ lima_update_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);
return true;
}
+static void
+get_scissor_from_box(struct pipe_scissor_state *s,
+ const struct pipe_box *b, int h)
+{
+ int y = h - (b->y + b->height);
+ /* region in tile unit */
+ s->minx = b->x >> 4;
+ s->miny = y >> 4;
+ s->maxx = (b->x + b->width + 0xf) >> 4;
+ s->maxy = (y + b->height + 0xf) >> 4;
+}
+
+static void
+get_damage_bound_box(struct pipe_resource *pres,
+ const struct pipe_box *rects,
+ unsigned int nrects,
+ struct pipe_scissor_state *bound)
+{
+ struct pipe_box b = rects[0];
+
+ for (int i = 1; i < nrects; i++)
+ u_box_union_2d(&b, &b, rects + i);
+
+ int ret = u_box_clip_2d(&b, &b, pres->width0, pres->height0);
+ if (ret < 0)
+ memset(bound, 0, sizeof(*bound));
+ else
+ get_scissor_from_box(bound, &b, pres->height0);
+}
+
static void
lima_resource_set_damage_region(struct pipe_screen *pscreen,
struct pipe_resource *pres,
return;
}
+ struct pipe_scissor_state *bound = &damage->bound;
+ get_damage_bound_box(pres, rects, nrects, bound);
+
damage->region = CALLOC(nrects, sizeof(*damage->region));
if (!damage->region)
return;
- for (i = 0; i < nrects; i++) {
- struct pipe_scissor_state *r = damage->region + i;
- int y = pres->height0 - (rects[i].y + rects[i].height);
- /* region in tile unit */
- r->minx = rects[i].x >> 4;
- r->miny = y >> 4;
- r->maxx = (rects[i].x + rects[i].width + 0xf) >> 4;
- r->maxy = (y + rects[i].height + 0xf) >> 4;
- }
+ for (i = 0; i < nrects; i++)
+ get_scissor_from_box(damage->region + i, rects + i,
+ pres->height0);
/* is region aligned to tiles? */
damage->aligned = true;