On 03/26/2013 10:38 AM, Zack Rusin wrote:
we were missing implementation of the breakc instruction and our TGSI semantics currently require an implicit endprim at the end of GS if none is present - this implements both.
Maybe I'm dense, but off-hand I don't see the relationship between endprim and breakc. Can you elaborate?
Signed-off-by: Zack Rusin<za...@vmware.com> --- src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 6 ++++ src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c | 1 + src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 38 ++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 4c6456e..4acc592 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -392,6 +392,12 @@ struct lp_build_tgsi_soa_context LLVMValueRef emitted_prims_vec; LLVMValueRef total_emitted_vertices_vec; LLVMValueRef emitted_vertices_vec; + /* if a shader doesn't have ENDPRIM instruction but it has + * a number of EMIT instructions it means the END instruction + * implicitly invokes ENDPRIM. handle this via a flag here + * in the future maybe we can enforce TGSI to always have + * an explicit ENDPRIM */ + boolean pending_end_primitive; LLVMValueRef consts_ptr; const LLVMValueRef *pos; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c index 41ddd99..55bb8e3 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c @@ -867,6 +867,7 @@ lp_set_default_actions(struct lp_build_tgsi_context * bld_base) 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; + bld_base->op_actions[TGSI_OPCODE_BREAKC].fetch_args = scalar_unary_fetch_args; bld_base->op_actions[TGSI_OPCODE_KIL].fetch_args = kil_fetch_args; bld_base->op_actions[TGSI_OPCODE_KILP].fetch_args = kilp_fetch_args; bld_base->op_actions[TGSI_OPCODE_RCP].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 95633ab..36e49ac 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; @@ -2190,6 +2207,7 @@ emit_vertex( LLVMBuildAdd(builder, bld->emitted_vertices_vec, masked_ones, ""); bld->total_emitted_vertices_vec = LLVMBuildAdd(builder, bld->total_emitted_vertices_vec, masked_ones, ""); + bld->pending_end_primitive = TRUE; } } @@ -2212,6 +2230,7 @@ end_primitive( bld->emitted_prims_vec = LLVMBuildAdd(builder, bld->emitted_prims_vec, masked_ones, ""); bld->emitted_vertices_vec = bld_base->uint_bld.zero; + bld->pending_end_primitive = FALSE; } } @@ -2250,6 +2269,17 @@ 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) +{ + struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); + + lp_exec_break_condition(&bld->exec_mask, emit_data->args[0]); +} + +static void if_emit( const struct lp_build_tgsi_action * action, struct lp_build_tgsi_context * bld_base, @@ -2504,6 +2534,12 @@ static void emit_epilogue(struct lp_build_tgsi_context * bld_base) /* If we have indirect addressing in outputs we need to copy our alloca array * to the outputs slots specified by the caller */ if (bld->gs_args) { + /* flush the accumulated vertices as a primitive */ + if (bld->pending_end_primitive) { + end_primitive(NULL, bld_base, NULL); + bld->pending_end_primitive = FALSE; + } + bld->gs_args->gs_epilogue(&bld->bld_base, bld->total_emitted_vertices_vec, bld->emitted_prims_vec, @@ -2572,6 +2608,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; @@ -2607,6 +2644,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, /* inputs are always indirect with gs */ bld.indirect_files |= (1<< TGSI_FILE_INPUT); bld.gs_args = gs_args; + bld.pending_end_primitive = FALSE; bld.bld_base.emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_gs_input; bld.bld_base.op_actions[TGSI_OPCODE_EMIT].emit = emit_vertex; bld.bld_base.op_actions[TGSI_OPCODE_ENDPRIM].emit = end_primitive;
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev