From 3346eb55edaea49495353538cd2b8e97113a39c0 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 3 Mar 2025 10:18:43 -0600 Subject: [PATCH] iris: Use pipe_box helpers for damage calculations The old calculations are wrong. They add width+x and call that a width the same with y and height. This is wrong but it's wrong in a way that only ever increases damage so we never noticed it. However, util/box.h has helpers for these operations which don't have this bug. Let's use them and make the code simpler, more obvious, and correct. We also weren't flipping the damage like we're supposed to and that was most likely not getting noticed because of the over-damage. Reviewed-by: Kenneth Graunke Part-of: --- src/gallium/drivers/iris/iris_screen.c | 44 ++++++++++++-------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/gallium/drivers/iris/iris_screen.c b/src/gallium/drivers/iris/iris_screen.c index 0e162c54750..2edfc8a7c50 100644 --- a/src/gallium/drivers/iris/iris_screen.c +++ b/src/gallium/drivers/iris/iris_screen.c @@ -628,32 +628,30 @@ iris_set_damage_region(struct pipe_screen *pscreen, struct pipe_resource *pres, { struct iris_resource *res = (struct iris_resource *)pres; - res->use_damage = nrects > 0; - if (!res->use_damage) + if (nrects == 0) { + res->use_damage = false; return; - - res->damage.x = INT32_MAX; - res->damage.y = INT32_MAX; - res->damage.width = 0; - res->damage.height = 0; - - for (unsigned i = 0; i < nrects; i++) { - res->damage.x = MIN2(res->damage.x, rects[i].x); - res->damage.y = MIN2(res->damage.y, rects[i].y); - res->damage.width = MAX2(res->damage.width, rects[i].width + rects[i].x); - res->damage.height = MAX2(res->damage.height, rects[i].height + rects[i].y); - - if (unlikely(res->damage.x == 0 && - res->damage.y == 0 && - res->damage.width == res->base.b.width0 && - res->damage.height == res->base.b.height0)) - break; } - res->damage.x = MAX2(res->damage.x, 0); - res->damage.y = MAX2(res->damage.y, 0); - res->damage.width = MIN2(res->damage.width, res->base.b.width0); - res->damage.height = MIN2(res->damage.height, res->base.b.height0); + struct pipe_box damage = rects[0]; + for (unsigned i = 1; i < nrects; i++) + u_box_union_2d(&damage, &damage, &rects[i]); + + /* The damage we get from EGL uses a lower-left origin but the hardware + * uses upper-left so we need to flip it. + */ + damage.y = res->base.b.height0 - (damage.y + damage.height); + + /* Intersect with the area of the resource */ + struct pipe_box res_area; + u_box_origin_2d(res->base.b.width0, res->base.b.height0, &res_area); + u_box_intersect_2d(&damage, &damage, &res_area); + + res->damage = damage; + res->use_damage = damage.x != 0 || + damage.y != 0 || + damage.width != res->base.b.width0 || + damage.height != res->base.b.height0; } struct pipe_screen *