nir/lower_blend: Set uses_fbfetch_output conservatively
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sun, 9 Apr 2023 14:14:29 +0000 (10:14 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 11 Apr 2023 04:16:32 +0000 (04:16 +0000)
Only insert a load_output if we're going to use it, don't rely on it getting
DCE'd since that will mess up the shader info. This does require a bit of logic
to figure out whether we do need it.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22385>

src/compiler/nir/nir_lower_blend.c

index 9a5ade4..f61a221 100644 (file)
@@ -188,6 +188,17 @@ should_clamp_factor(enum blend_factor factor, bool inverted, bool snorm)
    unreachable("invalid blend factor");
 }
 
+static bool
+channel_uses_dest(nir_lower_blend_channel chan)
+{
+   return chan.src_factor == BLEND_FACTOR_DST_COLOR ||
+          chan.src_factor == BLEND_FACTOR_DST_ALPHA ||
+          chan.src_factor == BLEND_FACTOR_SRC_ALPHA_SATURATE ||
+          !(chan.dst_factor == BLEND_FACTOR_ZERO && !chan.invert_dst_factor) ||
+          chan.func == BLEND_FUNC_MIN ||
+          chan.func == BLEND_FUNC_MAX;
+}
+
 static nir_ssa_def *
 nir_blend_factor(
    nir_builder *b,
@@ -510,19 +521,27 @@ nir_lower_blend_instr(nir_builder *b, nir_instr *instr, void *data)
    assert(store->src[0].is_ssa);
    nir_ssa_def *src = nir_pad_vector(b, store->src[0].ssa, 4);
 
-   /* Grab the previous fragment color */
-   b->shader->info.outputs_read |= BITFIELD64_BIT(sem.location);
-   b->shader->info.fs.uses_fbfetch_output = true;
-   sem.fb_fetch_output = true;
-
    assert(nir_src_as_uint(store->src[1]) == 0 && "store_output invariant");
 
-   nir_ssa_def *dst =
-      nir_load_output(b, 4,
-                      nir_src_bit_size(store->src[0]),
-                      nir_imm_int(b, 0),
-                     .dest_type = nir_intrinsic_src_type(store),
-                     .io_semantics = sem);
+   /* Grab the previous fragment color if we need it */
+   nir_ssa_def *dst;
+
+   if (channel_uses_dest(options->rt[rt].rgb) ||
+       channel_uses_dest(options->rt[rt].alpha) ||
+       options->logicop_enable ||
+       options->rt[rt].colormask != BITFIELD_MASK(4)) {
+
+      b->shader->info.outputs_read |= BITFIELD64_BIT(sem.location);
+      b->shader->info.fs.uses_fbfetch_output = true;
+      sem.fb_fetch_output = true;
+
+      dst = nir_load_output(b, 4, nir_src_bit_size(store->src[0]),
+                            nir_imm_int(b, 0),
+                            .dest_type = nir_intrinsic_src_type(store),
+                            .io_semantics = sem);
+   } else {
+      dst = nir_ssa_undef(b, 4, nir_src_bit_size(store->src[0]));
+   }
 
    /* Blend the two colors per the passed options. We only call nir_blend if
     * blending is enabled with a blend mode other than replace (independent of