Mesa (arb_geometry_shader4): gs: generate output

Zack Rusin zack at kemper.freedesktop.org
Sat Aug 8 14:11:36 UTC 2009


Module: Mesa
Branch: arb_geometry_shader4
Commit: 799a4e47feb37975ca7fa8ae640e8244b4e082b0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=799a4e47feb37975ca7fa8ae640e8244b4e082b0

Author: Zack Rusin <zackr at vmware.com>
Date:   Sat Aug  8 10:16:16 2009 -0400

gs: generate output

geometry shader now seems to generate the correct output. the code that
collects the results and passes them through the rest of the draw module
is still a bit broken though.

---

 src/gallium/auxiliary/draw/draw_gs.c   |   46 ++++++++++++++++++++------------
 src/gallium/auxiliary/tgsi/tgsi_exec.c |   20 ++++++++++++--
 src/gallium/auxiliary/tgsi/tgsi_exec.h |    2 +
 3 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index b887ec2..f2cb369 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -38,26 +38,34 @@
 
 #define MAX_PRIM_VERTICES 6
 /* fixme: move it from here */
-#define MAX_PRIMITIVES 128
+#define MAX_PRIMITIVES 64
 
 boolean
 draw_gs_init( struct draw_context *draw )
 {
    tgsi_exec_machine_init(&draw->gs.machine);
 
-   draw->gs.machine.Inputs = align_malloc(MAX_PRIM_VERTICES *
-                                          PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16);
+   draw->gs.machine.MaxGeometryShaderOutputs
+      = MAX_PRIM_VERTICES * MAX_PRIMITIVES * PIPE_MAX_ATTRIBS;
+
+   draw->gs.machine.Inputs =
+      align_malloc(MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS *
+                   sizeof(struct tgsi_exec_vector), 16);
    if (!draw->gs.machine.Inputs)
       return FALSE;
 
-   draw->gs.machine.Outputs = align_malloc(MAX_PRIM_VERTICES *
-                                           PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16);
+   draw->gs.machine.Outputs =
+      align_malloc(draw->gs.machine.MaxGeometryShaderOutputs
+                   * sizeof(struct tgsi_exec_vector), 16);
    if (!draw->gs.machine.Outputs)
       return FALSE;
 
-   draw->gs.machine.Primitives = align_malloc(MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16);
+   draw->gs.machine.Primitives = align_malloc(
+      MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16);
    if (!draw->gs.machine.Primitives)
       return FALSE;
+   memset(draw->gs.machine.Primitives, 0,
+          MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector));
 
    return TRUE;
 }
