diff options
Diffstat (limited to 'src/gallium/auxiliary')
| -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: | 
