diff options
author | Zack Rusin <[email protected]> | 2013-03-27 02:38:32 -0700 |
---|---|---|
committer | Zack Rusin <[email protected]> | 2013-03-27 03:53:02 -0700 |
commit | f20f981553ede032b72988c10189be7bc2cc6bda (patch) | |
tree | 1ae36df317f6ab9ab3bfa3636091d64279681b4b /src | |
parent | b66ffcf2f8a0128497d1e0afed0416a4aa4a14be (diff) |
gallivm: Implement the breakc instruction
Required by more modern examples. Like BRK but with a condition.
Signed-off-by: Zack Rusin <[email protected]>
Reviewed-by: Brian Paul <[email protected]>
Reviewed-by: José Fonseca <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 33 |
2 files changed, 34 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c index 41ddd9923f4..dfe581d1a11 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c @@ -864,6 +864,7 @@ lp_set_default_actions(struct lp_build_tgsi_context * bld_base) bld_base->op_actions[TGSI_OPCODE_SCS] = scs_action; bld_base->op_actions[TGSI_OPCODE_XPD] = xpd_action; + bld_base->op_actions[TGSI_OPCODE_BREAKC].fetch_args = scalar_unary_fetch_args; bld_base->op_actions[TGSI_OPCODE_COS].fetch_args = scalar_unary_fetch_args; bld_base->op_actions[TGSI_OPCODE_EX2].fetch_args = scalar_unary_fetch_args; bld_base->op_actions[TGSI_OPCODE_IF].fetch_args = scalar_unary_fetch_args; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index b9de31ca710..d038b05892f 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -213,6 +213,23 @@ static void lp_exec_break(struct lp_exec_mask *mask) lp_exec_mask_update(mask); } +static void lp_exec_break_condition(struct lp_exec_mask *mask, + LLVMValueRef cond) +{ + LLVMBuilderRef builder = mask->bld->gallivm->builder; + LLVMValueRef exec_mask = LLVMBuildNot(builder, + mask->exec_mask, + "break"); + + exec_mask = LLVMBuildAnd(builder, exec_mask, cond, ""); + + mask->break_mask = LLVMBuildAnd(builder, + mask->break_mask, + exec_mask, "break_full"); + + lp_exec_mask_update(mask); +} + static void lp_exec_continue(struct lp_exec_mask *mask) { LLVMBuilderRef builder = mask->bld->gallivm->builder; @@ -2252,6 +2269,21 @@ brk_emit( } static void +breakc_emit( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + LLVMValueRef tmp; + struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); + + tmp = lp_build_cmp(&bld_base->base, PIPE_FUNC_NOTEQUAL, + emit_data->args[0], bld->bld_base.base.zero); + + lp_exec_break_condition(&bld->exec_mask, tmp); +} + +static void if_emit( const struct lp_build_tgsi_action * action, struct lp_build_tgsi_context * bld_base, @@ -2580,6 +2612,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, bld.bld_base.op_actions[TGSI_OPCODE_BGNLOOP].emit = bgnloop_emit; bld.bld_base.op_actions[TGSI_OPCODE_BGNSUB].emit = bgnsub_emit; bld.bld_base.op_actions[TGSI_OPCODE_BRK].emit = brk_emit; + bld.bld_base.op_actions[TGSI_OPCODE_BREAKC].emit = breakc_emit; bld.bld_base.op_actions[TGSI_OPCODE_CAL].emit = cal_emit; bld.bld_base.op_actions[TGSI_OPCODE_CONT].emit = cont_emit; bld.bld_base.op_actions[TGSI_OPCODE_DDX].emit = ddx_emit; |