[Mesa-dev] [PATCH 3/7] tgsi: add support for geometry shader streams.

Dave Airlie airlied at gmail.com
Wed May 27 00:45:57 PDT 2015


This adds support to retrieve the primitive counts
for each stream, along with the offset for each
primitive into the output array.

It also adds support for parsing the stream argument
to the emit and end instructions.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/auxiliary/tgsi/tgsi_exec.c | 59 ++++++++++++++++++++++++++--------
 src/gallium/auxiliary/tgsi/tgsi_exec.h | 14 ++++++--
 2 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index a098a82..f080385 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -706,7 +706,22 @@ enum tgsi_exec_datatype {
 #define TEMP_OUTPUT_C      TGSI_EXEC_TEMP_OUTPUT_C
 #define TEMP_PRIMITIVE_I   TGSI_EXEC_TEMP_PRIMITIVE_I
 #define TEMP_PRIMITIVE_C   TGSI_EXEC_TEMP_PRIMITIVE_C
-
+#define TEMP_PRIMITIVE_S1_I   TGSI_EXEC_TEMP_PRIMITIVE_S1_I
+#define TEMP_PRIMITIVE_S1_C   TGSI_EXEC_TEMP_PRIMITIVE_S1_C
+#define TEMP_PRIMITIVE_S2_I   TGSI_EXEC_TEMP_PRIMITIVE_S2_I
+#define TEMP_PRIMITIVE_S2_C   TGSI_EXEC_TEMP_PRIMITIVE_S2_C
+#define TEMP_PRIMITIVE_S3_I   TGSI_EXEC_TEMP_PRIMITIVE_S3_I
+#define TEMP_PRIMITIVE_S3_C   TGSI_EXEC_TEMP_PRIMITIVE_S3_C
+
+static const struct {
+   int idx;
+   int chan;
+} temp_prim_idxs[] = {
+   { TEMP_PRIMITIVE_I, TEMP_PRIMITIVE_C },
+   { TEMP_PRIMITIVE_S1_I, TEMP_PRIMITIVE_S1_C },
+   { TEMP_PRIMITIVE_S2_I, TEMP_PRIMITIVE_S2_C },
+   { TEMP_PRIMITIVE_S3_I, TEMP_PRIMITIVE_S3_C },
+};
 
 /** The execution mask depends on the conditional mask and the loop mask */
 #define UPDATE_EXEC_MASK(MACH) \
@@ -1848,35 +1863,51 @@ exec_kill(struct tgsi_exec_machine *mach,
 }
 
 static void
-emit_vertex(struct tgsi_exec_machine *mach)
+emit_vertex(struct tgsi_exec_machine *mach,
+            const struct tgsi_full_instruction *inst)
 {
+   union tgsi_exec_channel r[1];
+   unsigned stream_id;
+   unsigned *prim_count;
    /* FIXME: check for exec mask correctly
    unsigned i;
    for (i = 0; i < TGSI_QUAD_SIZE; ++i) {
          if ((mach->ExecMask & (1 << i)))
    */
+   IFETCH(&r[0], 0, TGSI_CHAN_X);
+   stream_id = r[0].u[0];
+   prim_count = &mach->Temps[temp_prim_idxs[stream_id].idx].xyzw[temp_prim_idxs[stream_id].chan].u[0];
    if (mach->ExecMask) {
-      if (mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] >= mach->MaxOutputVertices)
+      if (mach->Primitives[stream_id][*prim_count] >= mach->MaxOutputVertices)
          return;
 
+      mach->PrimitiveOffsets[stream_id][*prim_count] = mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0];
       mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += mach->NumOutputs;
-      mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
+      mach->Primitives[stream_id][*prim_count]++;
    }
 }
 
 static void
-emit_primitive(struct tgsi_exec_machine *mach)
+emit_primitive(struct tgsi_exec_machine *mach,
+               const struct tgsi_full_instruction *inst)
 {
-   unsigned *prim_count = &mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];
+   unsigned *prim_count;
+   union tgsi_exec_channel r[1];
+   unsigned stream_id = 0;
    /* FIXME: check for exec mask correctly
    unsigned i;
    for (i = 0; i < TGSI_QUAD_SIZE; ++i) {
          if ((mach->ExecMask & (1 << i)))
    */
