diff --git a/src/asahi/lib/agx_nir_lower_tilebuffer.c b/src/asahi/lib/agx_nir_lower_tilebuffer.c index 98d2da55e5f..81d32275d51 100644 --- a/src/asahi/lib/agx_nir_lower_tilebuffer.c +++ b/src/asahi/lib/agx_nir_lower_tilebuffer.c @@ -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; }