asahi: Force translucency for ignored render targets
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sun, 3 Sep 2023 14:14:14 +0000 (10:14 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 5 Sep 2023 18:50:34 +0000 (18:50 +0000)
If we bound 4 render targets but we only write to 1 of them, the other 3 need
their contents preserved. This requires either properly configuring HSR to
implement colour masking (TODO) or using the big hammer of setting TRANSLUCENT.
This patch picks the latter for now.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25052>

src/asahi/lib/agx_nir_lower_tilebuffer.c

index 98d2da5..81d3227 100644 (file)
@@ -22,6 +22,7 @@ struct ctx {
    bool *translucent;
    unsigned bindless_base;
    bool any_memory_stores;
+   uint8_t outputs_written;
 };
 
 static bool
@@ -220,6 +221,8 @@ tib_impl(nir_builder *b, nir_instr *instr, void *data)
    unsigned comps = util_format_get_nr_components(logical_format);
 
    if (intr->intrinsic == nir_intrinsic_store_output) {
+      ctx->outputs_written |= BITFIELD_BIT(rt);
+
       /* Only write components that actually exist */
       uint16_t write_mask = (uint16_t)BITFIELD_MASK(comps);
 
@@ -315,5 +318,19 @@ agx_nir_lower_tilebuffer(nir_shader *shader, struct agx_tilebuffer_layout *tib,
       nir_fence_pbe_to_tex_pixel_agx(&b);
    }
 
+   /* If there are any render targets bound to the framebuffer that aren't
+    * statically written by the fragment shader, that acts as an implicit mask
+    * and requires translucency.
+    *
+    * XXX: Could be optimized.
+    */
+   for (unsigned i = 0; i < ARRAY_SIZE(tib->logical_format); ++i) {
+      bool exists = tib->logical_format[i] != PIPE_FORMAT_NONE;
+      bool written = ctx.outputs_written & BITFIELD_BIT(i);
+
+      if (translucent)
+         *translucent |= (exists && !written);
+   }
+
    return progress;
 }