From 8eb6c109994de2827b0a1340a2dc8d933edaf5e0 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 19 Aug 2014 15:22:43 -0700 Subject: [PATCH] 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 Reviewed-by: Connor Abbott Reviewed-by: Matt Turner Reviewed-by: Eric Anholt --- 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 03e9ee80e13..388e6360161 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 7c447af489e..13a3bf29da8 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; -- 2.30.2