panfrost: Make sure we reset the damage region of RTs at flush time
authorBoris Brezillon <boris.brezillon@collabora.com>
Thu, 14 Nov 2019 08:35:27 +0000 (09:35 +0100)
committerBoris Brezillon <boris.brezillon@collabora.com>
Fri, 29 Nov 2019 09:20:29 +0000 (10:20 +0100)
We must reset the damage info of our render targets here even though a
damage reset normally happens when the DRI layer swaps buffers. That's
because there can be implicit flushes the GL app is not aware of, and
those might impact the damage region: if part of the damaged portion
is drawn during those implicit flushes, you have to reload those areas
before next draws are pushed, and since the driver can't easily know
what's been modified by the draws it flushed, the easiest solution is
to reload everything.

Reported-by: Carsten Haitzler <raster@rasterman.com>
Fixes: 65ae86b85422 ("panfrost: Add support for KHR_partial_update()")
Cc: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/pan_job.c
src/gallium/drivers/panfrost/pan_resource.c
src/gallium/drivers/panfrost/pan_resource.h

index 3df1cc226ee70c2a57798365c7478a1d7f90b326..ea6bd02251175437a2d7d32988389a8fc9cdc009 100644 (file)
@@ -940,6 +940,25 @@ panfrost_batch_submit(struct panfrost_batch *batch)
         if (ret)
                 fprintf(stderr, "panfrost_batch_submit failed: %d\n", ret);
 
+        /* We must reset the damage info of our render targets here even
+         * though a damage reset normally happens when the DRI layer swaps
+         * buffers. That's because there can be implicit flushes the GL
+         * app is not aware of, and those might impact the damage region: if
+         * part of the damaged portion is drawn during those implicit flushes,
+         * you have to reload those areas before next draws are pushed, and
+         * since the driver can't easily know what's been modified by the draws
+         * it flushed, the easiest solution is to reload everything.
+         */
+        for (unsigned i = 0; i < batch->key.nr_cbufs; i++) {
+                struct panfrost_resource *res;
+
+                if (!batch->key.cbufs[i])
+                        continue;
+
+                res = pan_resource(batch->key.cbufs[i]->texture);
+                panfrost_resource_reset_damage(res);
+        }
+
 out:
         panfrost_freeze_batch(batch);
         panfrost_free_batch(batch);
index c3fb12777b73526f50c22f7a8594427f6ece42b6..df0fc9e5cac03944ac28ab843947874e9997b358 100644 (file)
@@ -48,7 +48,7 @@
 #include "pan_util.h"
 #include "pan_tiling.h"
 
-static void
+void
 panfrost_resource_reset_damage(struct panfrost_resource *pres)
 {
         /* We set the damage extent to the full resource size but keep the
index 22404a609e12c0f6a65576b1c20a3f86b46a173b..a9c4d7cc539623339b6d57805305bfde32f513ac 100644 (file)
@@ -135,6 +135,9 @@ void
 panfrost_blit_wallpaper(struct panfrost_context *ctx,
                         struct pipe_box *box);
 
+void
+panfrost_resource_reset_damage(struct panfrost_resource *pres);
+
 void
 panfrost_resource_set_damage_region(struct pipe_screen *screen,
                                     struct pipe_resource *res,