From b66ffcf2f8a0128497d1e0afed0416a4aa4a14be Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 27 Mar 2013 02:30:38 -0700 Subject: [PATCH] gallivm: implement implicit primitive flushing MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit TGSI semantics currently require an implicit endprim at the end of GS if an ending primitive hasn't been emitted. Signed-off-by: Zack Rusin Reviewed-by: Brian Paul Reviewed-by: José Fonseca --- src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 6 ++++++ src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 62d4707..fe4444e 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_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 6f174a5..b9de31c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -2190,6 +2190,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 +2213,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; } } @@ -2504,6 +2506,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_iface) { + /* 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_iface->gs_epilogue(&bld->bld_base, bld->total_emitted_vertices_vec, bld->emitted_prims_vec, @@ -2607,6 +2615,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, /* inputs are always indirect with gs */ bld.indirect_files |= (1 << TGSI_FILE_INPUT); bld.gs_iface = gs_iface; + 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; -- 2.7.4