Mesa (master): i965/fs: Handle conditional discards.

Kenneth Graunke kwg at kemper.freedesktop.org
Tue Feb 24 23:28:19 UTC 2015


Module: Mesa
Branch: master
Commit: 8eb6c109994de2827b0a1340a2dc8d933edaf5e0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8eb6c109994de2827b0a1340a2dc8d933edaf5e0

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Aug 19 15:22:43 2014 -0700

i965/fs: Handle conditional discards.

The discard condition tells us which channels we want killed.  We want
to invert that condition to get the channels that should survive (remain
live) in f0.1.  Emit a CMP to negate it.

Nothing generates these today, but that will change shortly.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
Reviewed-by: Connor Abbott <cwabbott0 at gmail.com>
Reviewed-by: Matt Turner <mattst88 at gmail.com>
Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/mesa/drivers/dri/i965/brw_fs_nir.cpp     |   22 ++++++++++++++--------
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp |   21 ++++++++++++---------
 2 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 03e9ee8..388e636 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -1258,16 +1258,22 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
    bool has_indirect = false;
 
    switch (instr->intrinsic) {
-   case nir_intrinsic_discard: {
+   case nir_intrinsic_discard:
+   case nir_intrinsic_discard_if: {
       /* We track our discarded pixels in f0.1.  By predicating on it, we can
-       * update just the flag bits that aren't yet discarded.  By emitting a
-       * CMP of g0 != g0, all our currently executing channels will get turned
-       * off.
+       * update just the flag bits that aren't yet discarded.  If there's no
+       * condition, we emit a CMP of g0 != g0, so all currently executing
+       * channels will get turned off.
        */
-      fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
-                                    BRW_REGISTER_TYPE_UW));
-      fs_inst *cmp = emit(CMP(reg_null_f, some_reg, some_reg,
-                              BRW_CONDITIONAL_NZ));
+      fs_inst *cmp;
+      if (instr->intrinsic == nir_intrinsic_discard_if) {
+         cmp = emit(CMP(reg_null_f, get_nir_src(instr->src[0]),
+                        fs_reg(0), BRW_CONDITIONAL_Z));
+      } else {
+         fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
+                                       BRW_REGISTER_TYPE_UW));
+         cmp = emit(CMP(reg_null_f, some_reg, some_reg, BRW_CONDITIONAL_NZ));
+      }
       cmp->predicate = BRW_PREDICATE_NORMAL;
       cmp->flag_subreg = 1;
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 7c447af..13a3bf2 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -2415,17 +2415,20 @@ fs_visitor::visit(ir_swizzle *ir)
 void
 fs_visitor::visit(ir_discard *ir)
 {
-   assert(ir->condition == NULL); /* FINISHME */
-
    /* We track our discarded pixels in f0.1.  By predicating on it, we can
-    * update just the flag bits that aren't yet discarded.  By emitting a
-    * CMP of g0 != g0, all our currently executing channels will get turned
-    * off.
+    * update just the flag bits that aren't yet discarded.  If there's no
+    * condition, we emit a CMP of g0 != g0, so all currently executing
+    * channels will get turned off.
     */
-   fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
-                                   BRW_REGISTER_TYPE_UW));
-   fs_inst *cmp = emit(CMP(reg_null_f, some_reg, some_reg,
-                           BRW_CONDITIONAL_NZ));
+   fs_inst *cmp;
+   if (ir->condition) {
+      ir->condition->accept(this);
+      cmp = emit(CMP(reg_null_f, this->result, fs_reg(0), BRW_CONDITIONAL_Z));
+   } else {
+      fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
+                                      BRW_REGISTER_TYPE_UW));
+      cmp = emit(CMP(reg_null_f, some_reg, some_reg, BRW_CONDITIONAL_NZ));
+   }
    cmp->predicate = BRW_PREDICATE_NORMAL;
    cmp->flag_subreg = 1;
 




More information about the mesa-commit mailing list