@@ -165,7 +173,8 @@ static void draw_fetch_geometry_input(struct draw_geometry_shader *shader,
          debug_printf("\t%d)(%d) Input vert:\n", idx, j);
 
          for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; slot++) {
-            if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_VERTICES) {
+            if (shader->info.input_semantic_name[slot] ==
+                TGSI_SEMANTIC_VERTICES) {
                machine->Inputs[idx + slot].xyzw[0].f[j] = (float)num_vertices;
                machine->Inputs[idx + slot].xyzw[1].f[j] = (float)num_vertices;
                machine->Inputs[idx + slot].xyzw[2].f[j] = (float)num_vertices;
@@ -205,7 +214,7 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader,
                               const float (*constants)[4],
                               unsigned count,
                               unsigned input_stride,
-                              unsigned output_stride)
+                              unsigned vertex_size)
 {
    struct tgsi_exec_machine *machine = shader->machine;
    unsigned int i, j, prim_idx;
@@ -223,9 +232,11 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader,
    }
 
    for (i = 0; i < num_primitives; i += MAX_TGSI_PRIMITIVES) {
-      unsigned int max_primitives = MIN2(MAX_TGSI_PRIMITIVES, num_primitives - i);
+      unsigned int max_primitives = MIN2(MAX_TGSI_PRIMITIVES,
+                                         num_primitives - i);
 
-      draw_fetch_geometry_input(shader, i, max_primitives, input, input_stride, inputs_from_vs);
+      draw_fetch_geometry_input(shader, i, max_primitives, input,
+                                input_stride, inputs_from_vs);
 
       tgsi_set_exec_mask(machine,
                          1,
@@ -240,13 +251,14 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader,
        */
       for (prim_idx = 0; prim_idx < max_primitives; ++prim_idx) {
          for (j = 0; j < num_vertices; j++) {
-            int idx = ((i + prim_idx) * num_vertices + j) * shader->info.num_outputs;
-            debug_printf("%d) Post xform vert:\n", i + j);
+            int idx = ((i + prim_idx) * num_vertices + j) *
+                      shader->info.num_outputs;
+            debug_printf("%d) Post xform vert:\n", idx);
             for (slot = 0; slot < shader->info.num_outputs; slot++) {
-               output[idx + slot][0] = machine->Outputs[idx + slot].xyzw[0].f[j];
-               output[idx + slot][1] = machine->Outputs[idx + slot].xyzw[1].f[j];
-               output[idx + slot][2] = machine->Outputs[idx + slot].xyzw[2].f[j];
-               output[idx + slot][3] = machine->Outputs[idx + slot].xyzw[3].f[j];
+               output[idx + slot][0] = machine->Outputs[idx + slot].xyzw[0].f[prim_idx];
+               output[idx + slot][1] = machine->Outputs[idx + slot].xyzw[1].f[prim_idx];
+               output[idx + slot][2] = machine->Outputs[idx + slot].xyzw[2].f[prim_idx];
+               output[idx + slot][3] = machine->Outputs[idx + slot].xyzw[3].f[prim_idx];
                debug_printf("\t%d: %f %f %f %f\n", slot,
                             output[idx + slot][0],
                             output[idx + slot][1],
@@ -256,7 +268,7 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader,
             }
          }
 
-	 output = (float (*)[4])((char *)output + output_stride);
+	 output = (float (*)[4])((char *)output + (num_vertices * vertex_size));
       }
    }
 }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index ed95bba..f296431 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -292,6 +292,14 @@ tgsi_exec_machine_bind_shader(
                                    * sizeof(struct tgsi_full_declaration));
             maxDeclarations += 10;
          }
+         if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_OUTPUT) {
+            unsigned reg;
+            for (reg = parse.FullToken.FullDeclaration.DeclarationRange.First;
+                 reg <= parse.FullToken.FullDeclaration.DeclarationRange.Last;
+                 ++reg) {
+               ++mach->NumOutputs;
+            }
+         }
          memcpy(declarations + numDeclarations,
                 &parse.FullToken.FullDeclaration,
                 sizeof(declarations[0]));
@@ -1447,6 +1455,10 @@ store_dest(
       index = mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
          + reg->DstRegister.Index;
       dst = &mach->Outputs[offset + index].xyzw[chan_index];
+      if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) {
+      fprintf(stderr, "STORING OUT[%d] = (%f, %f, %f, %f)\n", index, chan->f[0],
+              chan->f[1], chan->f[2], chan->f[3]);
+      }
       break;
 
    case TGSI_FILE_TEMPORARY:
@@ -1745,15 +1757,17 @@ exec_kilp(struct tgsi_exec_machine *mach,
 static void
 emit_vertex(struct tgsi_exec_machine *mach)
 {
-   mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16;
+   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]]++;
 }
 
 static void
 emit_primitive(struct tgsi_exec_machine *mach)
 {
-   mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++;
-   mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
+   unsigned *prim_count = &mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];
+   ++(*prim_count);
+   debug_assert((*prim_count * mach->NumOutputs) < mach->MaxGeometryShaderOutputs);
+   mach->Primitives[*prim_count] = 0;
 }
 
 /*
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index da22baa..8fe3565 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -210,6 +210,8 @@ struct tgsi_exec_machine
 
    /* GEOMETRY processor only. */
    unsigned                      *Primitives;
+   unsigned                       NumOutputs;
+   unsigned                       MaxGeometryShaderOutputs;
 
    /* FRAGMENT processor only. */
    const struct tgsi_interp_coef *InterpCoefs;




More information about the mesa-commit mailing list