diff options
author | Brian Paul <[email protected]> | 2010-04-21 16:27:23 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2010-04-21 16:30:13 -0600 |
commit | feffd259da5f2655222a2f26e2e5665a9e28173f (patch) | |
tree | 5da3ef19faea530f2579933ee4164456c1f1e0b5 /src/gallium/auxiliary/gallivm | |
parent | 5c364b3ef78cd36a41c43a771efe5b631ea9559b (diff) |
gallivm: implement TGSI KILP
As in tgsi_exec.c we don't actually rely on condition codes; we do
an unconditional kill. The only predication comes from the execution
mask which applies inside loops/conditionals.
Diffstat (limited to 'src/gallium/auxiliary/gallivm')
-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 8901e656aed..cb5e62e6a41 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: |