diff --git a/.pick_status.json b/.pick_status.json index 82d89f11505..3a6348c9dc4 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -5104,7 +5104,7 @@ "description": "zink: Use pipe_box helpers for damage calculations", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "3d38c9597ff3b687026fa4c664f8b4aa20b97f53", "notes": null diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index ac9e726630c..bc0cc58d2b9 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -1469,30 +1469,35 @@ zink_set_damage_region(struct pipe_screen *pscreen, struct pipe_resource *pres, { struct zink_resource *res = zink_resource(pres); - for (unsigned i = 0; i < nrects; i++) { - int y = pres->height0 - rects[i].y - rects[i].height; - /* convert back to coord-based rects to use coordinate calcs */ - struct u_rect currect = { - .x0 = res->damage.offset.x, - .y0 = res->damage.offset.y, - .x1 = res->damage.offset.x + res->damage.extent.width, - .y1 = res->damage.offset.y + res->damage.extent.height, - }; - struct u_rect newrect = { - .x0 = rects[i].x, - .y0 = y, - .x1 = rects[i].x + rects[i].width, - .y1 = y + rects[i].height, - }; - struct u_rect u; - u_rect_union(&u, &currect, &newrect); - res->damage.extent.width = u.y1 - u.y0; - res->damage.extent.height = u.x1 - u.x0; - res->damage.offset.x = u.x0; - res->damage.offset.y = u.y0; + if (nrects == 0) { + res->use_damage = false; + return; } - res->use_damage = nrects > 0; + 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 Vulkan uses + * upper-left so we need to flip it. + */ + damage.y = pres->height0 - (damage.y + damage.height); + + /* Intersect with the area of the resource */ + struct pipe_box res_area; + u_box_origin_2d(pres->width0, pres->height0, &res_area); + u_box_intersect_2d(&damage, &damage, &res_area); + + res->damage = (VkRect2D) { + .offset.x = damage.x, + .offset.y = damage.y, + .extent.width = damage.width, + .extent.height = damage.height, + }; + res->use_damage = damage.x != 0 || + damage.y != 0 || + damage.width != res->base.b.width0 || + damage.height != res->base.b.height0; } static void