From 080b751d4ac5a1eacc44f7cef4e772734b3c5c18 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 13 Jul 2020 19:17:33 -0400 Subject: [PATCH] panfrost: Add rectangle subtraction algorithm For better supporting KHR_partial_update. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/panfrost/meson.build | 1 + .../drivers/panfrost/pan_partial_update.c | 135 ++++++++++++++++++ .../drivers/panfrost/pan_partial_update.h | 49 +++++++ src/gallium/drivers/panfrost/pan_resource.c | 8 ++ 4 files changed, 193 insertions(+) create mode 100644 src/gallium/drivers/panfrost/pan_partial_update.c create mode 100644 src/gallium/drivers/panfrost/pan_partial_update.h diff --git a/src/gallium/drivers/panfrost/meson.build b/src/gallium/drivers/panfrost/meson.build index f71a4cc2db5..c3181e7fab3 100644 --- a/src/gallium/drivers/panfrost/meson.build +++ b/src/gallium/drivers/panfrost/meson.build @@ -40,6 +40,7 @@ files_panfrost = files( 'pan_fragment.c', 'pan_sfbd.c', 'pan_mfbd.c', + 'pan_partial_update.c', ) panfrost_includes = [ diff --git a/src/gallium/drivers/panfrost/pan_partial_update.c b/src/gallium/drivers/panfrost/pan_partial_update.c new file mode 100644 index 00000000000..b4b61b7a03c --- /dev/null +++ b/src/gallium/drivers/panfrost/pan_partial_update.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2020 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include "util/ralloc.h" +#include "pan_partial_update.h" + +static struct pan_rect +pan_make_rect(unsigned minx, unsigned miny, unsigned maxx, unsigned maxy) +{ + struct pan_rect r = { + .minx = minx, + .miny = miny, + .maxx = maxx, + .maxy = maxy + }; + + return r; +} + +static struct pan_rect +pan_from_pipe(const struct pipe_box *p) +{ + return pan_make_rect(p->x, p->y, p->x + p->width, p->y + p->height); +} + +/* Helper to clip a rect inside another box */ + +static struct pan_rect +pan_clip_rect( + const struct pan_rect *r, + const struct pan_rect *clip) +{ + unsigned minx = MAX2(r->minx, clip->minx); + unsigned miny = MAX2(r->miny, clip->miny); + unsigned maxx = MAX2(MIN2(r->maxx, clip->maxx), minx); + unsigned maxy = MAX2(MIN2(r->maxy, clip->maxy), miny); + + return pan_make_rect(minx, miny, maxx, maxy); +} + +/* Subtract d from r, yielding four (possibly degenerate) rectangles for each + * bounding region */ + +static void +pan_subtract_from_rect( + struct pan_rect *out, + const struct pan_rect *r, + const struct pan_rect *d) +{ + struct pan_rect dc = pan_clip_rect(r, d); + + out[0] = pan_make_rect(r->minx, r->miny, dc.minx, r->maxy); + out[1] = pan_make_rect(dc.minx, r->miny, dc.maxx, dc.miny); + out[2] = pan_make_rect(dc.maxx, r->miny, r->maxx, r->maxy); + out[3] = pan_make_rect(dc.minx, dc.maxy, dc.maxx, r->maxy); +} + +/* Subtract d from the set of rects R, returning the number of + * (non-degenerate) rectangles returned. + * + * out must be at least sizeof(struct pan_rect) * R_len * 4 bytes + * + * Trivially satisfies: return value < (R_len * 4) */ + +static unsigned +pan_subtract_from_rects( + struct pan_rect *out, + const struct pan_rect *R, + unsigned R_len, + const struct pan_rect *d) +{ + unsigned count = 0; + struct pan_rect temp[4]; + + for (unsigned r = 0; r < R_len; ++r) { + pan_subtract_from_rect(temp, &R[r], d); + + /* Copy the rectangles with nonzero area */ + for (unsigned i = 0; i < 4; ++i) { + if (temp[i].maxx <= temp[i].minx) continue; + if (temp[i].maxy <= temp[i].miny) continue; + + out[count++] = temp[i]; + } + } + + return count; +} + +struct pan_rect * +pan_subtract_damage( + void *memctx, + unsigned initial_w, unsigned initial_h, + unsigned nrects, + const struct pipe_box *rects, + unsigned *out_len) +{ + struct pan_rect *R = ralloc(memctx, struct pan_rect); + *R = pan_make_rect(0, 0, initial_w, initial_h); + unsigned R_len = 1; + + for (unsigned d = 0; d < nrects; ++d) { + const struct pan_rect D = pan_from_pipe(&rects[d]); + struct pan_rect *out = rzalloc_array(memctx, struct pan_rect, + R_len * 4); + + R_len = pan_subtract_from_rects(out, R, R_len, &D); + ralloc_free(R); + R = out; + } + + *out_len = R_len; + return R; +} diff --git a/src/gallium/drivers/panfrost/pan_partial_update.h b/src/gallium/drivers/panfrost/pan_partial_update.h new file mode 100644 index 00000000000..9d85be664b9 --- /dev/null +++ b/src/gallium/drivers/panfrost/pan_partial_update.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2019 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors (Collabora): + * Alyssa Rosenzweig + * + */ + +#ifndef __PAN_PARTIAL_UPDATE_H +#define __PAN_PARTIAL_UPDATE_H + +#include "pipe/p_state.h" + +/* Like pipe_box but in terms of maxx/maxy instead of w/h, which is much easier + * to work with for our purposes */ + +struct pan_rect { + unsigned minx, miny; + unsigned maxx, maxy; +}; + +struct pan_rect * +pan_subtract_damage( + void *memctx, + unsigned initial_w, unsigned initial_h, + unsigned nrects, + const struct pipe_box *rects, + unsigned *R_len); + +#endif diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 08e0caba885..b79ebe72850 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -499,6 +499,14 @@ panfrost_resource_set_damage_region(struct pipe_screen *screen, damage_extent->maxy = MAX2(damage_extent->maxy, MIN2(y + h, res->height0)); } + + if (nrects == 0) { + damage_extent->minx = 0; + damage_extent->miny = 0; + damage_extent->maxx = res->width0; + damage_extent->maxy = res->height0; + } + } static struct pipe_resource * -- 2.30.2