diff options
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 8901e656ae..cb5e62e6a4 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -576,6 +576,9 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, } +/** + * Kill fragment if any of the src register values are negative. + */ static void emit_kil( struct lp_build_tgsi_soa_context *bld, @@ -606,6 +609,9 @@ emit_kil( if(terms[chan_index]) { LLVMValueRef chan_mask; + /* + * If term < 0 then mask = 0 else mask = ~0. + */ chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero); if(mask) @@ -621,6 +627,32 @@ emit_kil( /** + * Predicated fragment kill. + * XXX Actually, we do an unconditional kill (as in tgsi_exec.c). + * The only predication is the execution mask which will apply if + * we're inside a loop or conditional. + */ +static void +emit_kilp(struct lp_build_tgsi_soa_context *bld, + const struct tgsi_full_instruction *inst) +{ + LLVMValueRef mask; + + /* For those channels which are "alive", disable fragment shader + * execution. + */ + if (bld->exec_mask.has_mask) { + mask = LLVMBuildNot(bld->base.builder, bld->exec_mask.exec_mask, "kilp"); + } + else { + mask = bld->base.zero; + } + + lp_build_mask_update(bld->mask, mask); +} + + +/** * Check if inst src/dest regs use indirect addressing into temporary * register file. */ @@ -1179,8 +1211,7 @@ emit_instruction( case TGSI_OPCODE_KILP: /* predicated kill */ - /* FIXME */ - return 0; + emit_kilp( bld, inst ); break; case TGSI_OPCODE_KIL: |