nir/lower_clip: Only emit 1 discard
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Fri, 3 Feb 2023 14:59:04 +0000 (09:59 -0500)
committerMarge Bot <emma+marge@anholt.net>
Mon, 6 Feb 2023 02:50:20 +0000 (02:50 +0000)
If we have multiple clip planes, rather than emit multiple discards we can just
OR together the discard criteria. Then a nir_opt_algebraic rule kicks in to
optimize out the flt/.../flt/ior/.../ior into fmin/.../fmin/flt, generating
much less code at the end.

Written while debugging an unrelated issue with the clip lowering.

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/21103>

src/compiler/nir/nir_lower_clip.c

index 6fc9c2a..5632cbf 100644 (file)
@@ -454,17 +454,22 @@ lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables,
          load_clipdist_input(&b, in[0], 1, &clipdist[4]);
    }
 
+   nir_ssa_def *cond = NULL;
+
    for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) {
       if (ucp_enables & (1 << plane)) {
-         nir_ssa_def *cond;
-
-         cond = nir_flt(&b, clipdist[plane], nir_imm_float(&b, 0.0));
-         nir_discard_if(&b, cond);
+         nir_ssa_def *this_cond =
+            nir_flt(&b, clipdist[plane], nir_imm_float(&b, 0.0));
 
-         b.shader->info.fs.uses_discard = true;
+         cond = cond ? nir_ior(&b, cond, this_cond) : this_cond;
       }
    }
 
+   if (cond != NULL) {
+      nir_discard_if(&b, cond);
+      b.shader->info.fs.uses_discard = true;
+   }
+
    nir_metadata_preserve(impl, nir_metadata_dominance);
 }