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.
This commit is contained in:
Brian Paul
2010-04-21 16:27:23 -06:00
parent 5c364b3ef7
commit feffd259da

View File

@@ -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)
@@ -620,6 +626,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: