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

Reply via email to