+   if (inst) {
+      IFETCH(&r[0], 0, TGSI_CHAN_X);
+      stream_id = r[0].u[0];
+   }
+   prim_count = &mach->Temps[temp_prim_idxs[stream_id].idx].xyzw[temp_prim_idxs[stream_id].chan].u[0];
    if (mach->ExecMask) {
       ++(*prim_count);
       debug_assert((*prim_count * mach->NumOutputs) < mach->MaxGeometryShaderOutputs);
-      mach->Primitives[*prim_count] = 0;
+      mach->Primitives[stream_id][*prim_count] = 0;
    }
 }
 
@@ -1885,9 +1916,9 @@ conditional_emit_primitive(struct tgsi_exec_machine *mach)
 {
    if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) {
       int emitted_verts =
-         mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]];
+         mach->Primitives[0][mach->Temps[temp_prim_idxs[0].idx].xyzw[temp_prim_idxs[0].chan].u[0]];
       if (emitted_verts) {
-         emit_primitive(mach);
+         emit_primitive(mach, NULL);
       }
    }
 }
@@ -4596,11 +4627,11 @@ exec_instruction(
       break;
 
    case TGSI_OPCODE_EMIT:
-      emit_vertex(mach);
+      emit_vertex(mach, inst);
       break;
 
    case TGSI_OPCODE_ENDPRIM:
-      emit_primitive(mach);
+      emit_primitive(mach, inst);
       break;
 
    case TGSI_OPCODE_BGNLOOP:
@@ -5061,8 +5092,10 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
    mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0;
 
    if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) {
-      mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0;
-      mach->Primitives[0] = 0;
+      for (i = 0; i < TGSI_MAX_VERTEX_STREAMS; i++) {
+         mach->Temps[temp_prim_idxs[i].idx].xyzw[temp_prim_idxs[i].chan].u[0] = 0;
+         mach->Primitives[i][0] = 0;
+      }
       /* GS runs on a single primitive for now */
       default_mask = 0x1;
    }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 0f4c966..dd6cd23 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -199,7 +199,14 @@ struct tgsi_sampler
 #define TGSI_EXEC_TEMP_P0           (TGSI_EXEC_NUM_TEMPS + 9)
 #define TGSI_EXEC_NUM_PREDS         1
 
-#define TGSI_EXEC_NUM_TEMP_EXTRAS   10
+#define TGSI_EXEC_TEMP_PRIMITIVE_S1_I  (TGSI_EXEC_NUM_TEMPS + 10)
+#define TGSI_EXEC_TEMP_PRIMITIVE_S1_C  0
+#define TGSI_EXEC_TEMP_PRIMITIVE_S2_I  (TGSI_EXEC_NUM_TEMPS + 10)
+#define TGSI_EXEC_TEMP_PRIMITIVE_S2_C  1
+#define TGSI_EXEC_TEMP_PRIMITIVE_S3_I  (TGSI_EXEC_NUM_TEMPS + 10)
+#define TGSI_EXEC_TEMP_PRIMITIVE_S3_C  2
+
+#define TGSI_EXEC_NUM_TEMP_EXTRAS   11
 
 
 
@@ -230,6 +237,8 @@ struct tgsi_sampler
 
 #define TGSI_MAX_MISC_INPUTS 8
 
+#define TGSI_MAX_VERTEX_STREAMS 4
+
 /** function call/activation record */
 struct tgsi_call_record
 {
@@ -294,7 +303,8 @@ struct tgsi_exec_machine
    unsigned                      Processor; /**< TGSI_PROCESSOR_x */
 
    /* GEOMETRY processor only. */
-   unsigned                      *Primitives;
+   unsigned                      *Primitives[TGSI_MAX_VERTEX_STREAMS];
+   unsigned                      *PrimitiveOffsets[TGSI_MAX_VERTEX_STREAMS];
    unsigned                       NumOutputs;
    unsigned                       MaxGeometryShaderOutputs;
    unsigned                       MaxOutputVertices;
-- 
2.1.0



More information about the mesa-dev mailing list