panfrost: Add a bitset of render targets read by shaders

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5755>
diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c
index d398d21..06ee980 100644
--- a/src/gallium/drivers/panfrost/pan_assemble.c
+++ b/src/gallium/drivers/panfrost/pan_assemble.c
@@ -226,6 +226,12 @@
                 if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL))
                         state->writes_stencil = true;
 
+                uint64_t outputs_read = s->info.outputs_read;
+                if (outputs_read & BITFIELD64_BIT(FRAG_RESULT_COLOR))
+                        outputs_read |= BITFIELD64_BIT(FRAG_RESULT_DATA0);
+
+                state->outputs_read = outputs_read >> FRAG_RESULT_DATA0;
+
                 /* List of reasons we need to execute frag shaders when things
                  * are masked off */
 
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index abc0621..9806f74 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -878,7 +878,8 @@
                 bool depth_enabled = fs->writes_depth ||
                    (zsa && zsa->depth.enabled && zsa->depth.func != PIPE_FUNC_ALWAYS);
 
-                SET_BIT(fragmeta->midgard1.flags_lo, MALI_READS_TILEBUFFER, !depth_enabled && fs->can_discard);
+                SET_BIT(fragmeta->midgard1.flags_lo, MALI_READS_TILEBUFFER,
+                        fs->outputs_read || (!depth_enabled && fs->can_discard));
                 SET_BIT(fragmeta->midgard1.flags_lo, MALI_READS_ZS, depth_enabled && fs->can_discard);
         }
 
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index 7c438f6..0cf7b3e 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -664,6 +664,21 @@
                 }
         }
 
+        if (variant->outputs_read) {
+                struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer;
+
+                unsigned i;
+                BITSET_FOREACH_SET(i, &variant->outputs_read, 8) {
+                        enum pipe_format fmt = PIPE_FORMAT_R8G8B8A8_UNORM;
+
+                        if ((fb->nr_cbufs > i) && fb->cbufs[i])
+                                fmt = fb->cbufs[i]->format;
+
+                        if (variant->rt_formats[i] != fmt)
+                                return false;
+                }
+        }
+
         /* Point sprites TODO on bifrost, always pass */
         if (is_fragment && rasterizer && (rasterizer->sprite_coord_enable |
                                           variant->point_sprite_mask)
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index 2feb08f..3e5c6d6 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -225,6 +225,7 @@
         unsigned first_tag;
         struct panfrost_bo *bo;
 
+        BITSET_WORD outputs_read;
         enum pipe_format rt_formats[8];
 };